The equation for general gravity governs all objects, not
just those close to the surface of the earth as is covered in surface
gravity. Near the surface of the earth certain elements of the general
equation are simplified.
Gravity acts between all objects, and its force depends
on the distance between themand on
their masses. As the separating distance increases, gravity decreases.
As their masses increase, gravity increases. Gravity pulls the objects
toward each other.
The equation for the force of gravity between two objects:
gravity = mass1 * mass2 * k
distance2
In physics k is a constant number that
is set in nature, but in animation it can be tweaked
to make gravity stronger or weaker. In nature, gravity is a relatively
very weak force so that it takes very large masses (such as planets) to
notice it.
In this demo, there is one object acting under gravity.
It is attracted to an object kept at the mouse location. Move
the mouse over the stage to start the animation.
onexitframe() --distance components
distX = (themouseh)
- x
distY = (themousev)
- y
--pythagorean theorem to get distance
dist = sqrt(power(distX,2)
+ power(distY,2)) --put a lower limit on dist if dist < sp.widththen dist = sp.width
--calculate gravity, x & y
components
grav = mass * mouseMass / power(dist,2)
* 5
xGrav = grav * (distX/dist)
yGrav = grav * (distY/dist)
--accel (with mass), velocity,
position
xAccel = xGrav / mass
yAccel = yGrav / mass
xVelo = xVelo + xAccel
yVelo = yVelo + yAccel
x = x + xVelo
y = y + yVelo
--reset object if mouse leaves
stage
checkMouseOffStage
sp.loch = x
sp.locv = y end
Only the exitframe handler is shown here. See source
movie for full script
There's alot to chew on in this script. First, distX
and distY are the horizontal and
vertical components of the distance between the two objects.
They are used to find the straight-line distance using the pythagorean
theorem.
In the next statement, dist
is given a lower limit. This is to prevent dist
from getting close to zero—look at the gravity equation
and see what happens when distance gets close to zero. The velocity would
be great enough that in one frame the object would be gone.
With the distance calculated all the pieces are ready to
plug into the gravity equation (mass and
mouseMass are constants that have been
initialized). The gravity equation gives the force of the gravity.
Calculating the Direction
To calculate the x and y components of the gravity, which
gives the force a direction, the values distX/dist and
distY/dist are used. A movement by distX/dist
in the x direction and distY/dist in the y direction
would move the object a distance of exactly 1 toward the other object.
Multiplying each of those by grav
extends this distance in proportion to the force.
Using the word 'vector' makes this easier
to discuss and understand. [distX,distY] can be considered
a vector that extends from one object to the other. Dividing both distX
and distY by the length of the vector, dist,
shortens the vector to a length of 1. This is called
'normalizing' the vector. This vector can then be multiplied
by the force of gravity to give the gravity vector, which contains the
x and y components of the force of gravity. For more on vectors, see Vectors.
After that comes the common physics model algorithm
(with mass included).
General Gravity with Multiple Objects Click to add objects, right-click to restart Gravity, multiple objects - source
movie
onexitframeme
xTotalGrav = 0
yTotalGrav = 0 repeat with s = 1tototSp ifs <>me.spritenumthen
spOther = sprite(s)
--distance
components
distX = (spOther.x)
- x
distY = (spOther.y) - y
--pythagorean theorem to get distance
dist = sqrt(power(distX,2)
+ power(distY,2))
--put a lower limit on distance
minDist = (sp.width
+ spOther.width) / 2 if
dist < minDist then
dist = minDist
--calculate
gravity, x & y components
grav = mass * spOther.mass / power(dist,2)
* .005
xGrav = grav * (distX/dist)
yGrav = grav * (distY/dist)
--add force
to total
xTotalGrav = xTotalGrav + xGrav
yTotalGrav = yTotalGrav + yGrav end if end repeat
--acceleration, velocity, position
xAccel = xTotalGrav / mass
yAccel = yTotalGrav / mass
xVelo = xVelo + xAccel
yVelo = yVelo + yAccel
x = x + xVelo
y = y + yVelo
sp.loch = x
sp.locv = y end
Only the exitframe handler is shown here. See source
movie for full script.
The only difference with multiple objects is that for each
object A, the gravity with respect to each of the other
objects is added together to get the total force on object A.
In the repeat loop, the variable xTotalGrav accumulates
all the forces, or in other words adds them one at a time to get the total.
xTotalGrav is then used to set acceleration. The effect
is the same as accel = force1 + force2 + force3 + ... etc,
but the repeat loop is a more efficient way of doing it.
Variations in Animation
The concept of gravity can be altered in many ways in
animation. You could make the force constant, regardless
of distance and mass. Or change the "gravity field" by cubing
the distance instead of squaring it, or not raising it to any
power at all. You could make the force repel the objects
away from each other with a negative sign in the gravity equation. With
a little experimentation, the equations can be customized to get a particular
effect.
Extra for philomaths:
Near the surface of the earth the acceleration caused by gravity is constant
regardless of distance and mass. There are a few things that make this
happen. The general equation:
gravity = mass1 * mass2 * k
distance2
Distance in the general equation means distance between
the centers of the objects ("center of gravity"). An object
50 feet in the air is practically the same distance from the center of
the earth as an object 5 feet in the air. The difference is negligible
for most applications, so distance can be considered a constant.
Also, one of the masses in the equation is always the same—the
mass of the earth. So this is also a constant.
These two constants can be combined with the constant k so
that the equation becomes:
gravity = mass1 * c
Where c is the combined constants. Then
using the equation
acceleration = force / mass:
acceleration = gravity / mass1 = (mass1 * c) / mass1 =
c
So acceleration near the surface of the earth becomes constant.
It is something like 9.8 meters/sec2 but of course in animation
you can do whatever you want with the numbers to get the right effect.
If you really wanted you could find out the mass of the earth, it's radius,
and the value of k (gravitational constant) and derive the 9.8 m/s2
yourself.
Some important differences are noticeable between the animation
and real-world behavior. In the real world these objects would not move
off stage—the center of gravity of the set of objects
would remain stationary. Also, in the single-object demo
the orbit of the object is not elliptical like real satellites
but rather a sort of spirograph-type path.
In order to get the animation closer to the real thing
requires more computation each step of the animation. The extra
computation would estimate the effect of gravity between frames.
The more computation, the closer the estimate.