packages icon
-------------------------------------------------------
Orbit7:  A Simple Gravity Simulator
-------------------------------------------------------
by Mike Sussman <plexus23@aol.com>
and Ben Collins-Sussman <sussman@red-bean.com>
and others: <kfogel@red-bean.com>, <cmpilato@xnet.com>

(C) 1999 under the GNU GPL version 2
-------------------------------------------------------

HISTORY

	This program was originally written by Mike Sussman, a young
	astrophysicist, as a very first C program.  (Originally using
	DOS, Turbo C, and the Borland Graphics Library.)

	His brother Ben ported the code to Xaw, Lesstif, and then
	finally found an excuse to learn GTK+.


REQUIREMENTS

	The ability to compile programs written for GTK+ 1.2 or
	higher.  (The program was developed on a Linux 2.2.x system,
	but should build anywhere GTK is available.)


BUILDING

	Just run `make`.


GUI NOTES

	This program uses the "gtkdial" widget from the GTK Tutorial;
	it was originally meant as a simple example of writing a
	custom widget, but we find it provides a nice "Star Trek" feel
	to the user interface.

PHYSICS NOTES

	Mike Sussman's description of the code is below.

CONTACT & UPDATES

	Please feel free to hack on this program.  It's fun.  We
	welcome any changes or improvements!  Email orbit7@red-bean.com.  

	You can get the latest version from red-bean.com's anonymous
	CVS repository:

	export CVSROOT=:pserver:anonymous@cvs.red-bean.com:/usr/local/cvs
	cvs login
	cvs co orbit7

	(The password for anonymous access is "the key".)


------------------------------------------------


here, incidentally, is a little explanation for that orbit
engine...it's not totally thorough, but it should give a bit of an
overview for someone trying to disect my trainwreck of code....

it all starts with a 2-dimensional array of doubles (far better than
floats, as sensitivity to precision is very important in non-linear
dynamics), where the horizontal axis is the hamiltonian expressed as 5
separate variables - (mass, x-position, y-position, x-velocity,
y-velocity)...

(in case you were wondering, a Hamiltonian is what is known as the
state descriptor - if you know the hamiltonian, then you know you have
necessary and sufficient information to predict the outcome of the
system...in classical mechanics, the hamiltonian is the position and
the momentum....however, in quantum mechanics, the hamiltonian must
contain imaginary numbers - thus why you can only know the position or
the momentum - because the other variable contains uninterpretable
data - after all, what does it mean to say a neutron be traveling at
5i miles per second?)

in my array, the 2nd and 3rd variables are the position, and since
momentum is just mass times velocity, the 1st, 4th, and 5th variables
are the momentum descriptor...so that's how i set up the columns...the
first row is then the sun, while each subsequent row represents
different planets....  something like: Mass x-positions y-position
x-velocity y-velocity

sun 5000 0 0 0 0 
planet1 100 10 0 0 -10 
planet2 100 5 5 5 -5 
planet3 100 15 -5 -3 2

...and so on, for as many planets as your little heart desires....i
believe the code involves some kind of general random function (thanks
again, karl) to generate some positions and velocities for the
planets...actually what i do is give everything a standard radius from
the central star, with a complementary tangential motion for that
radial position, and then offset each planet's position and momentum
by some random amount...currently that randomness is unweighted, but i
suppose i could work in a function to give it a standard bellcurve
randomness....

once this is all said and done, i calculate, for each planet and the
sun, what its change in velocity must be based on the position of
every other planet (since gravity is a function of the distance...) -
this is where the real meat of the proceesor time occurs - it must
calculate every interaction between every two bodies...(note that if
you have 2 objects, there's only 1 interaction, but 3 objects means 3
interactions, 4 bodies is 6 interactions, 5 bodies is 10, etc...in
other words, if the number of bodies is N, the number of interactions
is (N^2 - N)/2...this eats up processor time very quickly as you
increase the objects...i'll have to check the code again, but i'm
afraid i might actually calculate each interaction twice...once from
object A to object B, then again later from object B to object
A...thanks to newton's law about
every-action--means-an-opposite-and-equal-reaction, tho', we should
only have to calculate each interaction once, and then just switch the
direction of that vector for the opposite action...

the acceleration due to gravity is exactly as you'll find in the
textbooks - it's proportional to (mass of gravitating
body)/(distance^2)...of course - this is just a proportion - the
actual number is found by multiplying by a gauge constant...as the
units of velocity, position, and mass are all arbitrary, this is the
only part which requires some tweaking to figure out what will produce
the desired affect - you don't want gravity too strong, or everything
will fall into the sun and produce ugly anamolies when the distance
between objects enters the same order of magnitude as the imprecision
of a double variable...but, you don't want it too weak, or else the
planets will go flying off in hyperbolic orbits, never to return -
this makes for a very boring demo after the first few seconds.
(Interestingly, gauge constants are also the only values in physics
which cannot be derived from theory - they must be empirically
determined...my sloppiness/arbitrariness is thus a consequence of our
own slightly arbitrary universe...)

anyway, each planets/sun now has a new velocity based on the strength
of that gravitational interaction, and based on the new velocity, i
calculate what its new position is...then we redraw all the
planets/sun, and the process begins anew....thus, it goes something
like this:

acceleration = gauge constant * (SUM (from element 1 to N) of ((Mass
of N)/distance^2)) (note that this is all vector addition) velocity +=
gravitational acceleration position += velocity redraw new positions.

as you can see, it takes place as a series of steps - the size of the
steps (just how much each planet moves between each subsequent
calculation) is equivalent to the size of a step one would take to
solve a numerical integration....it's technically arbitrary, but there
are guidelines - you want them large enough to show visible swirling
motion, but if you make them too large, you'll start introducing
inaccuracies and the orbits will start to precess....

Big Fun.  confused? good. write me email, and I'll explain more.