Posted on Tuesday 22 March 2005
A math-challenged teacher sent me an email today asking how she could simulate Newton's law of gravitation in Flash: namely, show the earth moving around the sun in an elliptical orbit. Since it's a classical example of applying math to Flash programming, I figured I might help her and other people here.
Newton's law of gravitation states that the gravitational force between two bodies is . Here r is the radius between the two bodies, F is the force,
and
are the masses of the bodies. From Pythagora's theorem we know that
, where
and
are the distances between the bodies measured on the x and y axes respectively. We know that
, where m is the mass, a is the acceleration of the body and F is the force exerted.
The trouble here is that the last equation is vectorial and the first is scalar. We know the absolute value of the force exerted on the body but we do not know it's direction from the first equation. In fact, the force on the first body is directed in the direction of the second body. For the forces to add up properly, we need to have . A quick look will convince you that the correct solution is
and
. Why? Remember that
. Just replace into the previous equation and verify that this works. But what is theta then? Since
, then
.
All right, putting this all together we get:
And:
The big question is: how does this translate into Flash. x and y are pretty obviously the screen coordinates here. But what about the acceleration? Remember that the acceleration is the speed at which the speed changes. You can set a discrete time scale in your Flash movie such that 1 frame equals a discrete step in time. Then x will be equal to the previous x plus the current speed. And the current speed will be equal to the previous speed plus the current acceleration. This acceleration can be easily calculated from the above formulas.
Since the teacher told me her course was in Flash MX, let's do it in AS1. Assuming there is a movieclip on the root of the timeline called mcEarth and another called mcSun, placing this script on the main timeline will emulate gravitation:
with(mcEarth)
{
vx = 3;
vy = -2;
ax = 0;
ay = 0;
scaling = 3500;
}
mcEarth.onEnterFrame = function()
{
var a = scaling/(Math.pow(this._x - this._parent.mcSun._x, 2) +
Math.pow(this._y - this._parent.mcSun._y, 2)) ;
var theta = Math.atan2(this._parent.mcSun._y - this._y,
this._parent.mcSun._x - this._x);
ax = a*Math.cos(theta);
ay = a*Math.sin(theta);
vx += ax;
vy += ay;
this._x += vx;
this._y += vy;
}
Here we've assumed (as is usually done) that only the earth moves and not the sun. The 'scaling' variable replaces the gravitational constant and the masses. Otherwise this is a straightforward transposition of the previous analysis.
Can we solve the three-body problem? Sure we can! In fact the approach we're using to simulate gravitation is the exact one used by Feynman in his Lectures on Physics to solve the three body problem numerically. All we need is create a controller object that stores all references to the 'planets' and a bunch of planet objects that happily dance around the screen. Obviously this benefits from an OOP approach so here I'm moving to AS2. Here's the result:
Planets are put on the stage randomly whenever they collide or go off-screen. Download the source here.


