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, 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]);




// 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 () {


                        demoIsRunning = false;




start_btn.onRelease = function() {

            onEnterFrame = function () {      // play the movie forward by incrementing t by dt

                        demoIsRunning = true;


                        t += dt;



rev_btn.onRelease = function() {

            onEnterFrame = function () {     //play the movie backward by decrementing t by dt

                        demoIsRunning = true;


                        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++) {



            itrail = 0;