Home Contents Forum Links Tip Jar
Animation Math in Lingo       

Circular Motion

The method of generating circular motion is directly related to the definitions of sine and cosine.

Circle center is draggable
Circular motion - source movie

property sp
property millis
property xSlider, ySlider

on beginsprite(me)
  sp = sprite(me.spritenum)
  millis = the milliseconds
  xSlider = sprite(5)
  ySlider = sprite(8)
end

on exitframe(me)
  -- drive p
  p = eTime(2000) -- two seconds
  pW = xSlider.p()
  pH = ySlider.p()

  -- no bias

  -- p drives animation
  xscale = pW * (150 - 0) + 0
  yscale = pH * (150 - 0) + 0
  centX = sprite(1).loch
  centY = sprite(1).locv
  t = p * 2 * pi

  sp.loch = cos(t) * xscale + centX
  sp.locv = -sin(t) * yscale + centY
  
  -- rotation
  st = sin(t)
  if xscale = 0 then xscale = .000001
  ct = cos(t) * yscale / xscale
  if ct = 0 then ct = .000001
  r = atan(st / ct) + pi * ((1 - ct/abs(ct)) / 2.0) - pi/2
  sp.rotation = r * 180 / pi
end

on eTime(period)
  elapsed = (the milliseconds) - millis
  return (elapsed mod period) / float(period) -- 0->1
end

To drive circular motion, p drives a value for t as described in Sine & Cosine Definitions. This is done in the same way as driving a property. In order for t to make one full revolution its range is t:0->2pi. The function to shift & scale
p:0->1 to that range is t = p * 2 * pi. Try giving t different ranges like these:

Ranges

 

Functions

t: 0 -> pi
t: pi/2 -> 3pi/2
t: 5pi/4 -> 3pi/4
t: 0 -> -pi/2

t = p * (pi - 0) + 0
t = p * (3*pi/2 - pi/2) + pi/2
t = p * (3*pi/4 - 5*pi/4) + 5*pi/4
t = p * (-pi/2 - 0) + 0

The x and y values of the object's position are given by cos(t) and sin(t), scaled to the desired size. The amount scaled by is the radius of the path. If x and y are scaled by the same amount, the path is a circle, otherwise the path is an ellipse. In this demo the ranges for the horizontal and vertical scaling is
0->150, so their functions are scale = p * (150 - 0) + 0  (using pW & pH).

Negative sin() is used because I wanted the motion on screen to match the unit circle. Otherwise, because positive y is downward on screen, the motion would be flipped vertically.

centX and centY values for the center of the circle are added to move the center to the desired location on stage. If they weren't added the object would revolve around the upper left corner of the stage, (0,0). In this demo, the center of the circle is draggable, which is the reason for setting the centX and centY variables every frame rather than setting them once in the beginsprite handler.

•What if the center of the circle itself were moved in a circular path? Try it!

Drivers
There are several new ideas in this demo relating to drivers. First, there are three of them—the position along the path is driven by time, and two sliders control the width and height of the path. Each drives a parameter, so there are three parameters as well: p, pW, and pH.

The driver functions for the sliders have been made part of the slider objects themselves. This makes for good code organization. All the logic that governs the slider is contained in the slider itself, and it provides a function p() that can be called by anything else in the program. p() returns a value p:0->1 for the position of that slider.

Bias
There is no bias used for p so that the circular motion is constant. Try using different biases and see what happens.

Animator Functions
The animator functions are written inside the exitframe handler. Try rewriting them as separate functions,

circleX(p, pW, centX)
circleY(p, pH, centY)

Sprite Rotation
Calculating the rotation for the sprite in the demo is a matter of finding the slope of the ellipse at t. The slope is the (change in sin(t) / change in cos(t)).

 
 


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.