Some Technical
Information on the Animations
The animations are created using Macromedia’s Flash MX 2004 (educational version, which typically costs about $99). You can download a free 30-day trial copy of Flash MX 2004 from www.macromedia.com/software/mx2004/, which will allow you to run the program given below.
Here is the Flash source code for the Almagest Mars animation. The principal part of the program is written in ActionScript, and you can download just that code here. The ActionScript code alone is included in the Flash source code, but you cannot see it without first installing the Flash authoring environment.
The remainder of this document lists the ActionScript code directly. I have included some comment lines that might be helpful in understanding how the code works.
// these first several lines
initialize various parameters
t = 0;
/* the fundamental in Flash, at
least the way I am using it, is to literally compute the position of every
object
on the stage for a given value of time t. Flash
then renders that frame into a graphic image and displays it for you.
Flash will render and display up to 30 frames per second. Thus, a Flash
animation is simply a series of frame images
that you compute for succeeding instants of
time */
dt = 2.0; // the time interval in days
between successive frames
// some variable needed to draw the
trail of the planet
itrail = 0;
var initObject
= new Object();
initObject._alpha = 30;
initObject._xscale = 50;
initObject._yscale = 50;
/* the Flash stage is typically 550
pixels wide and 400 pixels high. The native coordinate system has its origin (0,0)
at the upper left corner of the stage. The
variable x increases horizontally left to right, and
the variable y increases
vertically from top to bottom (i.e. *not*
bottom to top as we normally do things). */
rescale = 1.8;
wt = 0.524051; // mean motion in longitude for Mars
wa = 0.461576; // mean motion in
anomaly for Mars
ws = 360/365.25; // mean motion in
longitude for the Sun (and note that ws = wt + wa, as required for an outer planet).
R = 60*rescale; // we'll typically
use Almagest units, but rescale them to make the image fill the stage
RS = 45*rescale;
e = 6*rescale;
re = 39.5*rescale;
demoIsRunning = false; // this variable gets
toggled depended on whether the animation is running or stopped
drawDiagram(t); // draw the first view of the
stage. This is what you see upon starting the program
function drawDiagram(t)
{
clear(); //erase everthing on the
stage, in preparation for drawing a new frame. Time t has been incremented by dt
with (Math) {
var rpd
= PI/180;
var dpr
= 180/PI;
var gam
= asin(e/R*sin(wt*t*rpd))*dpr; //some geometry need to draw the line from the equant
to the deferent
var rho
= sqrt(R*R+e*e-2*e*R*cos((wt*t-gam)*rpd));
var Ox = 275; // put the Earth at
the center of the stage
var Oy =
200;
var Dx =
Ox; // offset the deferent by the eccentricity e
var Dy =
Oy-e;
var Ex = Dx;
// offset the equant by another step in e
var Ey =
Dy-e;
var Cx =
Ex-rho*sin(wt*t*rpd);
//locate the (moving) center of the epicycle on the deferent
var Cy = Ey-rho*cos(wt*t*rpd);
var Px =
Cx-re*sin((wt+wa)*t*rpd); // locate the position of Mars on the epicycle
var Py =
Cy-re*cos((wt+wa)*t*rpd);
var MSx
= Ox-(R+RS)*sin(ws*t*rpd);
//locate a position of the mean sun
var MSy
= Oy-(R+RS)*cos(ws*t*rpd);
circle(Dx, Dy,
R); //draw the deferent circle
circle(Cx, Cy, re); // draw the
epicycle
lineStyle(2,
0xFF0000, 100);
moveTo(Ox,
Oy); //draw a line from the Earth, to the deferent
center, to the equant, to the center of the
lineTo(Dx, Dy); // epicycle, and finally to the planet
lineTo(Ex,
Ey);
lineTo(Cx, Cy);
lineTo(Px, Py);
lineStyle(2,
0x0000FF, 100);
moveTo(Ox,
Oy); //draw a line from the earth to the mean Sun
lineTo(MSx, MSy);
ballO_mc._x = Ox; // put a small ball at each point of
interest
ballE_mc._x = Ex;
ballD_mc._x = Dx;
ballC_mc._x = Cx;
ballP_mc._x = Px;
ballO_mc._y = Oy;
ballE_mc._y = Ey;
ballD_mc._y = Dy;
ballC_mc._y = Cy;
ballP_mc._y = Py;
ballMS_mc._x = MSx;
ballMS_mc._y = MSy;
O_mc._x = Ox+10; //put a labelling
letter at each point of interest
O_mc._y = Oy+10;
D_mc._x = Dx+10;
D_mc._y = Dy;
E_mc._x = Ex+10;
E_mc._y = Ey-10;
C_mc._x = Cx+10;
C_mc._y = Cy;
P_mc._x = Px+10;
P_mc._y = Py;
MS_mc._x = MSx+RS+10;
MS_mc._y = MSy;
// if the logical variable drawtrail is true, then leave a new ball image in the
current position of Mars.
if (drawtrail) {
ballP_mc.duplicateMovieClip("ballP"+itrail,
itrail+100, initObject);
trailColor = new
Color(_root["ballP"+itrail]);
trailColor.setRGB(0x00FF00);
itrail++;
}
// if the demo is running, move some
of the labels off the stage
if (demoIsRunning) {
C_mc._x = -100;
D_mc._x = -100;
E_mc._x = -100;
}
else {
// and if it not running, put them
back on the stage
C_mc._x = Cx+10;
D_mc._x = Zx+10;
E_mc._x = Ex+10;
}
}
}
/* there are just two drawing
primitives in Flash. You can draw a line from one point to another, or you can
draw
a quadratic Bezier curve from one point to
another. In order to draw a circle, you need to draw eight such
curved segments, as shown below. Drawing an
ellipse is only slight more involved. */
function circle(x, y, R) {
var a = R*0.4086;
var b = R*0.7071;
lineStyle(2,
0x000000, 90);
moveTo(x-R,
y);
curveTo(x-R,
y-a, x-b, y-b);
curveTo(x-a,
y-R, x, y-R);
curveTo(x+a, y-R, x+b, y-b);
curveTo(x+R, y-a, x+R, y);
curveTo(x+R, y+a, x+b,
y+b);
curveTo(x+a, y+R, x, y+R);
curveTo(x-a,
y+R, x-b, y+b);
curveTo(x-R,
y+a, x-R, y);
}
pause_btn.onRelease = function()
{ // if you push (and release)
the pause button, stop playing the movie
onEnterFrame = function () {
stop();
demoIsRunning = false;
drawDiagram(t);
};
};
start_btn.onRelease = function()
{
onEnterFrame = function () { // play the movie forward by incrementing
t by dt
demoIsRunning = true;
drawDiagram(t);
t
+= dt;
};
};
rev_btn.onRelease = function()
{
onEnterFrame = function () { //play the movie backward by decrementing
t by dt
demoIsRunning = true;
drawDiagram(t);
t
-= dt;
};
};
function getSpeed(dt100)
{ //this is how you get the position of
the slider that controls the size of dt
dt = dt100.getValue();
dt = dt/10;
}
drawtrail = false;
trail_btn.onRelease = function()
{ // toggle the logical variable drawtrail by pressing the button
if (drawtrail) {
drawtrail = false;
}
else {
drawtrail = true;
}
};
cleartrail_btn.onRelease = function()
{ // press this button and erase all the
trail balls
for (var i
= 0; i<itrail; i++) {
_root["ballP"+i].removeMovieClip();
}
itrail = 0;
};