How to Swing a Pendulum Arc

In my previous article explaining How to Draw an Arc with ActionScript a few readers asked how to simulate the swing of a pendulum or the swaying motion of a falling leaf. Hopefully this tutorial will add a little insight into that process. The technique I’ll be using won’t mimic the effects of gravity but will be more similar to the metered swing of a clock’s pendulum or a large carnival ride.

Observations
: Before we start writing any code, let’s make a few general observations. If you were to swing a pendulum from right to left, you could note the following:

  1. Once the pendulum is dropped or released, it begins to pick up speed as it approaches the bottom of its arc. This gradual acceleration is similar to “Easing In”.
  2. Once the pendulum passes the bottom of its arc, it begins to swing upward and consequently slows down which is similar to “Easing Out”.
  3. Once the pendulum reaches the top of its arc on the left, it begins to swing backwards from left to right. The swing from left to right is a mirror image of the previous swing from right to left.

Conventions: With those observations in mind we can start hammering out some conventions to simplify the writing of our Pendulum function.

  1. When the pendulum is at the bottom of its arc it can be assumed to be at an angle of 0.
  2. To swing the pendulum, we need to know how high to lift it, or if you want to get all fancy about it, we need to know its “Angle Of Inclination”. We’ll call this AOI.
  3. Once you know the AOI, you can describe the pendulum’s position as being anywhere between -1 * AOI (full left raised position) to +1 * AOI (full right raised position).
  4. There are many ways to describe angles but, because I’m a freak, I like to use ratios between 0 and 1. Zero represents no rotation while 1 represents one full rotation or 360 degrees. An angle of 90 degrees would be described as .25 or similarly 90/360

Deductions: With our observations and conventions in hand we can start visualizing what we will need to make everything “go”.

  1. To swing from right to left we need to generate values from +1 to -1.
  2. To swing from left to right we need to generate values from -1 to +1.
  3. The values generated need to be eased. More easing when near -1 or +1. Less easing when near 0.

Achieving all of the above goals may seem like a fairly daunting task until you realize that this is a problem that you solve every time you draw a circle. In my How to Draw a Circle tutorial I discussed a Magic Trig Function which just happens to be the perfect mechanism for driving the “swing” of our pendulum. Let’s take a look at this Magic function shall we? I think we shall…

//
//
function magicTrigFunction (pointRatio){
    return Math.cos(pointRatio*2*Math.PI);
}
for(var i=0; i<=22; i++){
    // Input numbers between 0 and 1.
    var ratio = i/22;
    // Output eased values between -1 an +1.
    trace(magicTrigFunction(ratio));
}
//
//

Running the above code will produce the following results:

1
0.959492973614497
0.841253532831181
0.654860733945285
0.415415013001886
0.142314838273285
-0.142314838273285
-0.415415013001886
-0.654860733945285
-0.841253532831181
-0.959492973614497
-1
-0.959492973614497
-0.841253532831181
-0.654860733945285
-0.415415013001887
-0.142314838273285
0.142314838273285
0.415415013001887
0.654860733945285
0.841253532831181
0.959492973614497
1

As you can see, the returned values go from +1 through 0 to -1 and then they reverse back through 0 to +1. That’s just what we need, and to put icing on the cake, the values are being eased the right way at the right time. Changes in values near 0 are large while changes near -1 and +1 are small. Perfect.

Arguments: Now that we understand the mechanism that will swing the pendulum, it’s time to think about the arguments we must give to our pendulum function. We’ll need a center for the pendulum to swing from, this will be noted with “centerX” and “centerY”. We’ll also need to know the distance of the pendulum form center, we’ll call this “radius”. Next we’ll need to know the maximum Angle Of Inclination (how far the pendulum swings), we’ll call this “aoi”.

The next argument we’ll need to provide is a “ratio of completion”. The position of the pendulum depends on the time it was set into motion so we must keep track of the amount of time that the pendulum has been swinging.

  • Before you release the pendulum, it has a “completion ratio” of 0.
  • After the pendulum is released, as it reaches the bottom of its swing it will have a completion ratio of .25.
  • Once the pendulum reaches its maximum height on the opposite side it will have a completion ratio of .5.
  • After reaching the opposite side, the pendulum swings back towards its starting position. As the pendulum reaches the bottom of this swing it will have a completion ratio of .75.
  • When the pendulum swings all the way back to the height of its starting position, it can be said to have a completion ratio of 1.

Measuring this change in time is what will drive the pendulum animation.

So now we can see that the pendulum function will have the following arguments:

//
//
function pendulum (centerX, centerY, radius, aoi, completionRatio){
    //Some Code.
}
//
//

Doin’ It: It has taken quite a while to get to this point, but now that we’ve done most of the mental grunt work (Observations, Conventions, Deductions, Arguments) writing the actual code will be pretty easy. You can follow along by reading the comments.

//
//
//
// Initial variables.
var pendX = 250;
var pendY = 250;
var pendRadius = 200;
var pendArc = 135/360;
var pendSpeed = .005;
var pendCount = 0;
//
//
//
// Make a red footbal-shaped clip.
createEmptyMovieClip("Pendu", 10);
with(Pendu){
    beginFill(0xFF0000);
    moveTo(-20, 0);
    curveTo(0, 15, 20, 0);
    curveTo(0, -15, -20, 0);
}
//
// Make a clip in which to draw the stick holding the pendulum.
createEmptyMovieClip("Stick", 5);
//
//
//
// Swing a point on an eased arc with the given properties.
function pendulum (centerX, centerY, radius, aoi, completionRatio){
    //
    // Use magic trig function to turn linear values between 0
    // and 1 to eased values between -1 and +1.
    var easedOneToNegOne = Math.cos(completionRatio*2*Math.PI);
    //
    // Convert "Angle Of Inclination" from a ratio between 0
    // and 1 to radians.
    var aoiRadians = aoi * 2 * Math.PI;
    //
    // Determine eased rotation of the pendulum in radians.
    // Derived from #3 in the above "Conventions" section.
    var currentRotation = easedOneToNegOne * aoiRadians;
    //
    // Get X and Y coordinates of pendulum at eased angle of rotation.
    var x = centerX + Math.sin(currentRotation) * radius;
    var y = centerY + Math.cos(currentRotation) * radius;
    //
    // Return both X and Y coordinates inside a single 'point' object.
    return {x:x, y:y};
}
//
//
//
// Advance the pendulum to its next position.
function swingPendulum (){
    //
    // Increment the clock counter.
    pendCount += pendSpeed;
    pendCount %= 1;
    //
    // Get the pendulum's new coordinates.
    var point = pendulum (pendX, pendY, pendRadius, pendArc, pendCount);
    //
    // Place the pendulum at its new coordinates.
    Pendu._x = point.x;
    Pendu._y = point.y;
    //
    // Draw a line from the center to the pendulum.
    with (Stick){
        clear();
        lineStyle(2, 0);
        moveTo(pendX, pendY);
        lineTo(point.x, point.y);
    }
}
//
// Keep Swinging the pendulum every time we enter a frame.
onEnterFrame = swingPendulum;
//
//
//
//

The above code will produce the following SWF:

And so it goes. One pendulum swinging in an arc.

6 Responses to “How to Swing a Pendulum Arc”

  1. Phil says:

    I can understand making an arc and then connecting it like a piece of pie; however, imagine a triangle. They hypotenuse of the triangle is curing inward towards the 90 degree angle instead of outward like a pie. How do you do that?

  2. mac says:

    superb articles from you!!!!!!!!11

  3. R.M.M. says:

    Excellent! Quite a genial approach. Many thanks.

  4. malarobin says:

    Super. Updated this to ActionScript 3.0 and posted it here:

    http://robin.learnnewmedia.ca/241/pend.txt

  5. brad says:

    Great entry. I am working on a grappling hook and your pendulum has some great insights like the magicTrigFunction. I like your thoughtful approach to coding.

  6. […] Update: The next tutorial in this series is How to Swing a Pendulum Arc. […]

Leave a Reply

PixelWit.com's Comment Guidelines


Warning: Undefined variable $user_ID in /home2/pixelwit/public_html/blog/wp-content/themes/fvariant2/comments.php on line 57

You must be logged in to post a comment.

© Sean O'Shell 2007-2024