Calculating initial speed needed for perfect orbit

kamiyasi

Member
Hi there. Let me explain what I'm working on.


I have a star, with a gravitational radius that's 200 times it's size.
I use this code...
Code:
var gdir = point_direction( x,y,other.x,other.y );
        var gdis = point_distance( x,y,other.x,other.y );
        var pstrength = ( (other.mass*0.000001) );
       
        var pull = (pstrength) * clamp(( ((gdis / (other.mass*global.pulldistance) )*-1)+1 ) ,0,1);              
       
        ///add gravitational pull
       
        xspeed += ( lengthdir_x( pull, gdir) );
        yspeed += ( lengthdir_y( pull, gdir) );
to tell my planets to have a smaller gravitational pull towards the star if they're further away from it. [ In this project, global.pulldistance is equal to 200 and mass is the size of the star ]

What I would like to do is find an equation that sets each planet's initial xspeed and yspeed so that once the room starts, they enter a near perfect orbit around the star regardless of their distance from it (unless they're outside of the gravitational raidus of course, in which case they wouldn't move at all)

I'm using the following equation so far which gets the planets in an orbit, but it's far from a perfect orbit.
Code:
var i;
for (i=0; i<6; i++)
{
    with instance_create( x+lengthdir_x(20000+(10000*i),(45*i)),y+lengthdir_y(20000+(10000*i),(45*i)),obj_planet)
    {
        ///set initial momentum
        var gdir = point_direction( x,y,other.x,other.y );
        var gdis = point_distance( x,y,other.x,other.y );
        var pstrength = ( (other.mass) );
        var pull = (pstrength) * clamp(( ((gdis / (other.mass*global.pulldistance) )*-1)+1 ) ,0,1);
        var inertia = 0.04 + (pull*0.000009);
       
        xspeed += ( lengthdir_x( (inertia), gdir+90) );
        yspeed += ( lengthdir_y( (inertia), gdir+90) );
    }
}
If anyone has a good algorithm for what I'm trying to achieve, I'd appreciate it :)
 
I could tell you how to get your planets in orbit if you were using realistic-ish gravity. But the gravity you are using looks to be something else entirely.

With normal gravity a perfect circular orbit would have an initial speed of

sqrt( parent_mass * G / dist_between_bodies )

and of course the initial direction of motion would be perpendicular to the direction from one body to the other.

That assumes the satellite body has negligible mass in comparison to its parent.

If you want to implement realistic gravity I've got some very simple math for you:

Code:
//to gravitate A toward B.

//G is gravitational constant (can be any positive number).
//larger G or larger mass means more gravity. 
//negative product of G*mass will result in repulsive gravity rather than attractive gravity (funny but kind of useless).
//if G == 1, then you can remove it from the calculation.


//you can substitute power(point_distance(0,0,_x,_y),3)
//with power(dot_product(_x,_y,_x,_y),1.5),
//I've found the latter to be slightly faster, maybe becuase it involves one less subtraction and no square root?

//by the way you probably have seen gravitational formulas that involve dividing by distance squared
//but this code here also has a vector normalization
//which is why it is dividing by distance cubed.

var _x = B.x - A.x;
var _y = B.y - A.y;
var _f = G * B.mass / power(point_distance(0,0,_x,_y),3);
A.hspeed += _x * _f;
A.vspeed += _y * _f;
 
Last edited:

kamiyasi

Member
I could tell you how to get your planets in orbit if you were using realistic-ish gravity. But the gravity you are using looks to be something else entirely.

With normal gravity a perfect circular orbit would have an initial speed of

sqrt( parent_mass / dist_between_bodies )

and of course the initial direction of motion would be perpendicular to the direction from one body to the other.

That assumes the satellite body has negligible mass in comparison to its parent.

If you want to implement realistic gravity I've got some very simple math for you:

Code:
//to gravitate A toward B.

//G is gravitational constant (can be any positive number).
//larger G or larger mass means more gravity.
//negative product of G*mass will result in repulsive gravity rather than attractive gravity (funny but kind of useless).
//if G == 1, then you can remove it from the calculation.


//you can substitute power(point_distance(0,0,_x,_y),3)
//with power(dot_product(_x,_y,_x,_y),1.5),
//I've found the latter to be slightly faster, maybe becuase it involves one less subtraction and no square root?

//by the way you probably have seen gravitational formulas that involve dividing by distance squared
//but this code here also has a vector normalization
//which is why it is dividing by distance cubed.

var _x = B.x - A.x;
var _y = B.y - A.y;
var _f = G * B.mass / power(point_distance(0,0,_x,_y),3);
A.hspeed += _x * _f;
A.vspeed += _y * _f;
Thanks for the tip. I seem to have gotten the gravity working like this
Code:
with argument0
{
    with other
    {
        if other.id == self.id then break;
       
        var gdir = point_direction( x,y,other.x,other.y );
        var _x = other.x - x;
        var _y = other.y - y;
        var _f = 1 * other.mass / power(point_distance(0,0,_x,_y),3);
        xspeed += _x * _f;
        yspeed += _y * _f;
       
       
     }
}
But my initial momentum doesn't work. It seems to just jettison off at 90 degrees too quickly and shoots out into space.

Code:
var gdir = point_direction( x,y,argument0.x,argument0.y );
        var gdis = point_distance( x,y,argument0.x,argument0.y );
        var inertia = sqrt( other.mass / gdis );
        xspeed += ( lengthdir_x( (inertia), gdir+90) );
        yspeed += ( lengthdir_y( (inertia), gdir+90) );
Do you see any problems?
 
Last edited:
are you gravitating everything or just having the satellite bodies gravitate around the central body?

by the way you don't need the point_direction in the gravity script.

EDIT: it looks to me with that nested with statements that you are trying to get every body to gravitate every other body. If that is the case, then getting perfect orbits is going to be (basically) impossible. ( Unless most of these things have almost zero mass. )
 
Last edited:

kamiyasi

Member
are you gravitating everything or just having the satellite bodies gravitate around the central body?

by the way you don't need the point_direction in the gravity script.
I have a parent / child structure of different bodies (planets, moons, stars, black hole)
Stars are attracted to the black hole
planets to stars and other planets
moons to moons and other planets.

With my original non realistic code, the strength of the gravitational pull was equal to 200 x the size of the body, which I called its mass, with its strength being 100% at the center, to 0% at the boundary.

I have to divide this orbit code by 100 to get the star going in a decent orbit, but with that the planets are way too fast and still jet off into space so something isn't working out here.
Code:
var inertia = ( sqrt( other.mass / gdis ) )/100;
 
if you have a lot (more than 2) of things orbiting each other, you aren't going to be able to calculate orbits for them, unless most of them have almost zero mass, or different satellite systems are very far away from each other.

EDIT:

I'll throw together a little project here that you can reverse engineer. I'll be done in a few minutes.
 
Last edited:
Okay, would have just edited my above post but I want you to get a notice that I'm leaving this message:

https://www.dropbox.com/s/qqr6xjge1urdf4r/Orbiting_A_Planet.gmz?dl=0

Oh, I made one little booboo earlier, the circular orbit speed is actually:

sqrt( parent.mass * G / distance_between_them )

forgot to include gravitational constant there, so if it is anything other than 1, it would have messed up the calculations.

In the "scr_create_some_satellites" script, try adjusting the value of "_A", to make the orbits of satellites more elliptical.

There's a little bonus in there, a script that calculates obital parameters which will allow you to draw an ellipse for the orbit of each satellite.
 

kamiyasi

Member
Okay, would have just edited my above post but I want you to get a notice that I'm leaving this message:

https://www.dropbox.com/s/qqr6xjge1urdf4r/Orbiting_A_Planet.gmz?dl=0

Oh, I made one little booboo earlier, the circular orbit speed is actually:

sqrt( parent.mass * G / distance_between_them )

forgot to include gravitational constant there, so if it is anything other than 1, it would have messed up the calculations.

In the "scr_create_some_satellites" script, try adjusting the value of "_A", to make the orbits of satellites more elliptical.

There's a little bonus in there, a script that calculates obital parameters which will allow you to draw an ellipse for the orbit of each satellite.
Thanks for your help. Unfortunately, after trying to replicate your example, I'm still getting the result that the initial burst of momentum is too fast and sends my bodies far out of orbit. If you have time and wouldn't mind,
would you give my project a quick look? I'd appreciate it a lot.
https://www.dropbox.com/s/c2k97j48dm4st4i/Orbiting_A_Planet.gmx.zip?dl=0
 
Last edited:
haha, you are running at x7000 time. However, gravitation is still done in normal time. Its a good idea to make the sun quite a bit more massive than the planets, and to make sure planets are pretty far apart from each other, or they will drag each other out of orbit. Add to a satellites speed vector, the speed of its parent. You'll also want your satellites to be much closer to their parents than their parent is to its parent. Oh, one more thing, if you have satellites that also exert a force on their parents, then you are going to have systems that drift away from where they start. With just two bodies, it is easy enough to cancel out that drift, but it gets more complicated with more than two bodies.
 
Last edited:

NicoFIDI

Member
On circular uniform movement it's true that:
Radian aceleration = -(angular speed)^2 * radius

So in human, your speed need to start 90 degrees from its aceleration, and its value must be:
sqrt(aceleration/distance)
 

kamiyasi

Member
I've solved my problem. For some reason, multiplying the values of the initial inertia and the gravitational strength by the same factor in order to increase the movement speed is what caused the problem. I'm not sure why this is, but once I figured that out, I just raised the mass of the parent object instead, which gives the same result.
 
Top