Vector Class and Linear Motion
Projectile.png

Learning Objectives

  • Create a class that defines a vector object in Cartesian coordinates, and provides functions for retrieving as well as displaying information about the vector. Also overload operators to accomplish vector arithmetic.
  • Describe the quantities of position, velocity, acceleration, and time, and their relation to each other.
  • Recognize and utilize the correct units for position, velocity, acceleration, and time.
  • Implement the Forward Euler Method of integration to model motion.
  • Recall the advantages and disadvantages of the Forward Euler Method.

Introduction

When simulating physics in a video game environment, many of the physical quantities needed will be best represented by vectors. These can include direction, position, velocity, acceleration, forces, torques, and surface normals. All quantities you will learn about and implement in code in this course.

In this lab, you will create your own vector class called, Vector3D, and define basic methods on the class and then use it to model linear motion under acceleration. As you progress in the course, this vector class will grow in functionality.

We will use this same class whether we are working in one, two, or three dimensions by simply defaulting the value of the unused components to zero.

The Vector3D class

The Vector3D Class
Your Vector3D class should have the following functions

  • A set of constructors that can handle being passed zero, one, two, or three parameters, depending on the dimension and whether or not any values are defined. When the constructor is called with no parameters it should set default values of <0,0,0> for the vector. When called with a single Vector3D parameter, it should create a copy of the supplied Vector3D. When called with two floats, it should set the \\x\\ and \\y\\ components to the supplied values and set the z component to zero. When called with three floats, it should set the \\x\\, \\y\\, and \\z\\ components to the supplied values.
  • A function called SetRectGivenRect that will set the rectangular coordinates for the vector given an input of rectangular coordinates in both 2D and 3D.
  • A function called printRect that will display the rectangular coordinates to the screen in an easily readable fashion.
  • A function called printMag that will display the magnitude to the screen in an easily readable fashion.
  • A function called getMag that returns the magnitude of the vector.
  • A function called getMagSq that returns the magnitude of the vector squared.
  • A function called getX that returns the x-coordinate.
  • A function called getY that returns the y-coordinate.
  • A function called getZ that returns the z-coordinate.

Your vector class should store the following variables.

  • x - This will store the x-component of the vector
  • y - This will store the y-component of the vector
  • z - This will store the z-component of the vector.

You should overload operators to accomplish the following

  • Vector Addition
  • Vector Subtraction
  • Scalar Multiplication of a Vector
  • Normalization of a Vector

Resources

Linear Motion

One of the fundamental principles in any game is the motion of characters, ships, projectiles, and obstacles on the screen. Many of these motions can be very complex and dependent upon many different parameters. In this lab, we will investigate the simple motion of objects moving in a straight line subject to one acceleration function.

The velocity of a particle is the time rate of change in its position,

(1)
\begin{align} \vec {v} = {{ \Delta \vec {r} } \over { \Delta t }} \end{align}

The acceleration of a particle is the time rate of change in its velocity,

(2)
\begin{align} \vec {a} = {{ \Delta \vec {v} } \over { \Delta t }} \end{align}

Therefore, if the acceleration as a function of time is known, then the velocity and position of a particle can be determined for any time, t, since the previous two equations can be rewritten as follows:

(3)
\begin{align} \Delta \vec{r} = { \vec {v} * \Delta t} \end{align}
(4)
\begin{align} \Delta \vec {v} = { \vec {a} * \Delta t} \end{align}

These relationships are good over very short amounts of time when the change in the position or velocity are not extreme. The size of the time-step is critical to the stability of your results. If the time-step is too large, then the computed results will rapidly diverge from the true motion of the particle, and if the time-step is too small, your code will run too slowly and not be able to keep up with the pace of the game.

If the acceleration is uniform, then matters are much simpler. The position and velocity for a particle can be determined very quickly through analytic means rather than through numeric integration as above. Equations 1 and 2 can be manipulated to yield the following four equations that describe linear motion under uniform acceleration:

(5)
\begin{align} \Delta \vec {r} = { \vec {v}_i t + \left( 1/2 \right) \vec {a} t^2 } \end{align}
(6)
\begin{align} \Delta \vec {r} = { 1/2 \left( \vec {v}_f + \vec {v}_i \right) t } \end{align}
(7)
\begin{align} \vec {v}_f = { \vec {v}_i + \vec {a} t } \end{align}
(8)
\begin{align} v_{f}^2 = v_{i}^2 + 2 |a| * |\Delta r| \end{align}

In most instances, the initial velocity and accelerations will be known, so the first and third equations will be the most commonly used. Do keep in mind that these four equations are good ONLY if the acceleration is constant.
A very common case of constant accelerated motion is the motion of a falling body. Galileo had deduced, and supposedly demonstrated at the Leaning Tower of Pisa, that all objects fall with the same acceleration regardless of their mass. That acceleration is used so often in physics that it’s given its own symbol, g, where $g=9.8 m/s^2$. Equations 5 through 8, then, become very useful for accurately determining the position and speed of an object as it moves under the influence of gravity.

The Forward Euler Method is a method for evaluating the position and velocity of an object without having to evaluate equations 5 and 7 at every time step. The advantages are that it is quick to execute, easy to code, and easy to apply to non-uniform acceleration. Its biggest disadvantage is that it’s unstable and does not converge well. To determine the position of a particle first evaluate the new position by applying equation 3 in the following manner:

(9)
\begin{align} \vec{r}_{new} = \vec {r}_{old}+ \vec {v}_{old} * \Delta t \end{align}

The new velocity is found in similar fashion,

(10)
\begin{align} \vec {v}_{new} = \vec {v}_{old} + \vec {a}_{old} * \Delta t \end{align}

Notice in Equation 10 that the acceleration also has a subscript, $\vec {a}_{old}$. This allows for a non-uniform acceleration such as you would have when taking wind resistance into consideration. Equations 5-8 cannot handle a changing acceleration.

The source of the troubles with Forward Euler lies in its usage of the velocity at the beginning of the time-step as an approximation for the velocity throughout the time-step. The velocity is, of course, changing throughout the interval. The overall result is that the Forward-Euler method tends to add energy to a modeled system. Projectiles will go farther than they should, and oscillations will tend to grow over time. One way to combat this is to reduce the size of the time-step. Reducing the time-step size will have the adverse effect of slowing down your code’s execution, but it will improve the precision of your model. As a game programmer, one needs to find a good balance between speed and precision. Fortunately, a game environment doesn’t need to be as precise as a simulation. Forward Euler works well enough to make simple accelerated motion realistic and believable.

Be sure to read through the Kinematics chapter of the textbook for more details on the Forward Euler Method, including example code of how to implement it. We will look at how to implement more precise integration methods in subsequent labs.

Preparatory Thoughts

  1. Are there any computations that you will be coding that will require error trapping? Explain why or why not.
  2. How will you determine if a projectile has reached the ground?

Laboratory Procedures

1. Now that you have a Vector3D class, let's use it to model the ballistic motion of a ball.

  • Define the acceleration due to gravity as $\vec {a} = \langle 0.0f, 0.0f, -9.8f \rangle$.
  • Define the initial position as $\vec {r} = \langle 0.0f, 0.0f, 2.0f \rangle$.
  • Get the initial x-, y-, and z-components of the velocity vector from the user.
  • Get the value of the timestep (the delta time between frames) from the user.
  • Print the unit direction of the initial velocity.
  • Use the Forward Euler Method to simulate the ball's motion over time.
  • Print the position at which the ball strikes the ground and the elapsed time.
  • Print the unit direction of the displacement from the initial position to the final position.
  • Print the magnitude and magnitude squared of the displacement.

2. Execute the program for your instructor's verification.

Postlab Questions

  1. In game development, what could be the downside to using 3D vectors with $v_z=0$ to represent 2D vectors?
  2. Why use operator overloading instead of function calls to accomplish vector arithmetic?
  3. Were there any noticeable differences in the run-time when using different time-steps? If so, why would this ever be an issue?
  4. Is there any reason why you would ever select a time-step that would give you anything less than the best fit to an analytic solution?
Unless otherwise stated, the content of this page is licensed under Creative Commons Attribution-ShareAlike 3.0 License