Chapter 08

Rotation in Three Dimensions

Matrix form, Euler angles, gimbal lock, axis-angle, and quaternions.

In this chapter

  1. Orientation vs Angular Displacement
  2. Matrix Form
  3. Euler Angles
  4. Gimbal Lock & Canonical Euler Angles
  5. Axis-Angle & Exponential Map
  6. Quaternions
  7. Exercises
1

Orientation vs Angular Displacement

Two closely related but distinct concepts:

This distinction matters when interpolating rotations. Interpolating between two orientations (e.g., for animation blending) is different from integrating an angular velocity (physics simulation). The math for each path has different requirements.

An orientation can be described as a rotation from some known reference orientation (usually the identity / "upright" space). The amount of that rotation is the angular displacement.

For local/object coordinate spaces, the basis vectors will always be [1,0,0], [0,1,0], [0,0,1] (upright space). An orientation describes how these axes relate to that reference.


2

Matrix Form

A 3×3 rotation matrix stores the basis vectors of the object's local space expressed in the parent coordinate space. Each row is a basis vector.

Direction Cosines Matrix

A special way to build the matrix: use the cosines of the angles between each pair of basis vectors. This is equivalent to the dot product between unit vectors:

┌ p·p' q·p' r·p' ┐ M = │ p·q' q·q' r·q' │ └ p·r' q·r' r·r' ┘ where p,q,r are basis vectors of the initial CS and p',q',r' are basis vectors of the final CS

When the first coordinate space uses unit basis vectors, the matrix simplifies to just the dot products between the unit axes — which are exactly the direction cosines.

Advantages of Matrix Form
  • Rotating a vector is immediate (one matrix multiply)
  • Used directly by graphics APIs
  • Can concatenate multiple angular displacements
  • Matrix inversion (= transpose for ortho) is cheap
Disadvantages of Matrix Form
  • 9 numbers to store (vs 3 for Euler, 4 for quaternion)
  • Difficult to read/author by hand
  • Can accumulate floating-point error → "matrix drift"
  • Must periodically re-orthogonalize

3

Euler Angles

Describes orientation as three successive rotations about three mutually perpendicular axes. Any three axes and any order will work — different books use different conventions. This text uses heading, pitch, bank (also called yaw, pitch, roll) in a left-handed system:

  1. Start in identity orientation (object space = upright space)
  2. Heading (H / yaw) — rotate about the object's Y axis. Clockwise is positive.
  3. Pitch (P) — rotate about the object's X axis. Downward is positive.
  4. Bank (B / roll) — rotate about the object's Z axis. Counter-clockwise is positive.

Fixed Axis vs Object Axis

Using a fixed axis means H, P, B are always measured from the upright/world axes (extrinsic rotations). The key insight:

Applying (H, P, B) with object axes in order == Applying (B, P, H) with fixed axes
Advantages
  • Easiest for humans to understand and author
  • Only 3 numbers — minimal memory
  • Any three numbers form a valid orientation
  • Handles data loss well (numbers are just angles)
Disadvantages
  • Representation is not unique (aliasing)
  • Susceptible to gimbal lock
  • Interpolation is problematic
  • Composing rotations is more complex

4

Gimbal Lock & Canonical Euler Angles

Canonical Euler Angle Set

-180° < h ≤ 180° -90° ≤ p ≤ 90° -180° < b ≤ 180° Special case: p = ±90° → b = 0 (resolves aliasing at the poles)

Gimbal Lock

Gimbal lock occurs when p = ±90° (pitch straight up or straight down). At this angle, the heading and bank rotations become aligned — they both rotate about the same world-space axis, losing a degree of freedom. The "outer ring" and "inner ring" of the gimbal physically collapse onto the same axis.

Gimbal lock is a fundamental limitation of Euler angles — it's not a bug but a mathematical consequence of representing 3D orientation with three sequential single-axis rotations. Setting b = 0 when p = ±90° is a convention choice to avoid non-unique representations, but the loss of the third degree of freedom at those orientations is unavoidable with Euler angles alone.

Interpolation Problems

Even with canonical Euler angles, simple linear interpolation (lerp) can produce bad results:

Δθ = θ₁ - θ₀ θt = θ₀ + t·Δθ

The issue: interpolating from 170° to -170° would traverse 340° instead of the intended 20°. The fix is to wrap the delta into [−180°, 180°] using:

wrapPi(x) = x - 360° · floor((x + 180°) / 360°)

However, even with this fix, lerp can still suffer from gimbal lock. This is a fundamental problem when specifying orientation with only three values.


5

Axis-Angle & Exponential Map

Euler's Rotation Theorem

Any 3D angular displacement can be accomplished via a single rotation about a carefully chosen axis. This is the foundation of the axis-angle representation.

Axis-Angle

Axis-Angle: { n̂, θ } n̂ = unit vector in the direction of the rotation axis (passes through origin) θ = the rotation angle

Since is a unit vector, you can multiply it by θ without changing the encoded direction/angle data:

e = θ · n̂

Exponential Map

The exponential map encodes the axis-angle as a single 3D vector e whose direction matches and whose magnitude equals θ:

e = θ · n̂ (‖e‖ = θ)
Advantages
  • Better interpolation than Euler angles
  • Handles angular velocity naturally
  • Avoids gimbal lock at most orientations
Disadvantages
  • Still has aliasing (n̂, θ) == (-n̂, -θ)
  • Rotating a vector requires building a matrix first
  • Edge cases near 0° and 360°

6

Quaternions

Quaternions use four numbers to represent an orientation — a scalar w and a 3D vector component (x, y, z):

q = [ w (x y z) ] = [ cos(θ/2) sin(θ/2)·n̂ ] = [ cos(θ/2) sin(θ/2)·nx sin(θ/2)·ny sin(θ/2)·nz ]

The axis and angle are encoded into the four components by halving the angle. This half-angle encoding is what makes quaternions work mathematically.

What do the Numbers Mean?

Similar to axis-angle: is the unit axis of rotation and θ is the rotation amount. The difference is how they're encoded — both the angle and axis are "spread" across all four values through the half-angle trig functions.

Double Cover

Any orientation has exactly two quaternion representations: q and -q. They encode the same rotation (one goes "the short way around," the other "the long way"):

-q = [ -w (-x -y -z) ] describes the same orientation as q
This is called "double cover" — quaternions map the orientation sphere to itself twice. It's why quaternion interpolation must check which of the two aliases is closer before lerping, to avoid the 360° wrap-around problem.

Key Operations

Negation

-q = [-w (-x -y -z)] same angular displacement as q

Identity

I = [1 (0 0 0)] describes no angular displacement

Magnitude

‖q‖ = √(w² + x² + y² + z²) valid rotation quaternions have ‖q‖ = 1

Multiplication (Concatenating Rotations)

For q₁ = [w₁, v₁] and q₂ = [w₂, v₂]: q₁·q₂ = [ w₁w₂ - v₁·v₂, w₁v₂ + w₂v₁ + v₁×v₂ ]

Conjugate & Inverse

q* = [w (-x -y -z)] conjugate (for unit quaternions, also the inverse) q⁻¹ = q* / ‖q‖²
Advantages
  • Smooth interpolation (SLERP)
  • Only 4 numbers
  • Fast to concatenate and invert
  • No gimbal lock
  • Numerically stable
Disadvantages
  • Unintuitive to read or author directly
  • Double-cover aliasing
  • Rotating a vector still requires conversion or formula

7

Exercises

1. Euler → Matrix

Convert the orientation (h=90°, p=0°, b=0°) to the equivalent 3×3 rotation matrix. Which way does the object's forward vector point?

Heading 90° about Y (left-handed, clockwise from above). Ry(90°): forward was (0,0,1), after 90° CW it becomes (1,0,0). The object now faces the world +X axis.

2. Quaternion from Axis-Angle

Convert a 180° rotation about the Y axis to quaternion form.

w = cos(90°) = 0. x = sin(90°)·0 = 0. y = sin(90°)·1 = 1. z = 0. q = [0, (0, 1, 0)]. Negation: -q = [0, (0, -1, 0)] — same rotation.

3. SLERP vs LERP

You need to smoothly interpolate a camera from orientation A to orientation B over 30 frames. Should you use LERP or SLERP on the quaternions? Why?

SLERP (spherical linear interpolation) — it interpolates at a constant angular velocity along the shortest arc on the 4D quaternion sphere. LERP produces non-constant angular speed (the camera accelerates/decelerates mid-path). For smooth camera animation, SLERP is correct. LERP + renormalize is an acceptable approximation when angles are small.

Interview Question

What is gimbal lock and how do quaternions avoid it?

Gimbal lock occurs in Euler angles when two rotation axes align (e.g., pitch = ±90°), collapsing three degrees of freedom to two. Quaternions avoid this because they represent rotation as a single 4D unit vector — there's no sequential axis dependency and no degenerate configuration where two axes collapse. Quaternion space is continuous and has no singularities (except the double-cover aliasing, which is a different issue).

Interview Question

When would you choose Euler angles over quaternions in a game engine?

Euler angles are preferred in editor UIs and animation tools where humans need to read and author values directly. Artists understand "rotate 45° in yaw" but not "quaternion [0.92, 0, 0.38, 0]." Euler angles are also good for displaying object rotation in inspector panels. Internally the engine converts to quaternions for interpolation, physics, and concatenation.

Interview Question

What does the W component of a quaternion represent?

W = cos(θ/2), where θ is the rotation angle. It encodes "how much of the rotation is the identity (no rotation)" — when W = 1, the quaternion is the identity (no rotation); when W = 0, it's a 180° rotation. Together with the XYZ vector components (which equal sin(θ/2)·n̂), W lets you recover both the rotation axis and angle: θ = 2·arccos(W), n̂ = xyz / sin(θ/2).
← Chapter 7 ↑ Index Chapter 9 →