0
\$\begingroup\$

I'm writing a 2d space game, and I want the players to be able to 'orbit' objects and other players (if they're fast enough, of course), but I'm having trouble coming up with the right way to think about this physically (I never took physics, so this part is hard for me).

Note that this is not a 'realistic' space sim -- more like boats, really, so I don't want to do this by having the objects actually have enough gravity to force the orbit normally, because that'll make players that didn't press the 'orbit' button get sucked in and not be fun.

Also, do note that the objects players are trying to orbit may themselves be trying to orbit another object or even be mutual orbits.

I'm using the RK4 integrator right now, though if that needs to change, I'm totally up for it.

\$\endgroup\$
1
  • \$\begingroup\$ Check my answer. Updated with specific solution. \$\endgroup\$ Commented Aug 28, 2015 at 2:36

2 Answers 2

6
\$\begingroup\$

When the user presses the "orbit" button, store the vector between the ship and the planet. On every update, change the vector's angle leaving magnitude the same and then update the ships position by adding the planets position and the vector pointing at the ships new position. This will create the effect of the ship moving in a uniform circle around the object being orbited.

Also, it would be a nice touch if you programmed the ship to slowly turn until it was pointed 90 degrees to the planet before starting the uniform orbit, otherwise the ship could be going straight toward it then sharply turn into orbit when the user presses the button.

More Detailed Physics

If you want more complicated things like true elliptical orbits and correct orbital speeds, you will need to do some research into real physics.

This question has already been asked: https://stackoverflow.com/questions/4038554/2d-orbital-physics; But for those that find this page, I will summarize the results and try to apply it to your situation and somewhat explain the physics.

His engine uses the following equation to calculate the force applied on both objects, where F is the force, G is the gravitational constant, m and M are the masses of the two objects, and finally r is the radius.

F = G M m / r^2

Remember that Newton's Third Law says that "all forces between two objects exist in equal magnitude and opposite direction", meaning that this equation is evaluated once and represents both forces present.

In addition, his pseudo code for his engine might be helpful:

for each time step of length t:
  reset cumulative forces on each object to 0.
  for each unique pair of objects:
    calculate force between them due to gravity.
    accumulate force to the two objects.
  for each object:
    calculate velocity change dV for this timestep using Ft / m.
    v = v + dV.
    calculate position change dS using v * t.
    s = s + dS.

Also, he discovered that he needed to normalize the direction vector before he applied it to the force.

\$\endgroup\$
3
  • \$\begingroup\$ This is not actually an answer to my question as stated -- I'm trying to avoid complicating the simulation with gravity. \$\endgroup\$ Commented Aug 25, 2015 at 17:12
  • 2
    \$\begingroup\$ It's probably best to just implement the actual physics or you are going to find that your faked code is more complicated and less efficient than the real physics. You don't have to apply gravity throughout your whole game, just in the equation for orbits. \$\endgroup\$ Commented Aug 25, 2015 at 17:18
  • 2
    \$\begingroup\$ +1 I find Ramsay answer coherent with the question "How does orbital math work?" \$\endgroup\$ Commented Aug 28, 2015 at 6:51
2
\$\begingroup\$

If you need just a circular obit, use the method below, where the parameter "c" is the center position of the orbit, "t" is the vector in which the object will circulate around, I call it torque, "theta" is the angular displacement. On a 2d plane omit the z coordinate and change the vectors to 2d.

public void orbit(Vector3f c, Vector3f t, float theta) {
        
        //normalize t
        t = t.normalize();
                
        float orbitAngleRad = (float) Math.toRadians(theta);

        
        double sinTheta = Math.sin(orbitAngleRad);
        double cosTheta = Math.cos(orbitAngleRad);

        Vector3f p0 = this.getPosition();
        float x0 = p0.x;
        float y0 = p0.y;
        float z0 = p0.z;
        
        
        float x = (float) ((c.x*(t.y*t.y + t.z*t.z) - t.x*(c.y*t.y + c.z*t.z - t.dot(p0)))*(1-cosTheta)
                + x0*cosTheta + (-c.z*t.y + c.y*t.z - t.z*y0 + t.y*z0)*sinTheta);
        
        float y = (float) ((c.y*(t.x*t.x + t.z*t.z) - t.y*(c.x*t.x + c.z*t.z - t.dot(p0)))*(1-cosTheta)
                + y0*cosTheta + (c.z*t.x - c.x*t.z + t.z*x0 - t.x*z0)*sinTheta);
        
        float z = (float) ((c.z*(t.x*t.x + t.y*t.y) - t.z*(c.x*t.x + c.y*t.y - t.dot(p0)))*(1-cosTheta)
                + z0*cosTheta + (-c.y*t.x + c.x*t.y - t.y*x0 + t.x*y0)*sinTheta);
       
        //move the center point of the object
        this.setPosition(x,y,z);
        //this line is for construct the standard rotation matrix, this will rotate the center of the object
        this.getRotation().rotateAxis(orbitAngleRad, t);
        
    }
\$\endgroup\$

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .