Using Trigonometry to Animate Bounces, Draw Clocks, and Point Cannons at a Target

Notice that math.sin(0) returns 0, then the return value gradually increases until math.sin(3.14 / 2) (that is, half of pi) returns 1, then it begins to decrease until math.sin(3.14) returns 0. (The number 3.14 is a special number in mathematics called pi (pronounced the same as delicious “pie”.) This value is stored in the variable pi in the math module and has the float value 3.1415926535897931.

The pattern of return values for math.cos() looks similar, it just runs a little bit behind the sine wave:

This wavey-looking pattern of return values makes math.sin() and math.cos() pretty handy for a few graphics and animation programming techniques. The core benefit is that these are functions can take a linearly changing (that is, changes at a set rate) input and give an output that oscillates between -1.0 and 1.0.

Bouncing Animation with Sine and Cosine

Our first programming example shows some simple bouncing animation (though technically not a parabola, but though not physics-precise this bounce is simple to implement):

Download the Python source code for trig_bounce.py.

Here’s the main part of the code for the blue bouncing ball’s Y position:

yPos = -1 * math.sin(step) * AMPLITUDE

 

...some other code...

 

step += 0.02

When we call the math.sin() function, we pass it step for the argument. The step variable starts at 0 and is incremented on line 65 by 0.02. So the calls to math.sin() are: math.sin(0), math.sin(0.02), math.sin(0.04), and so on.

The return value (that is, the output) is used for the Y coordinate. It is multiplied by -1 because in Pygame (and most programming languages) the Y coordinate increases going down. This is the opposite direction used in Cartesian coordinates in your math class.

The return value is also multiplied by the value in the AMPLITUDE variable, so that instead of ranging over -1.0 to 1.0, it will range between (-1.0 * AMPLITUDE) to (1.0 * AMPLITUDE). Which is to say, it ranges from -AMPLITUDE to AMPLITUDE. Since we set AMPLITUDE to 100 on line 29 of trig_bounce.py, this causes the Y coordinate to move over a range of 200 pixels (from a Y coordinate of -100 to 100). If we increase AMPLITUDE, then the ball will move over a larger range (and move faster, since it covers a larger distance in the same amount of time).

Things to note:

  • Increasing AMPLITUDE = Increasing the range that the ball moves over.
  • Increasing AMPLITUDE = Increasing the speed that the ball moves (since it moves over a larger range in the same time as before).
  • Increasing the amount step increments by = Increases the speed the ball moves.

On line 55, we pass the red ball’s math.sin() return value to abs() which makes sure any negative return value is converted to a positive number. This is what causes the red ball to “bounce” instead of oscillate like the blue ball.

Changing the Amplitude and Frequency of the Waves

You can see the return values for the math.sin() and math.cos() functions (as well as the return value of math.sin() multiplied by a large amplitude value, and the return value of math.sin() with a larger input parameter to increase the wave’s frequency) in the trig_waves.py program:

Page 2 of 5 | Previous page | Next page