Maths/ Gravity Simulation
Use right-click to add and delete planets, moons and spacecraft.
Also use right-click to change the size (ie. weight) of planets.
Drag the green arrows to change the initial velcities
By default, planets are assumed to be large enough to not be affected by gravity.
Explanation and code
Newton's Universal Law of Gravity is used to find the forces between each object and update their positions.
Each object gets a force from each of the other objects.
The force the A exerts on B and the force that B exerts on A are equal, and are given by:
| Force = | G.MA.MB |
|---|---|
| r2 |
G is a constant - in reality in has a scientifically determined value - but in AS code it is adjusted until the animation looks fine.
MA and MB are the masses (ie. weights) of the objects, and 'r' is the distance between them
Let's take a look at the code, placed in the AS file for each object
1. var forcex:Number = 0; 2. var forcey:Number = 0; 3. var force:Object = new Object(); 4. for (var i:Number=0; i<=othernum; i++) { 5. if (i != myIndex) { 6. force = getForce(i); 7. forcex += force.x; 8. forcey += force.y; 9. } 10. } 11. ax = forcex/weight; 12. ay = forcey/weight; 13. vx += ax; 14. vy += ay; 15. updatexy(xpos+vx, ypos+vy);
Lines 4 and 5 go through each object different to the current object. We get the force using the formula above and sum all the x and y components to get the total force.
We use Newton's Law (acceleration = force/mass) to find the accelerations. Each frame, the velocity is incremented by the velocities and the x,y positions of the object in question are updated.
Here is the function to find the forces:
16. private function getForce(i:Number):Object { 17. var other:Planet = _root.getP(i); 18. var r:Object = new Object(); 19. var dx:Number = other.xpos-xpos; 20. var dy:Number = other.ypos-ypos; 21. var rsqr:Number = dx*dx+dy*dy; 22. var f:Number = gravC*weight*other.weight/(rsqr); 23. var theta:Number = getAngle(dy, dx); 24. //theta is between 0 and 2 pi, measured anticlockwise 25. r.x = f*Math.cos(theta); 26. r.y = f*Math.sin(theta); 27. return r; 28. }
This function gets the x and y components of the force. 'dx' and 'dy' are the x and y distances between the objects, and 'rsqr' is r2 as in the formula above. Line 22 is the important line - where we use the formula above.
To get the x and y components of the force we multiply by the cosine and sine of the angle made by the force.
29. private function getAngle(dy:Number, dx:Number):Number { 30. var theta:Number; 31. if (dx == 0) { 32. if (dy > 0) { 33. theta = Math.PI/2; 34. } 35. else { 36. theta = 3*Math.PI/2; 37. } 38. } 39. else { 40. theta = Math.atan(dy/dx); 41. if (dx < 0) { 42. theta += Math.PI; 43. } 44. } 45. return theta; 46. }
And finally this function returns the angle made by the vector with x and y components 'dx' and 'dy'.
This code has one proviso - that by default in my activity I assume that planets are so large in reality that gravity doesn't affect them.