Planetary Gravity.

Started by
15 comments, last by JS Lemming 18 years, 7 months ago
Well, googling "planetary gravity formula" didn't get me anywhere... I'm tring to figure out how to make a program that simulates gravity of bodyies in space like planets and moons and such. The bodies would probably have a certain mass and density and such. Now how would I go about doing this? I'm guessing there is some crazy complicated formular out there that I can just input a bunch of values to get the velocities/locations on the bodies. See, I think it would be fun to set moons in orbit around planets and such. And once I get this working I'll probably make some extreme pong game with planets in the arena that effect the ball. Thanks for any info!
Down with the cotton gin!
Advertisement
Well the classical Newtonian formula for gravity is:

F = GMm/r^2

G - gravitational constant
M and m - mass of two (point) bodies
r - separation of two bodies

The reason I write (point) is because is also applies to perfectly spherical bodies and is a good enough approximation if the two things are far enough apart. I don't know how much this is going to help a simulator though, from what I've heard you're likely to suffer stability problems. I'd look up a good numerical integration method (can't remember the name of the one I last used at the moment).
Thanks! I'll attempt to write out a demo. If it explodes.... I'll know it's unstable.
Down with the cotton gin!
FROM: http://hyperphysics.phy-astr.gsu.edu/hbase/grav.html#grav

X1, X2 are the x-coordinates of body 1 and 2 repectfully
Y1, Y2 are the y-coordinates of body 1 and 2 repectfully
M1, M2 are the masses of body 1 and 2 repectfully

RXsquared = (X1-X2)^2
RYsquared = (Y1-Y2)^2
Rsquared = RXsquared + RYsquared
Fgrav = (M1*M2) / Rsquared
BTW Fgrav is simplified

From newton: Force = Mass * Acceleration
We need to find the change in velocity AKA acceleration
So Acceleration = Force / Mass
A1 = (Fgrav/M1)

You'll need to split the acceleration into X and Y components
If X1<
google "universal gravitation"
Awww... Anonymous Poster(first one), thanks for the straigt forwardness.... I thought I had it in the bag. My only trouble was being caused by the "splitting of the acceleration into the X and Y"... Can you finish that last little part you were about to say?

"You'll need to split the acceleration into X and Y components
If X1<"

I'm guessing I need to find the angle at which the second body is located with respect to the first(the one I'm calculating this for)... and then doing something like xvel = xvel + A1*cos(angle) and the same for yvel. Is that right? If so, then how do I acquire the angle mathmaticly.
Down with the cotton gin!
Nevermind about that... I just did arc tan of the slope. I think that's how it's done. And then I did the:

cur1\xvel = cur1\xvel + A1#*Sin(SlopeAngle#)
cur1\yvel = cur1\yvel + A1#*Cos(SlopeAngle#)

So I guess that's all right. Now when I run the program, I see the two bodies for an instant then they disappear. I'm not sure what's up there. What value should I use for the mass of the bodies? A large number say 300 or something super small like 0.003? I tried both and it still disappears in an instant.

Here is the code for updating the bodies (if it's any help):
	;Cycle through and update all existing bodies	For cur1.Body = Each Body		For cur2.Body = Each Body					;Calculate gravitational force			RXsquared# = (cur1\x-cur2\x)*(cur1\x-cur2\x)			RYsquared# = (cur1\y-cur2\y)*(cur1\y-cur2\y)			Rsquared# = RXsquared + RYsquared			Fgrav# = (cur1\mass*cur2\mass)/Rsquared						;Calculate the slope angle			Slope# = (cur2\y-cur1\y)/(cur2\x-cur1\x)			SlopeAngle# = ATan(Slope)						Next				;Calculate acceleration based on (Force = Mass * Acceleration)		A1# = (Fgrav/cur1\mass)				;Adjust the velocities of this body based on the force calculated		cur1\xvel = cur1\xvel + A1#*Sin(SlopeAngle#)		cur1\yvel = cur1\yvel + A1#*Cos(SlopeAngle#)				;Adjust the position of the bodies based on their velocity		cur1\x = cur1\x + cur1\xvel		cur1\y = cur1\y + cur1\yvel				;Draw the body		Color 255,255,255		Oval cur1\x-cur1\radius,cur1\y-cur1\radius,cur1\radius*2,cur1\radius*2,1				Color 0,0,255		Text cur1\x-cur1\radius,cur1\y-cur1\radius-20,"Force: "+A1#			Next


What could be causing my planets to just explode out of view?
Down with the cotton gin!
Try adding a timestep t to your formulas.

Vel = Vel + Acc * t
Position = Position + Vel * t

Lower values of t will result in more accuracy but a slower simulation. It's nice to be able to control it. This is a basic explicit integration scheme, and it should work fine for what you're doing for now. The errors will tend to make the bodies gain energy as the simulation runs, so if you get bodies orbiting each other, the orbits may slowly get larger and larger. More sophisticated integration schemes have less error; some integration schemes will tend to reduce the energy in the system instead of increase it. But for getting planets to orbit each other this simple scheme is good enough.

Also it looks like you might be trying to make a planet apply its gravitational force to itself. The distance between a planet and itself is 0, so you end up dividing by 0 and getting infinite force.
Thanks Anonymous Poster, I didn't realize I was calculating the bodies by them selves. That fixed the exploding out of view problem. But before I add a time step, can someone tell me how to correctly split that acceleration into the X and Y components? I did this:

;Calculate the slope angle
Slope# = (cur2\y-cur1\y)/(cur2\x-cur1\x)
SlopeAngle# = ATan(Slope)

;Calculate acceleration based on (Force = Mass * Acceleration)
A1# = (Fgrav/cur1\mass)

;Adjust the velocities of this body based on the force calculated
cur1\xvel = cur1\xvel + A1#*Sin(SlopeAngle#)
cur1\yvel = cur1\yvel + A1#*Cos(SlopeAngle#)

But I don't think that works perfectly. What happens when I run the program is the two bodies move in the same direction instead of towards each other. I think it has something to do with the fact that slope doesn't account for direction... so I need to somehow get a negative sometimes or something.
Down with the cotton gin!
For one thing, I think you might have the sine and cosine parts mixed up. I'm not entirely sure about that though.

More importantly, yeah, the atan function has a period of 180 degrees. It returns the same angle for a vector as it would for a vector pointing in exactly the oposite direction. There's usually an atan2 function that takes the x and y components separately and works in any direction, or you can check if the x component is negative and if so add 180 degrees or pi radians or whatever units it is in to the angle returned by atan.

Or you can avoid trigonometric functions altogether. The sine of an angle of a vector can be interpreted as the ratio of the y component to the magnitude. You already can calculate this ratio without using any angles. If the distance between the bodies in the x direction is dx and the distance in the y direction is dy, the ratio is just dy/sqrt(dx^2 + dy^2). This will also give the correct sign.

And if you really wanted to for some reason, there are a few simple optimizations. One of them is if you use the formula above, it includes what you are already calculating and calling RSquared. Another is that the force A is applying to B is equal in magnitude and opposite in direction to the force B is applying to A (equal and opposite reaction...). This allows you to perform almost half as many calculations when calculating the gravitational forces between n bodies.

This topic is closed to new replies.

Advertisement