Rotation Matrices in 3-D

A game world is three-dimensional, and so are its rotations: a camera pitches up, a character turns to face a door, a die tumbles. The complex-number trick was a single multiplication, but matrices generalise to three dimensions immediately — and they remain the workhorse representation inside a vertex shader. We build the three elementary rotations about the coordinate axes, then compose them, working in 3-D vectors.

Rotating about the x-axis

Step 1 — rotate about x. Spinning about the x-axis leaves the x-coordinate fixed and rotates the (y, z)-plane by \theta — exactly the 2-D rotation we already know, now living in the lower-right block:

R_x(\theta) = \begin{bmatrix} 1 & 0 & 0 \\ 0 & \cos\theta & -\sin\theta \\ 0 & \sin\theta & \cos\theta \end{bmatrix}.

The first row and first column are the untouched x-axis: a 1 on the diagonal and zeros around it.

Rotating about the y- and z-axes

Step 2 — rotate about y. Now the y-coordinate is fixed and the (z, x)-plane turns. The fixed row/column is the middle one (the y-axis), and the sign pattern flips compared with the others — a consequence of the cyclic order x \to y \to z \to x:

R_y(\theta) = \begin{bmatrix} \cos\theta & 0 & \sin\theta \\ 0 & 1 & 0 \\ -\sin\theta & 0 & \cos\theta \end{bmatrix}.

Step 3 — rotate about z. The z-coordinate is fixed and the (x, y)-plane turns — the plain 2-D rotation sitting in the top-left block, with the z-axis (last row/column) untouched:

R_z(\theta) = \begin{bmatrix} \cos\theta & -\sin\theta & 0 \\ \sin\theta & \cos\theta & 0 \\ 0 & 0 & 1 \end{bmatrix}.

In each one, the axis you spin about keeps its own coordinate, and the 2 \times 2 rotation block lives in the other two.

Composing for a general rotation

Step 4 — multiply elementary rotations to reach any orientation. A single product of the three building blocks reaches every rotation in space. For example, pitch then yaw then roll:

R = R_z(\gamma)\,R_y(\beta)\,R_x(\alpha).

Matrix multiplication composes the spins, and — unlike the plane — order matters: R_x R_y \ne R_y R_x in general, because 3-D rotations don't commute. This is precisely composing transformations applied to spins, and naming those three angles is the subject of the next page.

Inverting a rotation is free

Step 5 — the columns are an orthonormal right-handed frame. Each column of a rotation matrix is the image of a basis vector; for a rotation those images are still mutually perpendicular unit vectors (the spin doesn't stretch or shear). A matrix whose columns are orthonormal is called orthogonal, and orthogonal matrices have a defining property:

R^{\mathsf T} R = I.

Step 6 — read off the inverse. That equation says R^{\mathsf T} is the inverse:

R^{-1} = R^{\mathsf T}.

Inverting a rotation costs nothing but a transpose — no determinant, no Gaussian elimination, just swap rows and columns. An engine that needs to undo a camera rotation a thousand times a frame loves this. And since the frame is right-handed (a proper rotation, no mirror flip),

\det R = +1. Rotation about a coordinate axis by an angle \theta is given by one of three elementary matrices, and:

Here is the most useful way to read a rotation matrix in a game. Its three columns are the images of \hat{x}, \hat{y}, \hat{z} — which means they are exactly the object's own local x, y and z axes expressed in world coordinates:

R = \big[\; \mathbf{right} \;\big|\; \mathbf{up} \;\big|\; \mathbf{forward} \;\big].

The first column is where the object's right vector points in the world, the second its up vector, the third its forward. So a rotation matrix isn't an abstract array — it is a little gimbal-free description of which way the object is facing. Want to know where a spaceship's nose points? Read off the appropriate column. This is also why R^{\mathsf T} = R^{-1} is so natural: transposing turns the columns (the local axes in world space) into rows (the world axes in local space), which is exactly the reverse transform.

Turn a 3-D frame

Pick an axis — x, y or z — and drag the angle. The little right-handed frame (its red x, green y and blue z arrows) spins about the chosen axis, shown in a simple isometric projection. The axis you select stays put while the other two arrows swing around it — the geometric meaning of "this row/column is fixed".