Archived

This topic is now archived and is closed to further replies.

Kyo

gravity for particles?

Recommended Posts

I want to simulate gravity like a planet around the sun or galaxies colliding but how do I use the equations in my particle class which uses the projectile motion equation
      
	//update position 

	x = (int)((0.5 * gx * SQRD(t)) + (ivx * t) + ix);
	y = (int)((0.5 * gy * SQRD(t)) + (ivy * t) + iy);
	z = (int)((0.5 * gz * SQRD(t)) + (ivz * t) + iz);
      
where gx, gy and gz is gravity, t is time, ivx is initial velocity and ix is initial position. And the formula for gravity: F = (m2)a = G(m1)(m2)/r^2 a = G(m1)/r^2 so if I find the distance x between the planet particle and the sun particle I simply use gx = GRAVITY_CONSTANT / distancex^2? and when the particle updates it's position it'll integrate the acceleration due to gravity x,y,z and get the position. Seeing as distance y and z = 0 then the only acceleration is x which makes the planet move straight instead of an orbit.. And in the opposite direction to the sun as well! It comes back eventually though which is a bit weird.. i must be missing out something.. edit: Please don't say Kepler's laws i want to do this using gravity equation first [edited by - Kyo on August 30, 2002 3:44:38 PM]

Share this post


Link to post
Share on other sites
you want something like:

// dist from sun (assuming sun is at origin)
float dist = sqrt (x * x + y * y + z * z);
// force magnitude: k = GMm is a constant which can
// be precalculated or which can be chosen based on
// gameplay
float force = k / (x*x);
// Newton''s third law
float acceleration = force / mass;
turn this into a vector pointing towards sun by multiplying
// by unit vector
ax = acceleration * x / dist;
ay = acceleration * y / dist;
az = acceleration * z / dist;
// update velocities
vx = vx + ax * t;
vy = vy + ay * t;
vz = vz + az * t;
// update positions
x = x + vx * t;
y = y + vy * t;
z = z + vz * t;

The interesting bits are working out the force and turning it into acceleration vector pointing towards the sun/centre. The last three lines are a basic Euler integrator: for such circular motion it''s not stable, so objects may slowly spiral outwards, but it may be good enough. decreasing the size of the time step helps this.

And don''t use ints. Use float for all values, including storing positions. You may need to convert to ints to render but if you use them during such calculations you will accumulate rouding errors.

Share this post


Link to post
Share on other sites
Thanks that helps especially the ints for storing positions..

Where does the

ax = acceleration * x / dist;
ay = acceleration * y / dist;
az = acceleration * z / dist;

come from? and if my acceleration due to gravity is

a = [ax, ay, az]

then integrating gives

v = [ax * t + ivx, ay * t + ivy, ...]

and again gives displacement

r = [1/2 * ax * t^2 + ivx * t + ix, ..., ...]

then shouldn''t

vx = vx + ax * t

be

vx = ivx + ax * t?

and isn''t it possible to use the above formula for displacement so i don''t have to change the particle class?

Share this post


Link to post
Share on other sites
ok here''s some code i tried different values for gravity constant and initial y velocity to get the earth moving round the sun (instead of just falling straight into it) but it always either spirals outwards or into the sun.


  
int distancex;
int distancey;
int distancez;
float distance;

ogl.FrameBegin();

gluLookAt(xcam, ycam, zcam, 0, 0, 0, 0, 1, 0);

gx = 0.0f;
gy = 0.0f;
gz = 0.0f;

sun.update(false);

distancex = earth.getx() - sun.getx();
distancey = earth.gety() - sun.gety();
distancez = earth.getz() - sun.getz();
distance = sqrt(SQRD(distancex) + SQRD(distancey) + SQRD(distancez));

//calculate acceleration

if (distancex < 0)
{
gx = G / SQRD(distance);
}
else if (distancex > 0)
{
gx = -(G / SQRD(distance));
}
if (distancey < 0)
{
gy = G / SQRD(distance);
}
else if (distancey > 0)
{
gy = -(G / SQRD(distance));
}
if (distancez < 0)
{
gz = G / SQRD(distance);
}
else if (distancez > 0)
{
gz = -(G / SQRD(distance));
}

earth.update(false);

sun.draw();
earth.draw();

Share this post


Link to post
Share on other sites
It is very difficult to get a perfect orbit using the gravity equation, I''d expect. The moon doesn''t even have a perfect orbit; it is moving slowly away from the earth (like one meter per year or some such, I read it somewhere. Anyone have the exact figure?)

Share this post


Link to post
Share on other sites
quote:
Original post by Neosmyle
It is very difficult to get a perfect orbit using the gravity equation, I''d expect. The moon doesn''t even have a perfect orbit; it is moving slowly away from the earth (like one meter per year or some such, I read it somewhere. Anyone have the exact figure?)


so I either fake it or find suitable values?

Share this post


Link to post
Share on other sites
quote:
so I either fake it or find suitable values?

Finding suitable values is not too difficult. For circular orbits, one can apply the relation of centripital acceleration to radius and speed. Ac = v**2 / r. Given the initial position, find r, calculate the acceleration, and solve for v. This gives the inital (tangential) speed needed for a stable circular orbit. Making v smaller and larger will not make the orbit unstalbe, it will only make it more elliptical.

Share this post


Link to post
Share on other sites