My physics algorithm

//Setting initial variables, constants and arrays
//if α is true, this is the first run of the algoritm. This is used to set inital positions once
α = true;
//sigma (aka. the sum of) is the count of the particles on screen, starts at 0
sigma = 0;
//this is hard to explain. the satge dimensions are variable (maximise/restore mess with these values) so they are recorded initially and the first values are used in calculations
stageHeight = Stage.height;
stageWidth = Stage.width;
//The stage containg the paths of movement. 201 is the depth, a random large value
this.createEmptyMovieClip("paths", 201);
//The scale constant is used in the constant array (k) to keep the forces in proportion. this can be changed for different models
scaleConstant = Math.pow(10, 10);
//An array of the constants of the force equations, in order: gravity, electro, strong Nuc.
k = new Array(-7.42583*Math.pow(10, -21)*scaleConstant, 1*scaleConstant, -100*scaleConstant);
//The properties that each force acts upon, in same order as above
propertyArray = new Array("mass", "charge", "colour");
//the base units of electrons for these properties, scaled with the K value, to keep proportion.
unitCharge = 1.78266*Math.pow(10, -29)*k[1];
unitMass = -1.36491*Math.pow(10, -20)*k[0];
unitColour = (1.78266*Math.pow(10, -29)*k[2])/10;
//the scale of the base unit mass of an electron to a proton (aka, a proton mass is unitMassMultiplier*unitMass)
unitMassMultiplier = 1836.152671;
//The subroutine for positioning the particles, runs every frame after forces is run.
position = function () {
//trace("test");
//For all the particles (0-sigma(particle count))
for (var sub = 0; sub //Drawing:
paths.lineStyle(1, 000000);
paths.moveTo(_root[sub]._x, _root[sub]._y);
//eqations for force->acceleration->speed->position for X,Y and Z
_root[sub].Xacceleration = _root[sub].Xforce/_root[sub].mass;
_root[sub].Xspeed += _root[sub].Xacceleration;
_root[sub].Yacceleration = _root[sub].Yforce/_root[sub].mass;
_root[sub].Yspeed += _root[sub].Yacceleration;
_root[sub].Zacceleration = _root[sub].Zforce/_root[sub].mass;
_root[sub].Zspeed += _root[sub].Zacceleration;
_root[sub].xIota += _root[sub].Xspeed;
_root[sub].yIota += _root[sub].Yspeed;
_root[sub].zIota += _root[sub].Zspeed;
//trace(_root[sub].Yforce)
//setting where the representations of the particles are (and how big they appear) using my equations for perspective
/////Should definately be revisited, will need to look into the idea of being able to move the view around to see what's goin on from various angles
_root[sub]._x = (_root[sub].xIota/Math.pow(2, _root[sub].zIota/stageWidth))+(stageWidth*((Math.pow(2, _root[sub].zIota/stageWidth)-1)/Math.pow(2, (_root[sub].zIota/stageWidth)+1)));
_root[sub]._y = (_root[sub].yIota/Math.pow(2, _root[sub].zIota/stageHeight))+(stageHeight*((Math.pow(2, _root[sub].zIota/stageHeight)-1)/Math.pow(2, (_root[sub].zIota/stageHeight)+1)));
_root[sub]._xscale = 100/Math.pow(2, _root[sub].zIota/stageWidth);
_root[sub]._yscale = 100/Math.pow(2, _root[sub].zIota/stageHeight);
//More drawing
paths.lineTo(_root[sub]._x, _root[sub]._y);
}
};
//Subroutine for calculating the forces. the parameters are (the first particle, the last particle) so that atoms can be considered individually if their particles are consecutive and the first and last are known
forces = function (alpha, omega) {
//For all the particles considered
for (var sub = alpha; sub //set all forces and components to 0
_root[sub].force = 0;
_root[sub].Xforce = 0;
_root[sub].Yforce = 0;
_root[sub].Zforce = 0;
//for all the particles considered
for (var ob = alpha; ob //except itsrself
if (sub != ob) {
//trace(alpha+" "+omega)
//find difference in X,Yand Z
deltax = (_root[ob].xIota)-(_root[sub].xIota);
deltay = (_root[ob].yIota)-(_root[sub].yIota);
deltaz = (_root[ob].zIota)-(_root[sub].zIota);
//find R squared, using pythag. it's kept as Rsquared (not R) because the force equations use R squared
Rsquared = (Math.pow(deltax, 2))+(Math.pow(deltay, 2))+(Math.pow(deltaz, 2));
//Find the angles (for magnitude AND direction)
beta = Math.atan(Math.sqrt(Math.pow(deltax, 2))/Math.sqrt(Math.pow(deltay, 2)));
theta = Math.atan(Math.sqrt(Math.pow(deltaz, 2))/Math.sqrt(Math.pow(deltax, 2)));
zeta = Math.atan(Math.sqrt(Math.pow(deltay, 2))/Math.sqrt(Math.pow(deltaz, 2)));
//trace(Math.tan(beta)+", "+1/(Math.tan(zeta)*Math.tan(theta)));
//trace(theta[ob][sub])
//trace(_root[sub].yIota);
//for all the force constants
for (var i = 0; i //work out only magnitude force with the appropriate constant and properties, with good use of the arrays
_root[sub].force = (k[i]*_root[sub][propertyArray[i]]*_root[ob][propertyArray[i]])/Rsquared;
//finding the directional components of the force using the angles, for X, Y and Z
if (deltax>0) {
_root[sub].Xforce -= _root[sub].force*Math.cos(theta);
} else {
_root[sub].Xforce += _root[sub].force*Math.cos(theta);
}
if (deltay>0) {
_root[sub].Yforce -= _root[sub].force*Math.cos(beta);
} else {
_root[sub].Yforce += _root[sub].force*Math.cos(beta);
}
if (deltaz>0) {
_root[sub].Zforce -= _root[sub].force*Math.cos(zeta);
} else {
_root[sub].Zforce += _root[sub].force*Math.cos(zeta);
}
}
}
}
//scaling of arrows in the particle for a more visual representation of what's happening with the forces
_root[sub].Yarrow._xscale = _root[sub].Yforce*Math.pow(10, 33);
_root[sub].Xarrow._xscale = _root[sub].Xforce*Math.pow(10, 33);
_root[sub].Zarrow._xscale = _root[sub].Zforce*Math.pow(10, 33);
//trace(zeta);
//trace(sub+", "+_root[sub].Xforce);
//trace(sub+", "+_root[sub].Xforce);
}
};
//Subroutine for setting the initial states (orbit velocities mainly)
initialStates = function () {
//for all particles
for (var sub = 0; sub //work out forces inside the atom. this was an internally stable atom can be set up, any unstability (likelyness for the electron to go freelance) is exterior after this (as would be in reality).
forces(_root[sub].Parent, _root[sub].Last);
//for (var ob = 0; ob //if (_root[sub].Parent == _root[ob].Parent && sub != ob) {
//This works out the centre of mass, around which all particles in the atom should rotate.
midx = 0;
midy = 0;
midz = 0;
totmass = 0;
for (var i = _root[sub].Parent; i<_root[sub].Last; i++) {
midx += _root[i].mass*_root[i].xIota;
midy += _root[i].mass*_root[i].yIota;
midz += _root[i].mass*_root[i].zIota;
totmass += _root[i].mass;
}
Midx = midx/totmass;
Midy = midy/totmass;
Midz = midz/totmass;
//Positioning a marker for this mid point, using the perspective equation again.
MidMarker._x = (Midx/Math.pow(2, Midz/stageWidth))+(stageWidth*((Math.pow(2, Midz/stageWidth)-1)/Math.pow(2, (Midz/stageWidth)+1)));
MidMarker._y = (Midy/Math.pow(2, Midz/stageWidth))+(stageWidth*((Math.pow(2, Midz/stageWidth)-1)/Math.pow(2, (Midz/stageWidth)+1)));
//trace(sub+" - "+ob+" - "+_root[sub].Xspeed);
//setting the initial velocities using f = (m*v squared)/R, where R is the distance from particle to the centre of mass.
///This works perfectly in 2 dimensions, am currently working on the third. More theory is needed.
if (_root[sub].yIota-Midy>0) {
_root[sub].Xspeed -= Math.sqrt(Math.sqrt(Math.pow(((_root[sub].Yforce*(_root[sub].yIota-Midx))/_root[sub].mass), 2)));
//trace(sub+", "+ob+", -X "+_root[sub].Xspeed);
} else {
_root[sub].Xspeed += Math.sqrt(Math.sqrt(Math.pow(((_root[sub].Yforce*(_root[sub].yIota-Midx))/_root[sub].mass), 2)));
//trace(sub+", "+ob+", X "+_root[sub].Xspeed);
}
if (_root[sub].xIota-Midx<0) {
_root[sub].Yspeed -= Math.sqrt(Math.sqrt(Math.pow(((_root[sub].Xforce*(_root[sub].xIota-Midx))/_root[sub].mass), 2)));
//trace(sub+", "+ob+", -Y "+_root[sub].Yspeed+", "+_root[sub].Xforce+", "+_root[sub].xIota+", "+Midx+", "+_root[sub].mass);
} else {
_root[sub].Yspeed += Math.sqrt(Math.sqrt(Math.pow(((_root[sub].Xforce*(_root[sub].xIota-Midx))/_root[sub].mass), 2)));
//trace(sub+", "+ob+", Y "+Math.sqrt(Math.pow(((_root[sub].Xforce*(_root[sub].xIota-Midx))/_root[sub].mass), 2)));
}
//}
//}
}
};
//Subroutine for making particles, upsilon is the name of the particle (e or P currently)
make = function (upsilon, X, Y, Z, Xspeed, Yspeed, Zspeed, charge, mass, colour, parent, particles) {
//attaching the movie initially called 'a' in the library, where sigma is the current count, and is set as the new name and the depth
_root.attachMovie("a", sigma, sigma);
//Setting the label (text box within mov.clip 'a') to the particle name and its number, just to keep track
_root[sigma].label.text = upsilon+sigma;
//this sets the parent particle of the atom, or the number of the first particle in the atom (for working out forces in an atom in initialStates)
_root[sigma].Parent = parent;
//finding the last particle in the parent atom,
_root[sigma].Last = parent+particles;
//setting first positions, speeds and properties, these are carried over from when the subroutine is called
_root[sigma].xIota = X;
_root[sigma].yIota = Y;
_root[sigma].zIota = Z;
_root[sigma].Xspeed = Xspeed;
_root[sigma].Yspeed = Yspeed;
_root[sigma].Zspeed = Zspeed;
//trace(_root[sigma].Yspeed)
//_root[sigma]._x = _root[sigma].xIota;
//_root[sigma]._y = _root[sigma].yIota;
_root[sigma].charge = charge;
_root[sigma].mass = mass;
_root[sigma].colour = colour;
//increase total count
sigma++;
};
//Subroutine for the creation of structures
///this should eventually be a library for all the chemicals and situations that can show/test the functions, right now the most complex structure is a pair of atoms
//The first 7 parameters here are needed for all structures, the letters are just arbitrary parameters that will change from structure to structure (so there is no point giving them sensible names)
create = function (structure, X, Y, Z, Xspeed, Yspeed, Zspeed, A, B, C, D, E, F, G) {
//trace(sigma);
//Using the case switch to choose structure
switch (structure) {
case "atom" :
startAtom = sigma;
particles = A+B;
//the radius of the atom, may need to set up many when more shells are possible
rho = 10;
//the angle the electron should start in, should be a value from 0-1 because ther are multiplied by 2PI when they're used
theta = 0;
zeta = 0;
beta = 0;
//Calling create again, with different perameters. once an atom is perfected, creating molecules will create atoms in the structure defined. and so everything need only be defined once.
create("nucleus", X, Y, Z, Xspeed, Yspeed, Zspeed, startAtom, particles, A);
create("extereus", X, Y, Z, Xspeed, Yspeed, Zspeed, startAtom, particles, B, rho, theta, zeta, beta);
break;
case "nucleus" :
for (var i = 0; i switch (i) {
case 0 :
make("P", X, Y, Z, Xspeed, Yspeed, Zspeed, unitCharge, unitMass*unitMassMultiplier, unitColour, A, B);
break;
case 1 :
make("P", X-5, Y, Z, Xspeed, Yspeed, Zspeed, unitCharge, unitMass*unitMassMultiplier, unitColour, A, B);
break;
}
}
break;
case "extereus" :
//An extereus, as opposed to the nucleus, is the exterior of the atom. aka the electrons
for (var i = 0; i switch (i) {
case 0 :
//here the position relative to the nucleus is worked out using the angles. Make is called with relevant perameters
make("e", X+(D*Math.cos(E*2*Math.PI)), Y-(D*Math.cos(G*2*Math.PI)), Z-(D*Math.cos(F*2*Math.PI)), Xspeed, Yspeed, Zspeed, -unitCharge, unitMass, 0, A, B);
break;
case 1 :
make("e", X+(D*Math.cos((E+0.5)*2*Math.PI)), Y-(D*Math.cos((G+0.5)*2*Math.PI)), Z-(D*Math.cos((F+0.5)*2*Math.PI)), Xspeed, Yspeed, Zspeed, -unitCharge, unitMass, 0, A, B);
break;
}
}
break;
case "pair" :
create("atom", X-100, Y, Z, Xspeed, Yspeed, Zspeed, 1, 2);
create("atom", X+100, Y, Z, Xspeed, Yspeed, Zspeed, 1, 2);
break;
}
};
//That which needs no explanation
god = function () {
//on the first run
if (α) {
//define the structure to be created, must be in the library
//here perameters are (structure, X,Y,Z, X vel, Y vel, Z vel, neucleons, electrons)
create("atom", 100, 100, 200, 0.5, 0.5, -5, 1, 1);
//set the first speeds
initialStates();
//the first run is over
α = false;
}
//work out forces for all particles
forces(0, sigma);
//position the particles
position();
};
//Run god on every frame
this.onEnterFrame = function() {
god();
};