Gravity question.

Started by
6 comments, last by taby 16 years, 9 months ago
Im writing a program using newtonian physics, much like asteroids, and I need to be able to determine gravity and its affect on the ship from various objects. Instead of moving the ship around the screen it stays centered and everything moves around it. I use: x_speed += cos(direction) y_speed += sin(direction) to "move" the ship. What math would I use to approximate gravity and how would I implement it?
Advertisement
First, you want to multiply your sin and cos by the distance in units you want the ship to move.

As for gravity, I'll use and Earth-like object for an example which has a gravitational pull of 9.8m/s. This means that all nearby objects will move towards the Earth-like object with an acceleration of 9.8 meters per sec. If your game is updating at 24 frames per second, your ship should accelerate 9.8 / 24 (approx .4083) meters each frame. When updating the movement of the ship, you'd have to move based on the ships trajectory AND the gravitational pull.

To find the angle from your ship to the Earth-like object you'll first need the tangent of the angle. This is the distance between the Y components divided by the distance between the X components ((planet_y - ship_y) / (planet_x - ship_x)). You can then use an arc tangent (atan() function) to find the angle from the tangent. Remember that the angle returned is in radians, not degrees. In case you need to, you can convert radians to degrees by multiplying the radians by (180 / PI).

Hope this helps.
Quit screwin' around! - Brock Samson
Don't listen to a word of the above post.

Ask yourself, do you really even need gravity? gravity is the smallest of the fundamental forces. You won't notice that it's gone unless you're doing a really accurate physical simulation. But here's how it goes:

gravitational force magnitude:

F = G*m1*m2/r^2

where G is 6.67*10^-11, m1 and m2 are the masses of two objects, and r is the distance between the objects.

This force is a vectoral quanity directed along the vector from one object to another.

For large mass ratios (i.e. planet to ship), you can leave out the mass m2, and only apply the force to object 2:

F2 = G*m1/r^2

-------------------------------

Once you have this force vector, you integrate your ship's position as follows:

v += (F/m)*dt
p += v*dt

where dt is the amount of time passed.

remember that F, v, and p are vectoral quantities.

------------------------------

but my real question is, why do you need any help with this if your program uses newtonian physics?
Quote:Original post by Aressera
but my real question is, why do you need any help with this if your program uses newtonian physics?


It's an arcade game; it doesn't have to be perfect, or even realistic.

So here's what we have: a ship whose position is always 0,0, some number of asteroids of possibly varying sizes, and an orientation of the ship that's expressed solely as an angle. The speed is expressed as an X and Y pair (good for you).

Now, I'm assuming you update your world on a per-frame basis, and that's fine for this situation.

coderx75 is right about one thing; since your speed will be changing, just using sine and cosine is insufficient. You'll need to multiply both of those by some variable v representing the speed. Right now, your speed is always 1. With other forces affecting your ship, that's no longer going to be true.

As Aressera noted, the gravitational force is:
F = G * m1 * m2 / (r*r)
where G is the gravitational constant 6.67e-11, m1 is the mass of the ship, m2 is the mass of the asteroid, and r is the distance between them.

Got that? Now forget it.

See, what we do is use the force to get the change in velocity, using F=m*a (force equals mass times acceleration). Ergo a = F/m. Since the F is the aforementioned gravity, and m is the mass of the object being moved (the ship, so m = m1), we can write:

a = G * m2 / (r*r)

So first, this is your game, not Newton's. We're going to do a couple things here:

First, we don't have to use G. Use whatever makes the game look nice. Instead of "G" we're going to use g, some arbitrary constant of your own design. It can be equal to G, pi, 6½ or whatever works. If gravity is too strong, make it smaller. If it's too weak, make it bigger.

Next, I'm assuming that you want bigger asteroids to have a bigger pull. Instead of using m2 for each one, we're going to store the relative effect of each asteroid - so that a normal sized asteroid has a value of 1, and a smaller one might have a value of 2 and so forth. We'll call this c. So m2 for any asteroid can be expressed as:
m2 = b * c
where b is another arbitrary constant. Now we have:
a = g * b * c / (r*r)
But since g and b are both arbitrary, let's lump them together into one final constant k.
a = k * c / (r*r)

So now that we have all of this, what do we do with it?

Starting out, we have this:
// v starts off as 1.0x_speed += v * cos(direction);y_speed += v * sin(direction);


Now what we have to do is go through and work out the gravitational effect of each asteroid:
for (int i=0; i<MAX_ASTEROIDS; i++) {  // Find out how far away it is  // (This is easy since the ship's position is always 0,0  float r2 = asteroid_x*asteroid_x + asteroid_y*asteroid_y;  // Ok, so this is the square of the distance; no sense in wasting it.  // Let's get the acceleration:  float a = k * asteroid_c / r2;  // Now let's get the real distance:  float r = sqrtf(r2);  // Now let's apply the acceleration  x_speed += -a * asteroid_x / r;  y_speed += -a * asteroid_y / r;  // We're done!}


HTH
We''re sorry, but you don''t have the clearance to read this post. Please exit your browser at this time. (Code 23)
In my opinion, calculating realistic gravity for a video game like this is overkill. The actual force due to gravity would probably be negligible within the context of a space shooter or something asteroids-like... unless you intend to have incredibly dense asteroids that are much more massive than actual asteroids of their size. Nothing that fits on the screen is going to exert enough force to alter your ship's behavior--again, under normal circumstances.
Quote:Original post by smitty1276
In my opinion, calculating realistic gravity for a video game like this is overkill. The actual force due to gravity would probably be negligible within the context of a space shooter or something asteroids-like... unless you intend to have incredibly dense asteroids that are much more massive than actual asteroids of their size. Nothing that fits on the screen is going to exert enough force to alter your ship's behavior--again, under normal circumstances.


Nor is it realistic to have a very dense asteroid field where the asteroids fling in random directions and only take one laser shot to destroy. It's fun though, and that's the point. :D

(Astronauts on the Apollo reported that objects moving away from the left side of the ship suddenly reappeared on the right side on the ship, forcing them to rethink the way they do evasive maneuvers. This has become less of a problem since the RAM in the onboard computers has increased. :P)
We''re sorry, but you don''t have the clearance to read this post. Please exit your browser at this time. (Code 23)
Wow. Thank you for the great answeres erissian and Aressera. Very helpfull.

I will clarify on the course of my project. Years ago I played a arcade style game where you controlled your ship, like you do in asteroids, and flew from star-system to star-system taking over planets. Once you captured the planet (by landing on it) NPC ships origonating from your home planet would make their way to the newly captured planet to colonize it. Meanwhile 1-3 computer opponents were trying to do the same. I cant remember for the life of me what the game was called but I thought that, despite its simplicity, it was pretty brilliant.

That is what im trying to emulate if to a larger scale. I wish I could remember what it was called though. Anyone have any idea?

In any case it's coming along nicely so far. I still have the implement gravity and a lot of optimization code. As far as gravity goes it doesnt have to be super accurate or realisitc. It is an arcade game after all.
I personally would leave G as is, and if you are wanting greater attraction, adjust the mass of each object instead (twice the attraction, twice the mass).

Here's some C++ code to implement Newtonian gravitation in 2D:

#include <iostream>using std::cout;using std::endl;#include <cmath>int main(void){	double G = 6.674e-11;	// Parameters of body 1.	double m1 = 4;	double pos_x1 = 234;	double pos_y1 = 122;	double vel_x1 = 0;	double vel_y1 = 0;	// Parameters of body 2.	double m2 = 6;	double pos_x2 = 100;	double pos_y2 = 122;	double vel_x2 = 0;	double vel_y2 = 0;	// Find the distance between the bodies (Pythagorean theorem).	double dist_x = fabs(pos_x1 - pos_x2);	double dist_y = fabs(pos_y1 - pos_y2);	double r = sqrt(dist_x*dist_x + dist_y*dist_y);	// Calculate the acceleration scalar.	double a1 = (G*m2)/(r*r);	double a2 = (G*m1)/(r*r);	// Find unit-length vectors pointing from one to the other.	double dir_x1 = (pos_x2 - pos_x1) / r;	double dir_y1 = (pos_y2 - pos_y1) / r;	double dir_x2 = (pos_x1 - pos_x2) / r;	double dir_y2 = (pos_y1 - pos_y2) / r;	// Translate first.	pos_x1 += vel_x1;	pos_y1 += vel_y1;	pos_x2 += vel_x2;	pos_y2 += vel_y2;	// Accelerate second.	vel_x1 += a1*dir_x1;	vel_y1 += a1*dir_y1;	vel_x2 += a2*dir_x2;	vel_y2 += a2*dir_y2;	return 0;}

This topic is closed to new replies.

Advertisement