Often we want to move an object (such as a flare) along a defined path. One way to achieve this is by using mathematical functions. In this section, we will explore the paths created by various functions that can later be used to define the motion of objects.
Excercise 3-13.
In this exercise we will write code to animate flares along paths.
  1.   Create a function called PathFunc that takes a single real argument X. Inside this function simply assign 0.5 to Result (since we're assigning 0.5 to Result what does the return type of the function have to be?). We also want to create two global variables X and XStep which are both real types. Initialize X to -14 and XStep to 0.01. During OnEnterFrame, call Flare(X, PathFunc(X), GetHue(clOrange), 255) and then increment X by XStep. Remember to call DoConvolutionFilter or nothing will happen. (Don't look at the solution for this. Each step is spelled out in order to help you practice translating words into code.)
  2.   You'll notice that the flare in the previous program moves very slowly. One way to speed it up is to increase the step size. Make the step size 0.1 to make it 10 times faster.
  3.   Although this speeds the flare up, there is the apperance of a small gap as the flare moves. This becomes worse if you make the flare move even faster (try 1 instead of 0.1). If the desired effect is continuous motion, you should take multiple steps per frame and change XStep back to 0.01. Implement this using a for loop that takes 10 steps per frame.
  4.   If the flare reaches the right hand side of the screen, make it start back at the beginning. (Hint: The right side of the screen is X = 14. The problem started with an if so that means you probably need an if statement in the code.)
  5.   First, let's change the color to lime just for practice in OnEnterFrame. Turn on the grid using GridVisible in Initialize. Now change the path the flare takes by modifying the code in PathFunc. Nothing needs to be changed in OnEnterFrame. We want the flare to take the path of the following function:
     
  6.   Increase the frequency of the sinusoid to 2 and see what happens (i.e., multiply the argument to the cos function by 2). Also decrease the frequency by half (i.e., multiply the argument to the cos function by 0.5).
  7.   We can vary the amplitude of a sinusoid by multiplying a constant outside of the function. By default the amplitude of a sinusoid is 1 (because it ranges between -1 and 1). Change the code to make the sinusoid have an amplitude of 5.
  8.   What happens when you sum two sinusoids of different frequencies? Change the path code so that it is the sum of the following:
  9.   What happens when you multiply two sinusoids of different frequencies? To really observe this effect you need to have one sinusoid that is several times slower than the other. Change the frequency of the 0.5 sinusoid to 0.125 and multiply the two sinusoids together.
  10.   Finally, in a last example of an envelope function we will use exponential decay.
      We use an amplitude of 8 because the idea behind exponential decay is that the amplitude is decaying while the frequency remains constant (thus, we have to have some large number to decay from). The -(X+14) determines the start of the decay (X = -14) and the 5 determines the rate of decay. You can experiment with different rates to see how they effect decay times. The best way to compare decay constants is to run three different functions at once (one at 2.5, one at 5, and one at 10). Do this and see what happens. Make one lime, one red, and one blue. You could also not use PathFunc and instead create a new function called DecayFunc that has arguments X and DecayConst.
So why would we ever need all these mathematical functions for animation? To begin with, wave paths can be pretty cool. But also, the motion of quite a few objects is described by sinusoids, especially decaying sinusoids.
Excercise 3-14.
  1.   Using the same code template, create something that looks like a pendulum. The top (the axis of rotation) should be a small circle and the bottom should be a larger circle. Make the top at (0,6) and the bottom at (0,-4). Also, the CircleAt and PolarToXY routines are reproduced below to make drawing easier:
    procedure CircleAt(X,Y,R : Double; Color : TColor);
    begin
      FillEllipse(X-R,Y-R,X+R,Y+R,Color);
    end;

    function PolarToXY(X,Y,Theta,Radius : Double) : TVector2D;
    begin
      Result.X := X+cos(Theta*PI/180)*Radius;
      Result.Y := Y+sin(Theta*PI/180)*Radius;
    end;
    Clear everything in OnEnterFrame so that you're starting from scratch. For now, just make the pendulum hang straight down with no motion.
  2.   Now modify your code so that the pendulum can be positioned at any Theta where Theta is the angle between the pendulum cable and the y-axis (not the x-axis so you'll need to subtract 90 degrees from any calculations made with PolarToXY). The easiest way to do this is to declare a variable V of type TVector2D and assign to it the output of PolarToXY where the starting point is (0,6) because this is the location of the axis around which the pendulum rotates, the angle is Theta-90 and the radius is 10 (because we want it to rest to (0,-4) when the angle is 0).
  3.   Now make a flare sinusoid appear behind the pendulum just like the sinusoids we made earlier. Give the sinusoid a frequency of 0.5 and an amplitude of 1.
  4.   A pendulum exhibits what is known as simple harmonic motion. This means that the angle it makes with the y-axis evolves over time as a sinusoid. Thus, we can animate the pendulum using PathFunc. Make the pendulum oscillate between -20 and 20 degrees using path func. Hint: You can solve this problem by thinking in two steps: (1) What variable should be assigned to in order for the pendulum to move and (2) PathFunc as it is written oscillates between -1 and 1 so how do we change its amplitude (you don't have to modify the code in PathFunc to do this)?
  5.   Pendulum's obviously don't swing forever. Their oscillations decay due to friction. Make the motion decay using functions we have already defined.