Home Contents Forum Links Tip Jar
Animation Math in Lingo       

General Gravity

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 them and 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.

Move mouse over stage to start animation
Gravity - source movie - vector version

on exitframe()
  --distance components
  distX = (the mouseh) - x
  distY = (the mousev) - y

  --pythagorean theorem to get distance

  dist = sqrt(power(distX,2) + power(distY,2))
  --put a lower limit on dist
  if dist < sp.width then 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

on exitframe me
  xTotalGrav = 0
  yTotalGrav = 0
  repeat with s = 1 to totSp
    if s <> me.spritenum then
      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.

 
 


Copyright © 2003 JM Harward 
 jmckell~at~jmckell~dot~com
All lingo provided on this site may be used freely for educational purposes. Not for redistribution as uncompiled code. Instructional materials may not be reproduced without permission.