Fun with Basis Vectors

From time to time, it’s useful to know a little about the transformed space represented in a matrix.

In a column-major matrix, each row of a matrix represents a basis vector (transformed axis vector). Row 0 is the transformed X axis, Row 1 is Y, row 2 is Z.

In a row-major matrix, each column contains a basis vector. Column 0 is the transformed X axis, column 1 is Y, column 2 is Z. (Column 3 is the sum of all of the translations that have been used to build the matrix.)

Why is this significant?

Imagine if we want to, say: figure out which way our Asteroids ship is pointed so that we can move it in the correct direction.

Assuming that we start with a model with the ship pointed UP in screen space (direction = \(\begin{bmatrix}0 & 1 & 0 & 0 \end{bmatrix}\)), we can just grab the transformed Y basis vector from the matrix.

If we label each basis vector component (transformed axis vector) as \({axis}_{x,y,z}\),
In column-major matrix,

\(
\begin{bmatrix}
x^1_{x} & x^1_{y} & x^1_{z} & x^1_{w} \\
y^1_{x} & y^1_{y} & y^1_{z} & y^1_{w} \\
z^1_{x} & z^1_{y} & z^1_{z} & z^1_{w} \\
w^1_{x} & w^1_{y} & w^1_{z} & w^1_{w} \\
\end{bmatrix}
\)

So, if we wanted to know which way our Asteroids ship was pointed – which is initially along \(\hat{y}\), we could just grab the second row:

[code language=”cpp”]
up.x = world.m10;
up.y = world.m11;
up.z = world.m12;

// might have to divide by W! (Why?:))
up /= world.m13;
[/code]

If we wanted vectors for “right” and “forward,” we would use the first (X) and third (Z) rows, respectively.

For a row-major matrix, we would use the first column as X, second as Y and third as Z.