How do you simulate gravity?

Started by
19 comments, last by DevLiquidKnight 21 years, 8 months ago
[removed] [Edited by - DevLiquidKnight on February 14, 2007 9:21:39 AM]
Advertisement
Hey,

You just add a velocity vector to you models and increase that with the gravity (9.8m/sec) or your own values

for example:

struct strMyObject {
Vector Pos, Vec;
}

strMyObject Player;

LOOP ->:
Player.Vec.y -= GRAVITY/Framespersec (or just a constant value)

Player.Pos += Vec;

So each frames you add the velocity vector to the players possision to make him accelerate down if nothing is stopping him
(like a floor =

<- LOOP

To elaborate on the AP's response, gravity is a force acting between all objects that have mass. I'll assume for the time being that you want to simulate gravity as it would be felt on the surface of a planet. Let's stick with Earth, since it's nice and easy to relate to.

First, take Newton's First Law:
F = M*a             (1) 

Force = Mass * Acceleration

The Gravitational force between two objects is proportional to their masses and inversely proprtional to the square of the separation between them, so that
    G M1 M2F = -------                    (2)      R2  


G is the gravitational constant and is equal to 6.672*10-11N m2 kg-2

If you hold one mass (M1) constant, say that of the Earth, then the acceleration that the other mass will undergo, relative to the first mass, is given by combining (1) and (2) to give

    G M1a = -------                    (2)      R2  


Substituting in the radius of the Earth (around 6,400 km on average) and the Mass of the Earth (about 5.98*1024 kg) gives an acceleration around 9.8 m s-2.

This is the same acceleration that all bodies undergo at the surface of the Earth. The Force that each body undergoes though is different and is given by F = 9.8 * mass of the body.

Since you know the acceleration of the body, you can work out it's vertical velocity (which is independant of the horizontal velocity) by integrating the acceleration over a fixed time interval, since acceleration is the first derivative of velocity with respect to time. You need to know the starting velocity to do this, since
v(t+dt) = v(t) + integraltt+dt a dt  

Furthermore, if you know the position of the object at time t then you can work out its position at time t+dt by integrating the velocity. The result is that for any object near the surface of the Earth, you get the following equations for the height of the object and it's velocity:

s(t+dt) = s(t) + 1/2a*dt2
v(t+dt) = v(t) + a*dt

So if you know a (which you set yourself), the initial height, s(t), and the initial velocity, v(t) m/s (down... negative means up) then you can work out where the object is some time later!

I hope this explains the solution for you.

Good luck,

Timkin

[edited by - Timkin on July 29, 2002 11:36:28 PM]
i have an extremley simple way of simulating gravity, just make an mz variable for your object. every frame, add the gravity variable to mz. and every frame, add mz to z, so that way, it accelerates down until it hits something, then make mz = 0 and only add gravity if bOnGround is false or something
quote:Original post by Timkin



    G M1a = -------                    (2)      R2   



Hey,

I''m just having a problem with this formula: the problem of it is that the acceleration isn''t constant here, and if I calculate physics in a space game every frame, I have to assume that the acceleration is constant during the 1/85th of a second this frame takes, and while this may seem only a small problem, the results of it are dramatic and the physics get more than 100% inaccurate. Do you have an idea how to calculate exactly what happened during one frame, knowing that not only the magnitude but also the direction of the gravity is changing during the time of one frame?

coming across one problem i simulated gravity and now when i walk on the platforms i made i get stuck so i tried to make it subtract 1 from the y variable when he is on a platform so he could move side to side and it causes the guy to bounce up and down really fast

[edited by - DevLiquidKnight on July 30, 2002 8:35:10 PM]
quote:Original post by Lode
I''m just having a problem with this formula: the problem of it is that the acceleration isn''t constant here, and if I calculate physics in a space game every frame, I have to assume that the acceleration is constant during the 1/85th of a second this frame takes, and while this may seem only a small problem, the results of it are dramatic and the physics get more than 100% inaccurate. Do you have an idea how to calculate exactly what happened during one frame, knowing that not only the magnitude but also the direction of the gravity is changing during the time of one frame?


Unless things are travelling quite fast, then 1/85th of a second is a very small time to integrate over. Are you using an Euler integration (which I suspect you are)?. You may want to consider using a predictor-corrector integration scheme.

Good luck,

Timkin
The 1/85th of a second becomes to large to keep it accurate in two cases:
-if the planet has such a big mass that it generates very strong accelerations if you get close to it, but then for example my ship gets an acceleration of 10000000000m/s² at a certain point and in the 1/85th of a second it''s of course suddenly very far away of the planet... so far that it doesn''t get the negative -10000000000m/s² that it should get when it just crossed the planet anymore.
-if I speed up the time of the simulation: if I speed up the simulation with a factor of 1000, the 1/85th of a second becomes like 11.7seconds and that is too long to keep it accurate.

So indeed I should somehow predict where the ship will be after that time... but what kind of predictor-corrector integration scheme should I be looking for?
Okay, I didn''t realise you were talking about such large accelerations. Since you are, you really cannot treat this problem with classical (Newtonian) physics. You need to deal with the simulation from the perspective of the gravitational potential energy and the conversion from this potential energy into kinetic energy (strictly speaking you should be using General Relativity to get things correct, but that''s more trouble than it''s worth!).

Taking the ''energy approach'' will enable you to bring in relativistic effects that limit the speed of the craft to the speed of light. It will also mean that at high velocities, a huge gravitational potential will only impart a small additional velocity.

If you''ve got an introductory college text on physics everything you need to know is in there. If you don''t, then try google... there''s certainly lots of physics stuff around. Failing that, holler here and I''ll write something up for you (I''m a bit flat out at work today otherwise I''d just do it now for you).

Good luck,

Timkin
quote:Original post by DevLiquidKnight
coming across one problem i simulated gravity and now when i walk on the platforms i made i get stuck so i tried to make it subtract 1 from the y variable when he is on a platform so he could move side to side and it causes the guy to bounce up and down really fast



I think you''re looking for something simpler than what''s being discussed here!

As the player is falling down towards the platform, you need to calculate whether the players current position + the players current (downward) velocity results in collision with the platform.


If this is the case, you need to ''snap'' the player somehow to the platform so that he appears to be standing on it (how easily you accomplish this depends on how you have stored the platform tiles).

Once the player has been re-positioned on the platform, set the y-acceleration (gravity) to zero and then set a flag saying not to start the downward acceleration again until a platform can no longer be detected underneath the player.

(this is only one way to avoid the ''bobbing'' you talk of, but you could use the ''snapping'' part of your code, but it dpeends on how you structure it).

hope this is of some help. I can elaborate if you like.

<a href="http://www.purplenose.com>purplenose.com

This topic is closed to new replies.

Advertisement