# 7.7 - Timing Along A Path¶

Let’s assume you are using a parametric equation to change the position
and orientation of an object over a series of frames for an animation. The
value of the parametric parameter *t* needs to vary from 0.0 to 1.0
over the frames that contain the movement. This lesson discusses how to calculate
appropriate values for *t*.

## Speed and Acceleration¶

Speed is defined as distance divided by time. For cars we use miles/hour; for a person running, perhaps meters/second. Distance, time, and speed are interrelated using these basic formulas:

```
speed = distance / time;
distance = speed * time;
time = distance / speed;
```

When you are designing an animation you have to chose two of the three values and the third value “is what it is.” So you have 3 scenarios for designing an animation:

- You decide the distance to travel and the time of travel.
- You decide the speed of movement and the time of travel.
- You decide the distance of travel and the speed.

Option 1 is perhaps the most common and that is what we will discuss in this lesson.

For an animation you can measure *time* in *seconds* or in *frames*.
Distance can be measured using any units
that are consistent with your virtual scene. Remember that
WebGL is unit-less; you just need to use consistent units for all
measurements.

Acceleration is the change in speed over time. When you are accelerating you are increasing your speed. When you are decelerating you are decreasing your speed. In the real world you can’t instantaneously start traveling at a particular speed, nor can you stop instantaneously. Any object that starts to move must accelerate to a given speed, travel at that speed for a certain amount of time, and then decelerate until the object is stationary. This is visualized in the diagram.

We often make simplifying assumptions about motion when we create virtual worlds. Let’s consider two scenarios:

- We ignore acceleration entirely.
- We include acceleration, but model it as a linear change.

## Ignore Acceleration¶

For simple motion it is sometimes acceptable to ignore acceleration and
immediately start moving at a constant speed. For the parametric
parameter *t*, if the difference between
your values of *t* are equal, your change in locations will be a constant
distance, which means you will be moving at a constant speed. To calculate
your “change in t” for such a motion, simply calculate the number of discrete
positions an object will have during the motion. Then divide this into 1.0,
since *t* varies between 0.0 and 1.0. (Note that given *n* frames, there
are *(n-1)* transitions between frames.)

```
number_frames = ending_frame - starting_frame + 1;
dt = 1.0 / (number_frames-1);
```

Let’s walk through a specific example. In frame 100 an object is stationary
and has a location of p1 = (10, 12,-4). You want the object to move to location
p2 = (20, 8, 5) by frame 110. In frames 101 through 109 the object will be in
a location calculated by the parametric equation. Using the above equations
the values for `dt` is 0.1 and the values for *t* for each frame will be:

frame number | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 |
---|---|---|---|---|---|---|---|---|---|---|---|

dt = | 0.100 | 0.100 | 0.100 | 0.100 | 0.100 | 0.100 | 0.100 | 0.100 | 0.100 | 0.100 | |

t = | 0.000 | 0.100 | 0.200 | 0.300 | 0.400 | 0.500 | 0.600 | 0.700 | 0.800 | 0.900 | 1.000 |

start | constant speed | end |

The selection of the starting and ending frames determines the *time* for the
animation. You can convert the number of frames into seconds by dividing by
the frame rate. For example:

```
seconds = (number_frames-1) / (30 frames/ 1 sec);
```

The selection of the starting and ending points determines the distance of the motion. You could calculate the exact distance using the distance formula:

```
distance = Math.sqrt( (p2x-p1x)*(p2x-p1x) + (p2y-p1y)*(p2y-p1y) + (p2z-p1z)*(p2z-p1z));
```

If we needed the exact speed of the motion we could calculate it:

```
speed = distance / seconds;
```

## Include Acceleration¶

For more realistic motion you need to include the acceleration of the object as it starts to move and the deceleration as it slows down to stop. This adds complexity to your animation design and to your calculations.

To simplify our calculations as much as possible we consider the acceleration and deceleration
to be linear functions as shown in the diagram. There are many scenarios we could
consider, but let’s look at a straightforward one where the animation
designer decides the time it takes to accelerate and decelerate. The equations
will be developed using the simple example we used above: in frame 100 an object
is stationary and has a location of p1 = (10, 12,-4); you want the object to
move to location p2 = (20, 8, 5) by frame 110; and acceleration takes 3 frames
at the beginning of the motion and deceleration takes 2 frames at the end of
the motion. The table below lays out the scenario with the values we
need to calculate. Please note that we need to calculate the “change in *t*”
between frames in order to calculate the the actual values of *t*. We will
end up with 11 values for *t*, but 10 “change in *t*” values.

frame number | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 |
---|---|---|---|---|---|---|---|---|---|---|---|

dt = | ? | ? | ? | dt | dt | dt | dt | dt | ? | ? | |

t = | 0.000 | ? | ? | ? | ? | ? | ? | ? | ? | ? | 1.00 |

accelerating | constant speed | decelerating | |||||||||

Let’s call the “change in *t*” `dt`. If `dt` is constant,
then we have constant speed. If `dt` is increasing we have acceleration;
if `dt` is decreasing we have deceleration.
We use the slope of the acceleration and deceleration
lines to approximate the `dt` value at the start and end of the motion.
We don’t know the value for `dt` but we do know that the sum of all the
values must be 1.0. For the specific example in the diagram, we can write the
equation below. In the diagram the frames are marked with vertical red lines.
Notice that we take the value for `dt` in the middle of each frame.

```
// Adding the dt values for acceleration, constant speed, and deceleration
1.0 = 1/6*dt + 3/6*dt + 5/6*dt + dt + dt + dt + dt + dt + 3/4*dt + 1/4*dt;
```

Therefore `7.5*dt === 1.0` and `dt` must be 1/7.5, or 0.133.
Substituting this value for `dt` back into each term gives us the
specific “change in *t*” for each frame. These values are show in the following
table.

frame number | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 |
---|---|---|---|---|---|---|---|---|---|---|---|

dt = | 0.000 | 0.022 | 0.067 | 0.111 | 0.133 | 0.133 | 0.133 | 0.133 | 0.133 | 0.100 | 0.033 |

t = | 0.000 | 0.022 | 0.088 | 0.200 | 0.333 | 0.467 | 0.600 | 0.733 | 0.866 | 0.966 | 1.000 |

accelerating | constant speed | decelerating | |||||||||

Let’s make some observations about the calculated values:

- For this problem the
`dt`value is 0.133, while for the original “constant speed” problem above the`dt`value was 0.1. It makes sense that the speed during constant motion must be greater to make up for the time lost during acceleration and deceleration. - The
`dt`values are increasing during acceleration and decreasing during deceleration. Hopefully this makes sense from a physical perspective as well.

With a little work we can generalize this algorithm for any set of inputs.
The function `calculateAnimation` in the demo code below will calculate
and return an array of *t* values based on a starting frame, an ending frame,
the number of frames to accelerate, and the number of frames to decelerate.
Please study the code carefully. Then experiment with the WebGL demo program.

To investigate linear motion between two points, **P1** and **P2**:

- Manipulate the location of the two points.
- Select whether you want to include acceleration.
- Set the number of frames for the animation.
- Set the number of frames to use for acceleration and deceleration.
- Push the
**Animate**button to animate a small sphere between the**P1**and**P2**

Click the **Animate** button to move between **P1** and **P2**.

P1 (5.0, 0.0, 0.0) |
P2 (-5.0, 0.0, 0.0) |
t = 0.0 |

X: -5.0 +5.0 | X: -5.0 +5.0 | |

Y: -5.0 +5.0 | Y: -5.0 +5.0 | t: 0.0 +1.0 |

Z: -5.0 +5.0 | Z: -5.0 +5.0 |

Include acceleration and deceleration.

2 150 Number of frames: 30

0 50 Frames for acceleration: 0

0 50 Frames for deceleration: 0

## Summary¶

You can change an object’s location, orientation, and possibly other properties
by using parametric equations which use a single input, *t*, to specify
intermediate values. If we vary *t*
correctly, we can simulate acceleration, constant speed, and deceleration. There
are three major scenarios for calculating the values of *t*, based on whether
you specify distance and time, which requires calculating speed, or you specify
distance and speed, which requires calculating time, or you specify
speed and time, which requires calculating distance. In the above examples
we specified distance and time, which required that we
calculate speed (which was the `dt` values). There are many other possible
scenarios than the two we have discussed here.

## Glossary¶

- speed
- The rate of change in an object’s location and/or orientation, measured in terms of distance per change in time.
- acceleration
- The change in speed over a time interval.