Know Your Math: Vectors

The following is a non-exhaustive summary of mathematical vectors. It is intended as a quick reference guide.

Table of Contents

Section Contents
Basics Points vs Vectors
Unary operators Magnitude
Normalization
Binary operators: Vector-Scalar Scalar Multiplication
Binary operators: Vector-Vector Addition
Dot Product
Cross Product
Practical Uses Are two vectors orthogonal?
Are two vectors parallel?
Vector projection
Calculate normal of a triangle
Check if an entity is behind another entity
Are two entities facing each other?

Basics

A vector –also known as Euclidean vector– is a geometric object that has a magnitude (i.e. length) and direction. They are described as being \( N \)-th dimensional, where \( N \) ends up representing the number of elements in it.

\[ \vec{v} = (v_1, \ldots, v_n) \]

Vectors on a plane are two-dimensional (2D) and vectors in our world are three-dimensional (3D).

Vectors that have a magnitude of 1 are called unit vectors. They are useful since they represent pure directions; their magnitude becomes irrelevant.

Multiple vectors are described as coplanar if they are parallel to the same plane. A normal of such plane is the result of the cross product of two coplanar vectors on the plane.

Points vs Vectors

It is very common1 to mistake or use both terms interchangeably.

Despite sharing some similarities, a Point represents a position in a coordinate system. It contains no direction (at least not in the same way as a vector would).

On the other hand, a Vector represents a displacement in a coordinate system.

Some of their defined operations are:

Adding a vector to a point returns a new point: \( P + \vec{v} = P' \)

Adding two vectors returns a new vector: \( \vec{v} + \vec{u} = \vec{w} \)

Subtracting two points returns a vector: \( P - Q = \overrightarrow{QP} \)


Unary Operators

Magnitude

Each vector has a direction (a unit vector) and a magnitude (a scalar). The magnitude is denoted as \( \|\vec{v}\| \) and represents the length of the vector \( \vec{v} \).

\[ \|\vec{v}\|  = \sqrt{ \sum_{i=1}^n{v_i^2}} = \sqrt{ v_1^2 + \ldots + v_n^2}\]

Normalization

The process of calculating the unit vector (direction) out of a vector is called Normalization.

It's denoted as \( \hat{v}\) and calculated by dividing the vector \( \vec{v} \) by its magnitude \( \|\vec{v}\| \).

\[ \hat{v} = \frac{\vec{v}}{\|\vec{v}\|} \]

Binary operators: Vector-Scalar

Scalar Multiplication

Multiplying a vector and a scalar (i.e. a number) has the effect of changing the vector's magnitude. That is, multiplying a vector \( \vec{v} \) by a scalar \( 2 \), results in a vector \( \vec{v'}\) that is twice as long as \( \vec{v} \).

For that, each component of the vector is multiplied individually:

\[ \vec{v} * s = (v_1 * s, \ldots, v_n * s) \]

Binary operators: Vector-Vector

Addition

Given two vectors of the same dimensions (i.e. number of elements), their sum results in a new vector:

\[ \vec{v} + \vec{w} = (v_1 + w_1, \ldots, v_n + w_n) \]

The sum of vectors is commutative.

Dot Product

Also known as Scalar Product, since the result is a scalar.

\[ \vec{a} \cdot \vec{b} = \sum_{i=1}^n {a_i b_i} \]

This value can be interpreted differently depending on the vectors being used.

For two normalized vectors, it can be read as how similar their directions are. A -1 means they are total opposites, while a 1 means they are alike.

On the other hand, the dot product of a non-normalized and a normalized vector results in how much of the non-normalized vector goes towards the same direction as the normalized vector.

The dot product is commutative.

It's interesting to note that the magnitude of \( \vec{v} \) is essentially: \( \|\vec{v}\| = \sqrt{\vec{v} \cdot \vec{v}}\)

Cross Product

Assuming we have 3D vectors, one of the possible cross products can be calculate as such:

\[ \vec{a} \times \vec{b} = (a_y b_z - a_z b_y, a_z  b_x - a_x b_z, a_x b_y - a_y b_x) \]

The cross product is non-commutative.

In fact, changing the order of the factors to \( \vec{b} \times \vec{a} \) will result in a vector that is still perpendicular to both \( a \) and \( b \) but opposite in direction to \( \vec{a} \times \vec{b} \).

\[ (\vec{a} \times \vec{b}) \cdot (\vec{b} \times \vec{a}) = -1  \]


Practical uses

Are two vectors orthogonal?

Two vectors are orthogonal, if and only if: \( \vec{a} \cdot \vec{b} = 0 \)

Are two vectors parallel?

Two vectors (with magnitudes different than zero) are parallel, if and only if the magnitude of their cross product is zero: \( \|\vec{a} \times \vec{b}\| = 0 \).

Vector projection

Given two non-normalized vectors, \( \vec{u} \) and \( \vec{v} \), the projection of \( \vec{u} \) over \( \vec{v} \) is a new vector, \( \vec{u'} \), that can be thought of as the shadow cast by \( \vec{u} \) over \( \vec{v} \).

\[ \vec{u'} = proj_{\vec{v}}\vec{u} = \frac{\vec{u} \cdot \vec{v}}{\|\vec{v}\|^2}\vec{v} \]

This formula can be more easily understood when refactored like this:

\[ proj_{\vec{v}}\vec{u} = \left(\textcolor{blue}{\frac{\vec{u} \cdot \vec{v}}{\|\vec{v}\|}} \right)\textcolor{red}{\frac{\vec{v}}{\|\vec{v}\|}}\]

Where, \( \textcolor{blue}{\textcolor{blue}{\frac{\vec{u} \cdot \vec{v}}{\|\vec{v}\|}}} \) represents the magnitude of the projected vector and \( \textcolor{red}{\frac{\vec{v}}{\|\vec{v}\|}} \) is a unit vector with the same direction as \( \vec{v} \).

Calculate the normal of a triangle

The normal of a plane is defined as an orthogonal vector to such plane. In order to calculate the normal of a triangle, it suffices to construct two directional vectors out of its three vertices and calculate the cross product between them.

Vec3[] vertices = new Vec3[3];
...
Vec3 aToC = Normalize(vertices[2] - vertices[0]);
Vec3 aToB = Normalize(vertices[1] - vertices[0]);
Vec3 normal = Cross(aToC, aToB);

Check if an entity is behind another entity

In game development, the dot product is typically used as a cheap way to determine whether an entity is behind another one.

Vec3 positionA = ...;
Vec3 positionB = ...;
Vec3 forwardA  = ...; //Forward Vector of entity A
Vec3 bToA = positionB - positionA;
bool bIsBehindOfA = Dot(forwardA, bToA) < 0.0;

Are two entities facing each other?

For this, we simply need to check if the two unit vectors –representing the forward direction of each entity– are opposite enough. If their dot product is 1, they will be exactly opposites; in order to leave some give some leeway, we need to account for some threshold of error.

// How different can the vectors get before we consider
// the two entities as not facing each other?
float facingThreshold = ...;

Vec3 forwardA  = ...; //Forward Vector of entity A
Vec3 forwardB  = ...; //Forward Vector of entity B

// To be facing each other, the dot product of the vectors
// need to be as close to -1 as possible.
bool areFacing = (1.0 + Dot(forwardA, forwardB)) <= facingThreshold;

1 In Game Development, it is common to represent both, vectors and points, using the same type of data. Also, out of convenience, points are essentially treated as vectors.