This project displays the common natural phenomenon expressed
by the inverse-square law. Essentially what this shows us
is that, for many types of acting forces (e.g. gravity or
magnetism), the strength of the force varies inversely with
the square of the distance between the two bodies the force
acts upon. In this case, the formula used is the standard
formula for the Law of Gravitational Attraction: 
(m1 * m2 * G) / (r^2).

This particular model demonstrates the effect of gravity
upon a system of interdependent particles. You will see each
particle in the collection of small masses (each of the n
bodies, n being the total number of particles present in
the system) exert gravitational pull upon all others,
resulting in unpredictable, chaotic behavior.

First select the number of particles with the NUMBER slider.

The RANDOM-SETUP switch determines whether or not the
particles' initial velocities will sum to zero. If set to 1,
they will. Their initial positions will also be randomly
distributed across the grpahics screen.
If RANDOM-SETUP is set to 0, each particle will have a
randomly determined mass and initial velocity, and all the
particles will begin at the origin (at position 0,0).

MASS-MAX and VELOCITY-MAX determine the initial values of
each particle's mass and velocity. If ZERO-SUM? is set to 0,
each particle will have a mass equal to MASS-MAX. Otherwise,
each of the bodies will have a random mass no greater than
MASS-MAX. In any case, no particle will have a velocity
greater than VELOCITY-MAX, either initially or during the
run of the model. (This is simply for sake of the model, to
keep the forces small enough so that the particles stay on
the screen, instead of all flying off.)

The TRACE-MODE switch, when set to 1, has each turtle mark
out its position every time-tick. Thus you can see the
paths the particles mark out as they move around and
interact with each other.

After you have set the sliders to the desired levels, press
SETUP to initialize all particles.
Next, press GO to begin running the simulation. You have two
choices: you can either let it run without stopping (the GO
forever button), or you can just advance the simulation by
one time-step (the GO once-button). It may be useful to step
through the simulation moment by moment, so that you can
carefully watch the interaction of the particles.

Finally, the CLEAR button will return the background to
black, effectively clearing the screen of all traces, if
TRACE-MODE has been set on.

The most important thing to observe is the behavior of the
particles. Notice how (and to what degree) the initial
conditions influence the model.

Compare the two different modes of the model, with
RANDOM-SETUP equal to 0 and then to 1. Observe the initial
symmetry of the zero-summed system, and what happens to it.
Why do you think this is?

As each particle acts on all the others, the number of
particles present directly affects the run of the model.
Every additional body changes the center of mass of the
system. Watch what happens with 2 bodies, 3 bodies, 4
bodies, etc... How is the behavior different?

It may seem strange to think of n discrete particles
exerting small forces on one other particle, determining its
behavior. However, you can think of it as just one large
force eminating from the center of mass of the system.
Watch as the center of mass changes over time. In the main
procedure, 'go', look at the two lines of code where each
body's position (xc, yc) is established- we shift each
particle back towards the center of mass. As no other forces
are present in the model (the n-bodies represent a closed
system), our real positions are relative, defined only
in relation to the center of mass itself. Recall Newton's
third law, which states that for each internal force acting
on a particle, it exerts an equal but opposite force on
another particle. Hence the internal forces cancel out, and
we have no net force acting on the center of mass. (If
particle 1 exerts a force on particle 2, then particle 2
exerts the same force on particle 1. Run the model with just
two particles to watch this in action.)

Compare this model to the other inverse square model,
'gravitation'. With TRACE-MODE on, look at the paths made by
the two different groups of particles. What do you notice
about each group? How would you explain the types of paths
made by each model?

The force acting upon each turtle is multiplied by a constant, 'g' 
(a global variable). In classical Newtonian Mechanics, 'g'
is the universal gravitational constant, used in the
equation for determining the force of gravitational
attraction between any two bodies:
	f = ((g * (mass1 * mass2)) / (distance^2))
In real life, 'g' is difficult to calculate, but is
approximately 6.67e-11 (or 0.0000000000667). However, in our
model, the use of 'g' keeps the forces from
growing too high, so that you might better view the simulation.
Feel free to play with the value of 'g' to see how changes
to the gravitational constant affect the behavior of the
system as a whole. 'g' is defined in the 'setup' procedure.

Also, the fact that we're keeping the turtles' velocities to
at or beneath VELOCITY-MAX limits the size of the forces.
What would happen if you were to remove this limitation? Are
there any other ways to limit the presentation of the model,
without constraining the speed of the particles themselves?

Each time-step, each turtle sums over all other turtles
(twice) to determine the net acting force upon it. Thus, if
we have n turtles, each one doing 2n operations each step,
we're approximately taking what is called 'n-squared time'.
By this, we mean that the time it takes to run the model is
proportional to how many particles we're using. 'n-time',
also called linear time, means that the speed of the model
is directly proportional to how many turtles are present-
for each turtle added, there is a corresponding slow-down.
But 'n-squared time' (also quadratic time or polynomial
time) is worse- each turtle slows the model down much more.
The speed of the model, compared to linear time, is as the
total number of turtles, squared. (So a linear time model
with 100 turtles would theoretically be as fast as a
quadratic time model with just 10 turtles!)
For small values of n (very few turtles), speed isn't a
problem. However, we can see that the speed of the model
decreases quadratically (as n-squared) as the number of
turtles (n itself) increases. How could you speed this up?
(It may help you that the center of mass of the system is
already being computed each new time-step.)

As the particles all can have different initial positions,
masses, and velocities, it makes sense to think of the model
as representational of a planetary system, with suns,
moons, planets, and other astronomical bodies. Establish
different breeds for these different classes- you could give
each kind a separate shape and range of masses. See if you
could create a model of a solar system similar to ours, or
try to create a binary system (a system that orbits about
two close stars instead of one).

We determine the acting force upon each turtle by splitting
the force vector into its components. The turtle stores
these components as variables for future reference, 'fx' and
'fy'. 'fx' and 'fy' are computed via the 'sum-of-turtles
[..]' command. Usually, 'sum-of-turtles' is called only to
sum the total amounts of a single turtle variable, such as:
'sum-of-turtles [value]'. But the list given to the command
is evaluated as well, so that 'sum-of-turtles' can be given
an expression of arbitrary complexity; in the case of
'n-bodies', we compute two trigonometric functions and
perform four arithmetic operations.

Inside of the above-mentioned 'sum-of-turtles' expression,
we use the 'atan' primitive, to find the angle towards each
particle from the body we're currently summing over.
Normally, we'd just use the StarLogo primitive 'towards' or
'towards-nowrap', but as the turtles in 'n-bodies' can
effectively go off-screen but continue moving, we must write
our own version of 'towards'. When a turtle's xc or yc
exceeds the boundaries of the graphical plane, we hide it
with 'ht' (an abbreviation of 'hideturtle'). But the
turtle's real position remains on the plane at the point it
was hidden. So calculations would be wrong if we continued
to direct the force towards the turtle's 'graphical' (and
erroneous) position, compared to its 'real' position. (Note
that by 'graphical' position, we mean the value of 'xcor'; by
'real' position, we mean the value of 'xc', that is
translated into 'xcor' when the turtle is within the
boundaries of the graphics screen.)