Vectors

This blog post will talk about some of the most common operations that can be performed on a vector. Here we will refer to all vectors as vectors in 3D-space. The operations are for the most part the same in all ND-spaces.

Addition
When you’re adding two vectors together, you’re performing a component-wize addition on the two vectors. If you’re adding the vector A (1.0, 2.0, 3.0) to the vector B (4.0, 5.0, 6.0), you’d get a vector C (5.0, 7.0, 9.0). This addition may look like C = A + B.

float AX = 1.0;
float AY = 2.0;
float AZ = 3.0;

float BX = 4.0;
float BY = 5.0;
float BZ = 6.0;

float CX = AX + BX;//5.0
float CY = AY + BY;//7.0
float CZ = AZ + BZ;//9.0

Subtraction
When you’re subtracting two vectors, you’re performing a component-wize subtraction on the two vectors. If you’re subtracting the vector B (4.0, 5.0, 6.0) from the vector A (5.0, 7.0, 9.0), you’d get a vector C (1.0, 2.0, 3.0). This subtraction may look like C = A – B.

float AX = 5.0;
float AY = 7.0;
float AZ = 9.0;

float BX = 4.0;
float BY = 5.0;
float BZ = 6.0;

float CX = AX - BX;//1.0
float CY = AY - BY;//2.0
float CZ = AZ - BZ;//3.0

Multiplication
When you’re multiplying two vectors together, you’re performing a component-wize multiplication on the two vectors. If you’re multiplying the vector A (2.0, 2.0, 2.0) with the vector B (3.0, 3.0, 3.0), you’d get a vector C (6.0, 6.0, 6.0). This multiplication may look like C = A * B. Vector multiplication is also possible with a vector and a scalar value (where a scalar value means any number).

float AX = 2.0;
float AY = 2.0;
float AZ = 2.0;

float BX = 3.0;
float BY = 3.0;
float BZ = 3.0;

float CX = AX * BX;//6.0
float CY = AY * BY;//6.0
float CZ = AZ * BZ;//6.0

Division
When you’re dividing two vectors, you’re performing a component-wize division on the two vectors. If you’re dividing the vector A (6.0, 6.0, 6.0) with the vector B (3.0, 3.0, 3.0), you’d get a vector C (2.0, 2.0, 2.0). This division may look like C = A / B. Vector division is also possible with a vector and a scalar value (where a scalar value means any number).

float AX = 6.0;
float AY = 6.0;
float AZ = 6.0;

float BX = 3.0;
float BY = 3.0;
float BZ = 3.0;

float CX = AX / BX;//2.0
float CY = AY / BY;//2.0
float CZ = AZ / BZ;//2.0

Length
The length of a vector, which is a scalar value and not a vector, is the square root of X * X + Y * Y + Z * Z. Sometimes the length squared is required, in which case the square root is omitted.

float AX = 1.0;
float AY = 1.0;
float AZ = 1.0;

float ALength = Sqrt(AX * AX + AY * AY + AZ * AZ);

Dot Product
The dot product between the two vectors A and B, is A.X * B.X + A.Y * B.Y + A.Z * B.Z. The dot product is a scalar value, not a vector.

float AX = 1.0;
float AY = 1.0;
float AZ = 1.0;

float BX = 1.0;
float BY = 1.0;
float BZ = 1.0;

float DotProduct = AX * BX + AY * BY + AZ * BZ;//3.0

Normalizing a Vector
To normalize a vector, simply divide the vector by its length.

float AX = 1.0;
float AY = 1.0;
float AZ = 1.0;

float ALength = Sqrt(AX * AX + AY * AY + AZ * AZ);

float BX = AX / ALength;
float BY = AY / ALength;
float BZ = AZ / ALength;

Cross Product
The cross product between the two vectors A and B is a vector C. The vector C is defined by C.X = (A.Y * B.Z – A.Z * B.Y), C.Y = (A.Z * B.X – A.X * B.Z) and C.Z = (A.X * B.Y – A.Y * B.X).

float AX = 1.0;
float AY = 1.0;
float AZ = 1.0;

float BX = 1.0;
float BY = 1.0;
float BZ = 1.0;

float CX = AY * BZ - AZ * BY;
float CY = AZ * BX - AX * BZ;
float CZ = AX * BY - AY * BX;

Optimizations
When you write the code yourself, you may want to use a few optimizations. One of them concerns division, because division tends to be slow. If you’re dividing by the same value more than once, you can always calculate its reciprocal (inverse) and then use that reciprocal value to multiply with instead.

float AX = 1.0;
float AY = 1.0;
float AZ = 1.0;

float ALength = Sqrt(AX * AX + AY * AY + AZ * AZ);
float ALengthReciprocal = 1.0 / ALength;//Always 1.0 / X

float BX = AX * ALengthReciprocal;//Instead of AX / ALength
float BY = AY * ALengthReciprocal;//Instead of AY / ALength
float BZ = AZ * ALengthReciprocal;//Instead of AZ / ALength

Points vs. Vectors

This article assumes you’re somewhat familiar with ND-spaces (where N can be replaced by some arbitrary number). The two ND-spaces we’ll talk about are 2D-space and 3D-space.

When you’re dealing with 3D graphics, the most common concepts you’ll come across are points and vectors. They’re used pretty much everywhere. But what are they, and what differences are there between the two?

As you might know, both points and vectors are represented by their coordinates, such as (X, Y) in 2D-space or (X, Y, Z) in 3D-space. They do look very similar, but they are distinct concepts.

A point represents a point in ND-space. It practically has no area, so it’s infinitesimal.

A vector represents a direction and a length in ND-space. How can it represent a direction? Doesn’t that require two points in ND-space? Yes it does. One of the two points is implicit, whereas the other, the one you specify yourself, is explicit. The implicit point is at the point that represents the origin in that ND-space. In 2D-space the origin is (0.0, 0.0) and in 3D-space the origin is (0.0, 0.0, 0.0). If you specify a vector in 3D-space as (1.0, 2.0, 3.0), that means you’re specifying a vector that starts at the point (0.0, 0.0, 0.0) in 3D-space and is directed towards the point (1.0, 2.0, 3.0) in 3D-space.