Following recommendation of this answer I've recently read the series of articles of Wolfire about linear algebra. I'm somewhat familiar with matrices and I came to a conclusion that vector and a matrix multiplication is in fact multiplication of 2x2 and 2x1 matrices:

\begin{equation*} \begin{bmatrix} a & c \\ b & d \end{bmatrix} \qquad \begin{bmatrix} x \\ y \end{bmatrix} \end{equation*}

In the article the author reveals that to accomplish translation in addition to rotation we need to add a row and a column to the translation matrix:

If we want to translate by a vector (e,f), we can just tack it onto our change-of-basis matrix like this: \begin{bmatrix} a & c & e\\ b & d & f\\ 0 & 0 & 1 \end{bmatrix} And then we add an extra 1 to the end of each position vector like this: \begin{bmatrix} x\\ y\\ 1 \end{bmatrix}

P.S. I edited the direction of the vector to make it comply with matrix multiplication conditions.

The 1 at the third row of the vector is totally understandable: to multiply 2x3 matrix we need a 3-row matrix.

What I didn't get here is why we need extra row for translation matrix? I can't see any difference in multiplication (except for the useless 1):

\begin{equation*} \begin{bmatrix} a & c & e\\ b & d & f\\ 0 & 0 & 1 \end{bmatrix} * \begin{bmatrix} x\\ y\\ 1 \end{bmatrix} = \begin{bmatrix} ax + cy + e\\ bx + dy + f\\ 0 + 0 + 1 \end{bmatrix} \end{equation*}

\begin{equation*} \begin{bmatrix} a & c & e\\ b & d & f\\ \end{bmatrix} * \begin{bmatrix} x\\ y\\ 1 \end{bmatrix} = \begin{bmatrix} ax + cy + e\\ bx + dy + f\\ \end{bmatrix} \end{equation*}

So the same question for 3D matrices, just it's easier to convey with a 2D case


1 Answer 1


If you're doing all your transformation with a single matrix, and you don't need to do any other computation with that matrix or the output vectors, then you're right, you don't need the extra row.

But if you want to transform a vector in stages, then the extra row helps. Imagine this:

v2 = MatrixA * v1
v3 = MatrixB * v2

If MatrixA & MatrixB are 2x3 matrices, then even if v1 is a 3-vector, the multiplication by MatrixA squashes the result v2 down to a 2-vector. Now it doesn't have enough entries to multiply by MatrixB for the second step of the computation.

The same thing happens if we want to concatenate matrices:

MatrixC = MatrixB * MatrixA
v3 = MatrixC * v1

Here MatrixA isn't the right shape to multiply with MatrixB, so we can't express their combination as a third matrix.

And we run into similar problems if we need the inverse of a matrix at any point, to un-transform a vector. The inverse is only strictly defined for square matrices.

So, adding this extra row helps us preserve the extra translation dimension through multiple chained operations, and lets our math proceed in a more uniform way, whether we're working backwards or forwards, through one matrix or several.

Now, just because the third row is there mathematically doesn't necessarily mean we need to store it and compute it literally. Some game & graphics math libraries will still just store the preceding rows, and structure their multiplication methods "as though" an extra row (0, 0, ..., 1) were present, without explicitly storing or multiplying by all those zeroes & the final one.


You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .