Planet Gravity

Started by
13 comments, last by Esys 14 years, 1 month ago
Quote:Original post by fcoelho

Wow. Online LaTeX rendering. Nice one :D

Advertisement
http://www.newgrounds.com/dump/item/40f6b15e7cb536a2eee2a442ae683870

Quick demo of the stuff I gathered from you guys. Use LEFT/RIGHT to change your rotation. I know the numbers need some major tinkering, especially since the "range" of the gravity seems far too short yet gets strong far, far too quickly. Shortly after you get in range of the gravity, it soon gets too strong to pull yourself out of so that needs some fiddling with.

Also, I think I do need the gravity to affect the rotation of the ship, because you cant really do the sling shot manuever or really anything, because as soon as you come into the range of the gravity, you pretty much have to angle yourself away from it in order to not get pulled in.

Some time back I wrote these tutorial code samples:

http://www.jernmager.dk/stuff/freebasic/gravity_02.zip

They're very simple examples of physically correct planetary gravitation. Line-by-line commented. Ideal for games.

Cheers,
Mike
Quote:Original post by Azh321
This seems a lot more complicated than I was expecting, luckily im currently taking calc 3 :) I will have to look over the math when I get back to my desktop.

To answer your question johnstanp, im not sure yet. I really need to reference a similar game to see how it deals with it. Im thinking I do want the ship to rotate to point in the direction that its currently moving towards, so I will need to have a separate variable for the angle and for the actual rotation of the player.


Well, you don't need to explicitly do it. Basically, all the equations you need to know, in rigid body dynamics, are:

dx(t)/dt = P(t)/M
dR(t)/dt = w(t) * R(t)
dP(t)/dt = F(t)
dL(t)/dt = T(t)

v(t) = P(t)/M
inverse(I(t)) = R(t) * inverse(Ib) * transpose( R(t) )( provided R(t) is a rotation )
w(t) = inverse(I(t))L(t)

x(t): position
P(t): linear momentum
M: mass
R(t): orientation
w(t): angular momentum
F(t): total force
L(t): angular momentum
T(t): total torque
v(t): linear_velocity
I(t): inertia tensor expressed in world coordinates
Ib: inertia tensor expressed in local coordinates
w(t): angular momentum

in english:
the rate of variation of the position of a rigid body is equal to its velocity,
the rate of variation of the axes of the basis of a rigid body is equal to the cross product of its angular velocity and its axes,
the rate of variation of the linear momentum of a rigid body is equal to the total force applied to it,
the rate of variation of the angular momentum of a rigid body is equal to the total torque applied to it.

This is all you only need for a rigid body simulation. You should be able to compute the forces applied to your body, and the torques they generate and the torques directly generated. Since the equations I posted are differential, you'll need an integration scheme( generally Euler would be sufficient ), that is:

x(t+dt) = x(t) + P(t)/M * dt
R(t+dt) = R(t) + w(t) * R(t) * dt
P(t+dt) = P(t) + F(t) * dt
L(t+dt) = L(t) + T(t)

v(t+dt) = P(t+dt)/M
inverse(I(t+dt)) = R(t+dt) * inverse(Ib) * transpose( R(t+dt) )
( you'll need re-orhonormalizing R(t+dt) from time to time )
w(t+dt) = inverse(I(t+dt))L(t+dt)

For your simulation

/*initialize position, orientation, linear momentum, and angular momentum of your spaceshift*/for each frame	force_accumulator = get_force_from_imput();	torque_accumulator = get_torque_from_imput();	for each planet		delta_position = planet.position - spaceshift.position;		squared_dist = squared_distance( delta_position );				force = 			gravitational_constant * 			( spaceshift.mass * planet.mass / squared_dist ) *			 unit_vector( delta_position );		force_accumulator += force;		/*we don't compute the generated torques because the forces are applied		 on the center of mass*/	end	spaceshift.force = force_accumulator;	spaceshift.torque = torque_accumulator;	update_state( spaceshift, timestep ) //integration stepend


P.S: here I assume that the size of the spaceshift is not big enough to experience a torque generated by gravitional forces...And even if it was big enough, over time, the spaceshift would come to be oriented in such a way that the generated torque by gravitational forces, becomes null. It is easier to grasp for a single planet acting on the spaceshift.
**edit** w(t)*R(t) is a special operation. Let's call the result M(t).
Then M(t)i = w(t).cross_product(R(t)i) ( M(t)i, ith column of M(t) if the columns of M(t) are the vectors of the orthonormal basis represented by M(t). The same for R(t)i ). So w(t)*R(t) = skew_symmetric_matrix(w(t))*R(t)

[Edited by - johnstanp on March 10, 2010 2:06:24 PM]
You always have the constant G to use to fine-tune your gravity formula:

This topic is closed to new replies.

Advertisement