Throughout this book we are going to explore the mathematical concepts required to detect and react to intersections in a 3D environment. In order to achieve robust collision detection and build realistic reactions, we will need a strong understanding of the math required. The most important mathematical concepts in physics are **Vectors** and **Matrices**.

Physics and collisions rely heavily on **Linear Algebra**. The math involved may sound complicated at first, but it can be broken down into simple steps. The recipes in this chapter will explain the properties of vectors using math formulas. Each recipe will also contain a visual guide. Every formula will also have an accompanying code sample.

### Note

This chapter does not assume you have any advanced math knowledge. I try to cover everything needed to understand the formulas presented. If you find yourself falling behind, Khan Academy covers the basic concepts of linear algebra at: www.khanacademy.org/math/linear-algebra.

A vector is an *n-tuple *of real numbers. A **tuple** is a finite ordered list of elements. An **n-tuple** is an ordered list of elements which has n dimensions. In the context of games *n* is usually 2, 3, or 4. An *n-dimensional* vector is represented as follows:

The subscript numbers are called the components of the vector. Components are expressed as a number or as a letter corresponding to the axis that component represents. Subscripts are indexed starting with *0*. For example, is the same as . Axis *x*, *y*, *z*, and *w* correspond to the numbers *0*, *1*, *2*, and *3*, respectively.

Vectors are written as a capital bold letter with or without an arrow above it. and *V* are both valid symbols for vector V. Throughout this book we are going to be using the arrow notation.

A vector does not have a position; it has a magnitude and a direction. The components of a vector measure **signed displacement**. In a two-dimensional vector for example, the first component represents displacement on the *X axis*, while the second number represents displacement on the *Y axis*.

Visually, a vector is drawn as a displacement arrow. The two dimensional vector would be drawn as an arrow pointing to 3 units on the *X axis* and 2 units on the *Y axis*.

A vector consists of a **direction** and a **magnitude**. The direction is where the vector points and the magnitude is how far along that direction the vector is pointing. You can think of a vector as a series of instructions. For example, take three steps right and two steps up. Because a vector does not have a set position, where it is drawn does not matter as shown in the following diagram:

The preceding figure shows several vectors, with vector (3,2) appearing multiple times. The origin of a vector could be anywhere; the coordinate system of the preceding figure was omitted to emphasize this.

Video games commonly use two, three, and four-dimensional vectors. In this recipe, we are going to define C++ structures for two and three-dimensional vectors. These structures will expose each component of the vector by the name of an axis, as well as a numeric index.

Follow these steps to start implementing a math library with vector support:

Create a new C++ header file; call this file

`vectors.h`

; add standard C-style header guards to the file:#ifndef _H_MATH_VECTORS_ #define _H_MATH_VECTORS_ // Structure definitions // Method declarations #endif

Replace the

`// Structure definitions`

comment with the definition of a two-dimensional vector:typedef struct vec2 { union { struct { float x; float y; }; float asArray[2]; }; float& operator[](int i) { return asArray[i]; } } vec2;

After the definition of

`vec2`

, add the definition for a three-dimensional vector:typedef struct vec3 { union { struct { float x; float y; float z; }; float asArray[3]; }; float& operator[](int i) { return asArray[i]; } } vec3;

We have created two new structures, `vec2`

and `vec3`

. These structures represent two and three-dimensional vectors, respectively. The structures are similar because with every new dimension the vector just adds a new component.

Inside the vector structures we declare an anonymous union. This anonymous union allows us to access the components of the vector by name or as an index into an array of floats. Additionally, we overloaded the indexing operator for each structure. This will allow us to index the vectors directly.

With the access patterns we implemented, the components of a vector can be accessed in the following manner:

vec3 right = {1.0f, 0.0f, 0.0f}; std::cout<< "Component 0: " <<right.x<< "\n"; std::cout<< "Component 0: " <<right.asArray[0] << "\n"; std::cout<< "Component 0: " <<right[0] << "\n";

Games often use a four-dimensional vector, which adds a *W* component. However, this *W* component is not always treated as an axis. The *W* component is often used simply to store the result of a perspective divide, or to differentiate a vector from a point.

A vector can represent a point in space or a direction and a magnitude. A three-dimensional vector has no context; there is no way to tell from the x, y, and z components if the vector is supposed to be a point in space or a direction and a magnitude. In the context of games, this is what the W component of a four-dimensional vector is used for.

If the W component is 0, the vector is a direction and a magnitude. If the W component is anything else, usually 1, the vector is a point in space. This distinction seems arbitrary right now; it has to do with matrix transformations, which will be covered in Chapter 3, *Matrix Transformations*.

We did not implement a four-dimensional vector because we will not need it. Our matrix class will implement explicit functions for multiplying points and vectors. We will revisit this topic in Chapter 3, *Matrix Transformations*.

Given two vectors, there are several component-wise operations we can perform. These operations will operate on each component of the vector and yield a new vector.

You can **add two vectors** component wise. Given two n-dimensional vectors and , addition is defined as follows:

You can also **subtract two vectors** component wise. Given two n-dimensional vectors and , subtraction is defined as follows:

**Multiplying two vectors **can also be done component wise. There are other ways to multiply two vectors; the dot product or cross product. Both of these alternate methods will be covered later in this chapter. Given two n-dimensional vectors and , multiplication is defined as follows:

In addition to multiplying two vectors, you can also **multiply a vector by a scalar**. In this context, a scalar is any real number. Given vector and scalar *S, *scalar multiplication is defined as follows:

Finally, we can check for **vector equality** by comparing each component of the vectors being tested. Two vectors are the same only if all of their components are equal.

We're going to implement all of the preceding component-wise operations by overloading the appropriate C++ operators. All of the operators presented in this section can be overloaded in C# as well. In languages that do not support operator overloading, you will have to make these into regular functions.

Follow these steps to override common operators for the vector class. This will make working with vectors feel more intuitive:

In

`vectors.h`

, add the following function declarations:vec2 operator+(const vec2& l, const vec2& r); vec3 operator+(const vec3& l, const vec3& r); vec2 operator-(const vec2& l, const vec2& r); vec3 operator-(const vec3& l, const vec3& r); vec2 operator*(const vec2& l, const vec2& r); vec3 operator*(const vec3& l, const vec3& r); vec2 operator*(const vec2& l, float r); vec3 operator*(const vec3& l, float r); bool operator==(const vec2& l, const vec2& r); bool operator==(const vec3& l, const vec3& r); bool operator!=(const vec2& l, const vec2& r); bool operator!=(const vec3& l, const vec3& r);

Create a new C++ source file,

`vectors.cpp`

. Include the following headers in the new file:#include "vectors.h" #include <cmath> #include <cfloat>

Add a macro for comparing floating point numbers to

`vectors.cpp`

:#define CMP(x, y) \ (fabsf((x)â€“(y)) <= FLT_EPSILON * \ fmaxf(1.0f, \ fmaxf(fabsf(x), fabsf(y))) \ )

Add the implementation of vector addition to the

`vectors.cpp`

file:vec2 operator+(const vec2& l, const vec2& r) { return { l.x + r.x, l.y + r.y }; } vec3 operator+(const vec3& l, const vec3& r) { return { l.x + r.x, l.y + r.y, l.z + r.z }; }

Add the implementation of vector subtraction to the

`vectors.cpp`

file:vec2 operator-(const vec2& l, const vec2& r) { return { l.x - r.x, l.y - r.y }; } vec3 operator-(const vec3& l, const vec3& r) { return { l.x - r.x, l.y - r.y, l.z - r.z }; }

Add the implementation for vector multiplication to the

`vectors.cpp`

file:vec2 operator*(const vec2& l, const vec2& r) { return { l.x * r.x, l.y * r.y }; } vec3 operator*(const vec3& l, const vec3& r) { return { l.x * r.x, l.y * r.y, l.z * r.z }; }

Add the implementation for scalar multiplication to the

`vectors.cpp`

file:vec2 operator*(const vec2& l, float r) { return { l.x * r, l.y * r }; } vec3 operator*(const vec3& l, float r) { return { l.x * r, l.y * r, l.z * r }; }

Finally, add the implementation for vector equality to the

`vectors.cpp`

file. This is where the compare macro we created in step 3 comes in:bool operator==(const vec2& l, const vec2& r) { return CMP(l.x, r.x) && CMP(l.y, r.y); } bool operator==(const vec3& l, const vec3& r) { return CMP(l.x, r.x) && CMP(l.y, r.y) && CMP(l.z, r.z); } bool operator!=(const vec2& l, const vec2& r) { return !(l == r); } bool operator!=(const vec3& l, const vec3& r) { return !(l == r); }

What these components-wise operations are doing might not be obvious from the definitions and code provided alone. Let's explore the component-wise operations of vectors visually.

Every vector describes a series of displacements. For example, the vector *(2, 3)* means move two units in the positive X direction and three units in the positive Y direction. We add vectors by following the series of displacements that each vector represents. To visualize this, given vectors and , draw them so the head of touches the tail of The result of the addition is a new vector spanning from the tail of to the head of :

Subtraction works the same way as addition. We have to follow the negative displacement of vector starting from vector . To visually subtract vectors and , draw and with their tails touching. The result of the subtraction is a vector spanning from the head of to the head of :

A more intuitive way to visualize subtraction might be to think of it as adding negative to, like so; . If we represent the subtraction like this, visually we can follow the rules of addition:

In the above image, the vector appears multiple times. This is to emphasize that the position of a vector does not matter. Both of the vectors above represent the same displacement!

Multiplying a vector by a scalar will scale the vector. This is easy to see when we visualize the result of a multiplication. The scalar multiplication of a vector will result in a uniform scale, where all components of the vector are scaled by the same amount. Multiplying two vectors on the other hand results in a non-uniform scale. This just means that each component of the vector is scaled by the corresponding component of the other vector:

Comparing vectors is a component-wise operation. If every component of each vector is the same, the vectors are equal. However, due to floating point error we can't compare floats directly. Instead, we must do an epsilon comparison. Epsilon tests commonly fall in one of two categories: **absolute tolerance** and **relative tolerance**:

#define ABSOLUTE(x, y) (fabsf((x)â€“(y)) <= FLT_EPSILON) #define RELATIVE(x, y) \ (fabsf((x) â€“ (y)) <= FLT_EPSILON * Max(fabsf(x), fabsf(y)))

The absolute tolerance test fails when the numbers being compared are large. The relative tolerance test fails when the numbers being compared are small. Because of this, we implemented a tolerance test with the `CMP`

macro that combines the two. The logic behind the `CMP`

macro is described by Christer Ericson at www.realtimecollisiondetection.net/pubs/Tolerances.

It's desirable to make vectors easy to construct in code. We can achieve this by adding default constructors. Each vector should have two constructors: one that takes no arguments and one that takes a float for each component of the vector. We do not need a copy constructor or assignment operator as the `vec2`

and `vec3`

structures do not contain any dynamic memory or complex data. The pair of constructors for the `vec2`

structure will look like this:

vec2() : x(0.0f), y(0.0f) { } vec2(float _x, float _y) : x(_x), y(_y) { }

The `vec3 `

constructors will look similar, it adds an additional component. The constructors for the `vec3`

structure will look like this:

vec3() : x(0.0f), y(0.0f), z(0.0f) { } vec3(float _x, float _y, float _z) : x(_x), y(_y), z(_z) { }

The **dot product**, sometimes referred to as **scalar product** or **inner product** between two vectors, returns a scalar value. It's written as a dot between two vectors, . The formula for the dot product is defined as follows:

The sigma symbol means sum (add) everything up that follows. The number on top of the sigma is the upper limit; the variable on the bottom is the lower limit. If *n* and *i* is 0, the subscripts 0, 1, and 2 are processed. Without using the sigma symbol, the preceding equation would look like this:

The resulting scalar represents the directional relation of the vectors. That is, represents how much is pointing in the direction of . Using the dot product we can tell if two vectors are pointing in the same direction or not following these rules:

If the dot product is

**positive**, the vectors are pointing in the**same direction**If the dot product is

**negative**, the vectors point in**opposing directions**If the dot product is

**0**, the vectors are**perpendicular**

Follow these steps to implement the dot product for two and three dimensional vectors:

Add the declaration for the dot product to

`vectors.h`

:float Dot(const vec2& l, const vec2& r); float Dot(const vec3& l, const vec3& r);

Add the implementation for the dot product to

`vector.cpp`

:float Dot(const vec2& l, const vec2& r) { return l.x * r.x + l.y * r.y; } float Dot(const vec3& l, const vec3& r) { return l.x * r.x + l.y * r.y + l.z * r.z; }

Given the formula and the code for the dot product, let's see an example of what we could use it for. Assume we have a spaceship **S**. We know its forward vector, and a vector that points to its right, :

We also have an enemy ship **E**, and a vector that points from our ship **S** to the enemy ship **E**, vector :

How can we tell if the the ship **S** needs to turn left or right to face the enemy ship **E**?

We need to take the dot product of and . If the result of the dot product is positive, the ship needs to turn right. If the result of the dot product is negative, the ship needs to turn to the left. If the result of the dot product is 0, the ship does not need to turn.

Our definition of the dot product is fairly abstract. We know that the dot product gives us some information as to the angle between the two vectors, and . We can use the dot product to find the exact angle between these two vectors. The key to this is an alternate definition of the dot product.

Given the vectors and , the geometric definition of the dot product is the length of multiplied by the length of multiplied by the cosine of the angle between them:

The **||** operator in the above equation means length and will be covered in the next section. We will cover the geometric definition and other properties of the dot product later in this chapter.

The **magnitude** or **length** of a vector is written as the letter of the vector surrounded by two bars, . The magnitude of a vector is the square root of the dot product of the vector with itself:

In addition to implementing the magnitude function, we're also going to implement a magnitude squared function. The formula is the same, but it avoids the expensive square root operation:

In games we often compare the magnitude of a vector to known numbers; however, doing a comparison between a number and the magnitude is expensive because of the square root operation. A simple solution to this problem is to square the number, and then compare against square magnitude. This means, instead of the following:

if (Magnitude(someVector) < 5.0f) {

We could instead write the following:

if (MagnitudeSq(someVector) < 5.0f * 5.0f) {

We'd then get the same result, avoiding the expensive square root operation.

To find the magnitude of a vector, take the square root of the vector's dot product with its-self. The square root operation is a relatively expensive one that should be avoided whenever possible. For this reason, we are also going to implement a function to find the square magnitude of a vector.

Follow these steps to implement a function for finding the length and squared length of two and three dimensional vectors.

Add the declaration for magnitude and magnitude squared to

`vectors.h`

:float Magnitude(const vec2& v); float Magnitude(const vec3& v); float MagnitudeSq(const vec2& v); float MagnitudeSq(const vec3& v);

Add the implementation for these functions to

`vectors.cpp`

:float Magnitude(const vec2& v) { return sqrtf(Dot(v, v)); } float Magnitude(const vec3& v) { return sqrtf(Dot(v, v)); } float MagnitudeSq(const vec2& v) { return Dot(v, v); } float MagnitudeSq(const vec3& v) { return Dot(v, v); }

We can derive the equation for the magnitude of a vector from the geometric definition of the dot product that we briefly looked at in the last section:

Because we are taking the dot product of the vector with itself, we know the test vectors point in the same direction; they are **co-directional**. Because the vectors being tested are co-directional, the angle between them is 0. The cosine of 0 is 1, meaning the part of the equation can be eliminated, leaving us with the following:

If both the test vectors are the same (which in our case they are) the equation can be written using only :

We can rewrite the preceding equation, taking the square root of both sides to find the length of vector :

The magnitude of a vector can be used to find the **distance** between two points. Assuming we have points and , we can find a vector () that connects them by subtracting from , as shown in the following diagram:

The distance between the two points is the length of . This could be expressed in code as follows:

float Distance(const vec3& p1, const vec3& p2) { vec3 t = p1 - p2; return Magnitude(t); }

A vector with a magnitude of 1 is a **normal vector**, sometimes called a **unit vector**. Whenever a vector has a length of 1, we can say that it has **unit length**. A normal vector is written as the letter of the vector with a caret symbol on top instead of an arrow, . We can normalize any vector by dividing each of its components by the length of the vector:

We never implemented division operators for the vector class. We can rewrite the preceding equation as reciprocal multiplication. This means we can obtain the normal of a vector if we multiply that vector by the inverse of its length:

We are going to implement two functions, `Normalize`

and `Normalized`

. The first function will change the input vector to have a length of 1. The second function will not change the input vector; rather it will return a new vector with a length of 1.

Follow these steps to implement functions which will make a vector unit length or return a unit length vector. These steps utilize reciprocal multiplication.

Declare the

`Normalize`

and`Normalized`

functions in`vectors.h`

:void Normalize(vec2& v); void Normalize(vec3& v); vec2 Normalized(const vec2& v); vec3 Normalized(const vec3& v);

Add the implementation of these functions to

`vectors.cpp`

:void Normalize(vec2& v) { v = v * (1.0f / Magnitude(v)); } void Normalize(vec3& v) { v = v * (1.0f / Magnitude(v)); } vec2 Normalized(const vec2& v) { return v * (1.0f / Magnitude(v)); } vec3 Normalized(const vec3& v) { return v * (1.0f / Magnitude(v)); }

Normalizing works by scaling the vector by the inverse of its length. This scale makes the vector have unit length, which is a length of 1. Unit vectors are special as any number multiplied by 1 stays the same number. This makes unit vectors ideal for representing a direction. If a direction has unit length, scaling it by some velocity becomes trivial.

The **cross product** is written as a X between two vectors, . It returns a new vector that is perpendicular to both vectors and . That is, the result of the cross product points 90 degrees from both vectors.

The cross product is defined only for three-dimensional vectors. This is because any two non-parallel vectors form a plane, and there will always exist a line perpendicular to that plane. As such, we will only be implementing the cross product for the `vec3`

structure.

The equation of the cross product is as follows:

The formula behind the cross product seems large and complicated. We're going to implement a pattern in code that hopefully will make remembering this formula easy.

The cross product is only well defined for three dimensional vectors. Follow these steps to implement the cross product in an intuitive way:

Add the declaration for the cross product to

`vectors.h`

:vec3 Cross(const vec3& l, const vec3& r);

Start the implementation in

`vectors.cpp`

:vec3 Cross(const vec3& l, const vec3& r) { vec3 result; // We will add more code here return resut; }

Start by listing out the

`x`

,`y`

, and`z`

components of the result in a column:vec3 Cross(const vec3& l, const vec3& r) { vec3 result; result.x = /* Will finish in step 6 */ result.y = /* Will finish in step 6 */ result.z = /* Will finish in step 6 */ return resut; }

Flesh out the first row by multiplying

`l.y`

and`r.z`

. Notice how the first column contains`x`

,`y`

, and`z`

components in order and so does the first row:vec3 Cross(const vec3& l, const vec3& r) { vec3 result; result.x = l.y * r.z /* Will finish in step 6 */ result.y = /* Will finish in step 6 */ result.z = /* Will finish in step 6 */ return resut; }

Follow the

`x`

,`y`

,`z`

pattern for the rest of the rows. Start each row with the appropriate letter following the letter of the first column:vec3 Cross(const vec3& l, const vec3& r) { vec3 result; result.x = l.y * r.z /* Will finish in step 6 */ result.y = l.z * r.x /* Will finish in step 6 */ result.z = l.x * r.y /* Will finish in step 6 */ return resut; }

Finally, complete the function by subtracting the mirror components of the multiplication from each row:

vec3 Cross(const vec3& l, const vec3& r) { vec3 result; result.x = l.y * r.z - l.z * r.y; result.y = l.z * r.x - l.x * r.z; result.z = l.x * r.y - l.y * r.x; return resut; // Done }

We're going to explore the cross product using three normal vectors that we know to be perpendicular. Let vector , , and represents the basis of , three-dimensional space. This means we define the vectors as follows:

- points right; it is of unit length on the
*x axis*: - points up; it is of unit length on the
*y axis*: - points forward; it is of unit length on the
*z axis*:

Each of these vectors are orthogonal to each other, meaning they are 90 degrees apart. This makes all of the following statements about the cross product true:

- Right X Up = Forward,
- Up X Forward = Right,
- Forward X Right = Up,

The cross product is not cumulative, is not the same as . Let's see what happens if we flip the operands of the preceding formulas:

- Up X Right = Backward,
- Forward X Up = Left,
- Right X Forward = Down,

Matrices will be covered in the next chapter, if this section is confusing, I suggest re-reading it after the next chapter. One way to evaluate the cross product is to construct a 3x3 matrix. The top row of the matrix consists of vector , , and . The next row comprises the components of the vector on the left side of the cross product, and the final row comprises the components of the vector on the right side of the cross product. We can then find the cross product by evaluating the pseudo-determinant of the matrix:

We will discuss matrices and determinants in detail in Chapter 2, *Matrices*. For now, the preceding determinant evaluates to the following:

The result of is a scalar, which is then multiplied by the vector. Because the vector was a unit vector on the x axis, whatever the scalar is will be in the x axis of the resulting vector. Similarly, whatever is multiplied by will only have a value on the y axis and whatever is multiplied by will only have a value on the z axis. The preceding determinant simplifies to the following:

We have had a brief introduction to the angle between vectors when we discussed the dot product and the magnitude of a vector. In this recipe, we will discuss how to find the actual angle between two vectors. The formula to find angle theta between two vectors is:

We have already implemented both the dot product and magnitude functions for vectors; this means we have everything needed to find the angle between two vectors already written. In general, this is a very expensive function, as it performs two square roots and an inverse cosine. Because it's such an expensive function, we try to avoid it whenever possible.

We can save a little bit of performance if, instead of multiplying the length of both vectors, we multiply the squared length of the vectors and then do just one square root operation on the result.

Add the declaration of the angle function to

`vectors.h`

:float Angle(const vec2& l, const vec2& r); float Angle(const vec3& l, const vec3& r);

Provide the implementation of the angle function in

`vectors.cpp`

:float Angle(const vec2& l, const vec2& r) { float m = sqrtf(MagnitudeSq(l) * MagnitudeSq(r)); return acos(Dot(l, r) / m); } float Angle(const vec3& l, const vec3& r) { float m = sqrtf(MagnitudeSq(l) * MagnitudeSq(r)); return acos(Dot(l, r) / m); }

This formula relies on the geometric definition of the dot product:

This formula states that the dot product of two vectors is the cosine of the angle between them multiplied by both of their lengths. We can rewrite this formula with the cosine being isolated if we divide both sides by the product of the lengths of and :

We can now use the inverse of cosine, the arc cosine (*acos*), to find the angle theta:

The `acos`

function we used to find the angle between vectors comes from the standard C math library. This implementation of `acos`

returns radians, not degrees. It's much more intuitive to think of angles in terms of degrees than radians.

Add the following macros to the top of the `vectors.h`

header file:

#define RAD2DEG(x) ((x) * 57.295754f) #define DEG2RAD(x) ((x) * 0.0174533f)

Using these macros you can convert between radians and degrees. For example, if you wanted to get the angle in degrees between vectors and , you could use the following code:

float degrees = RAD2DEG(Angle(A, B));

If you are interested in the math used to derive these numbers, I suggest watching the following *Khan Academy* video:

Sometimes it's useful to decompose a vector into parallel and perpendicular components with respect to another vector. Projecting onto will give us the length of in the direction of . This projection decomposes into its parallel component with respect to . Once we know the parallel component of , we can use it to get the perpendicular component. The formula for projecting onto is as follows:

The perpendicular component of with respect to is defined as follows:

Implementing the projection is fairly straightforward as we already have both the dot product and magnitude squared defined. In the following function, the vector being projected is represented by the variable `length`

, and the vector it is being projected onto is represented by the variable `direction`

. If we compare it to the preceding formula, `length`

is , and `direction`

is .

Follow these steps to implement projection functions for two and three dimensional vectors. A function to get the perpendicular component of the projection is also described:

Declare the projection and perpendicular functions in

`vectors.h`

:vec2 Project(const vec2& length, const vec2& direction); vec3 Project(const vec3& length, const vec3& direction); vec2 Perpendicular(const vec2& len, const vec2& dir); vec3 Perpendicular(const vec3& len, const vec3& dir);

Add the implementation of projection to

`vectors.cpp`

:vec2 Project(const vec2& length, const vec2& direction) { float dot = Dot(length, direction); float magSq = MagnitudeSq(direction); return direction * (dot / magSq); } vec3 Project(const vec3& length, const vec3& direction) { float dot = Dot(length, direction); float magSq = MagnitudeSq(direction); return direction * (dot / magSq); }

Add the implementation of perpendicular to

`vectors.cpp`

:vec2 Perpendicular(const vec2& len, const vec2& dir) { return len - Project(len, dir); } vec3 Perpendicular(const vec3& len, const vec3& dir) { return len - Project(len, dir); }

Let's explore how projection works. Say we want to project onto , to find . Having a *'* character next to a vector means prime; it's a transformed version of the vector; is pronounced **A-Prime**:

From the preceding figure we see that can be found by subtracting some unknown vector from . This unknown vector is the perpendicular component of with respect to , let's call it :

We can get the perpendicular component by subtracting the projection of onto from. The projection at this point is still unknown, that's what we are trying to find:

Because points in the same direction as , we can express as scaling by some unknown scalar *s*, . Knowing this, the problem becomes, how do we find *s*?:

The dot product of two perpendicular vectors is 0. Because of this, the dot product of and is going to be 0:

Substitute the value of with the equation we use to find its value, :

Finally, let's substitute with the equation we use to find its value, :

Now the only unknown in the formula is *s*, let's try to find it. The dot product exhibits the distributive property, let's distribute :

Let's start to isolate *s*, first we add to both sides of the equation:

Now we can isolate *s* if we divide both sides of the equation by . Remember, the dot product of a vector with itself yields the square magnitude of that vector:

Now we can solve by substituting *s* with the preceding formula. The final equation becomes:

One of the most important concepts in physics for games is collision response and how to react to a collision occurring. More often than not this involves one of the colliding objects bouncing off the other one. We can achieve the bounding through vector reflection. Reflection is also heavily used in many areas of game development, such as graphics programming, to find the color intensity of a fragment.

Given vector and normal , we want to find a vector that is reflected around :

The reflected vector can be found with the following formula:

Keep in mind, in the preceding equation, is a unit length vector. This means that the part of the equation actually projects onto . If was a non-normalized vector, the preceding equation would be written as follows:

Implementing the preceding formula is going to look a little different, this is because we only overloaded the vector scalar multiplication with the scalar being on the right side of the equation. We're going to implement the function assuming is already normalized.

Follow these steps to implement a function which will reflect both two and three dimensional vectors.

Add the declaration of the reflection function to

`vectors.h`

:vec2 Reflection(const vec2& vec, const vec2& normal); vec3 Reflection(const vec3& vec, const vec3& normal);

Add the implementation of the reflection function to

`vectors.cpp`

:vec2 Reflection(const vec2& vec,const vec2& normal) { float d = Dot(vec, normal); return sourceVector - normal * (d * 2.0f ); } vec3 Reflection(const vec3& vec, const vec3& normal) { float d = Dot(vec, normal); return sourceVector - normal * (d * 2.0f); }

Given and , we're going to find , which is the reflection of around :

First, we project onto , this operation will yield a vector along that has the length of :

We want to find the reflected vector . The following figure shows in two places, remember it doesn't matter where you draw a vector as long as its components are the same:

Looking at the preceding figure, we can tell that subtracting from will result in :