JS Lemming 122 Report post Posted August 30, 2005 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! 0 Share this post Link to post Share on other sites
ZQJ 496 Report post Posted August 30, 2005 Well the classical Newtonian formula for gravity is:F = GMm/r^2G - gravitational constantM and m - mass of two (point) bodiesr - separation of two bodiesThe 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). 0 Share this post Link to post Share on other sites
JS Lemming 122 Report post Posted August 30, 2005 Thanks! I'll attempt to write out a demo. If it explodes.... I'll know it's unstable. 0 Share this post Link to post Share on other sites
Guest Anonymous Poster Report post Posted August 30, 2005 FROM: http://hyperphysics.phy-astr.gsu.edu/hbase/grav.html#gravX1, X2 are the x-coordinates of body 1 and 2 repectfullyY1, Y2 are the y-coordinates of body 1 and 2 repectfullyM1, M2 are the masses of body 1 and 2 repectfullyRXsquared = (X1-X2)^2RYsquared = (Y1-Y2)^2Rsquared = RXsquared + RYsquaredFgrav = (M1*M2) / RsquaredBTW Fgrav is simplifiedFrom newton: Force = Mass * AccelerationWe need to find the change in velocity AKA accelerationSo Acceleration = Force / MassA1 = (Fgrav/M1)You'll need to split the acceleration into X and Y componentsIf X1< 0 Share this post Link to post Share on other sites
Guest Anonymous Poster Report post Posted August 30, 2005 google "universal gravitation" 0 Share this post Link to post Share on other sites
JS Lemming 122 Report post Posted August 30, 2005 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 componentsIf 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. 0 Share this post Link to post Share on other sites
JS Lemming 122 Report post Posted August 30, 2005 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# NextWhat could be causing my planets to just explode out of view? 0 Share this post Link to post Share on other sites
Guest Anonymous Poster Report post Posted August 30, 2005 Try adding a timestep t to your formulas.Vel = Vel + Acc * tPosition = Position + Vel * tLower 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. 0 Share this post Link to post Share on other sites
JS Lemming 122 Report post Posted August 31, 2005 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 angleSlope# = (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 calculatedcur1\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. 0 Share this post Link to post Share on other sites
Guest Anonymous Poster Report post Posted August 31, 2005 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. 0 Share this post Link to post Share on other sites
timw 598 Report post Posted August 31, 2005 I'm fairly certian that the problem of a rotation body about antoher body can be solved analitically. since the sun is so massive, to a close approximation, we can ignore gravity from other planets. I'm fairly certian for the problem of one planet orbiting abround the sun, you can derive a paramaterized version of the motion, after all, we know from kepler law that it travels in an eliptical path, and we can certianally prarmaterize an elipse. I think you could build an elipse representing the positions of the planet, and use energy consideration to find the velocity of the planet. this would be certianlly faster then integrated force approach, furthermore, since it is traveling in a paramaterizxed curve, it eliminates the problem you have with to large of a time step, naimly divergance from the eliptical path. to use energy consideration you could do something like thisyou know that the sum potentialEnergyDueToGravity + kineticEnergyOfPlanet = Constant; the potential energy due to gravity can be easily calculated, and the kinetic energy can be solved for using the above equation, which would give us the velocity of the object. also, this technique is sutable for real time.tim 0 Share this post Link to post Share on other sites
JY 289 Report post Posted September 1, 2005 Still nobody posted the gravitational constant:gravitational constant = 6.67300 × 10-11 m3 kg-1 s-2 0 Share this post Link to post Share on other sites
JS Lemming 122 Report post Posted September 1, 2005 Dang... I think I did what you said... but it's not working to well. All the bodies just start moving down-right instead of toward each other. Here is the code I have now: ;Cycle through and update all existing bodies For cur1.Body = Each Body For cur2.Body = Each Body If cur1\ID <> cur2\ID ;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 ratio Ratio# = Sqr(RYsquared#)/Sqr(RXsquared# + RYsquared#) ;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# * Ratio# cur1\yvel = cur1\yvel + A1# * Ratio# EndIf Next ;Adjust the position of the bodie based on it's 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 NextI bet I'm doing something really stupid... but I'm not sure. 0 Share this post Link to post Share on other sites
Ysaneya 1383 Report post Posted September 2, 2005 Quote:Original post by JS LemmingDang... I think I did what you said... but it's not working to well. All the bodies just start moving down-right instead of toward each other. Here is the code I have now:*** Source Snippet Removed ***I bet I'm doing something really stupid... but I'm not sure.The formula calculates the intensity of the force, and you're applying it as a direction too.What you should do is to calculate the vector between the centers of your two bodies, normalize it, and then multiply it by the gravitation intensity. This is your acceleration force for one of the two bodies, the other one is reversed. You should then take into account the mass of each body to calculate the change of velocity.Y. 0 Share this post Link to post Share on other sites
Guest Anonymous Poster Report post Posted September 2, 2005 That ratio you have is the same as the sine. Except you're taking the square root of y^2 and that basically just loses the sign information, which is not what you want to do, it creates the same problem as using atan. Also cosine is dx/sqrt(dx^2+dy^2), so use that for determining how much of the acceleration to apply in the x direction. 0 Share this post Link to post Share on other sites
Jotaf 280 Report post Posted September 2, 2005 For anyone who is trying to use atan for this effect: don't :PRead up on atan2, it's a wrapper around the atan function that automatically gives you the output you want. Just be careful not switching around the coordinates, that still happens to me sometimes ;) 0 Share this post Link to post Share on other sites
JS Lemming 122 Report post Posted September 2, 2005 Woot! It works! Thanks for all your help. Now I need to add a time step and somehow work the real gravitational constant into the mug. 0 Share this post Link to post Share on other sites