2D Rotations & Rotation Matrices

Geometry & Trigonometry

Chapter 5 · 2D Rotations & Rotation Matrices

Linear Algebra Fundamentals introduced the 2D rotation matrix briefly, as one example transformation among several. This chapter gives it the deeper, dedicated treatment it needs: composing rotations, rotating about a point other than the origin, why the order transforms are applied in genuinely changes the result, and a real, verified reason repeated rotation composition needs care — directly setting up Chapters 6 and 7's own motivation for quaternions.

The 2D Rotation Matrix, Built From the Unit Circle

Chapter 2 defined (cos θ, sin θ) as the point reached by rotating (1,0) by angle θ. The rotation matrix is exactly that idea generalized to rotate any point: R(θ) = [[cos θ, −sin θ], [sin θ, cos θ]].

Composing Rotations

Applying R(θ₁) and then R(θ₂) should be the same as applying one combined rotation, R(θ₁+θ₂) — and matrix multiplication makes that literal: R(θ₂)·R(θ₁) = R(θ₁+θ₂).

Verified directly
R(30°)·R(45°), computed as an actual matrix product, gives [[0.25881904510252085, −0.9659258262890683], [0.9659258262890683, 0.25881904510252085]]. Computing R(75°) directly gives [[0.25881904510252074, −0.9659258262890683], [0.9659258262890683, 0.25881904510252074]] — matching to within ≈10⁻¹⁶, exactly the trigonometric angle-addition identities in matrix form.

Rotating About an Arbitrary Pivot

The rotation matrix alone always rotates around the origin. To rotate around a different pivot point C: translate the point so C becomes the origin, rotate, then translate back — P' = C + R(θ)(P−C).

Verified directly — matching a hand calculation
Rotating P=(5,5) by 90° around pivot C=(2,2): subtracting the pivot gives (3,3); rotating 90° maps (x,y)→(−y,x), giving (−3,3); adding the pivot back gives P' = (−1, 5) — confirmed exactly by the matrix computation.

Why Order Matters: Rotate-Then-Translate vs. Translate-Then-Rotate

Combining a rotation and a translation is not commutative — doing them in the opposite order produces a genuinely different final position, not just a different intermediate path to the same place.

Verified directly — the same two operations, dramatically different results
Starting from (1,0), rotating 90° then translating by (5,0) gives (5.0, 1.0). Translating by (5,0) first, then rotating 90°, gives (≈0, 6.0) — a completely different final point, from the identical rotation and the identical translation, just applied in the opposite order.
Why this is a real, common bug
This is exactly the mechanism behind "my object orbits around the wrong point" bugs in game engines: an object rotated after being moved away from the origin rotates around the origin, not around its own current position, producing a wide, unintended orbiting motion instead of a stationary spin. The fix is precisely this chapter's own arbitrary-pivot formula — rotate around the object's own position as the pivot, not the world origin.

A Real Reason Rotation Matrices Need Care: Accumulated Drift

Chapter 2 verified that accumulating a rotation angle without wrapping it loses precision. Composing rotation matrices by repeated multiplication has an analogous, independently verifiable problem.

Verified directly — 200,000 composed rotations vs. one direct computation
Composing a small rotation matrix (0.0003 radians) with itself 200,000 times via repeated matrix multiplication (total angle: 60 radians) gives a determinant of 1.0000000000188298. A true rotation matrix always has determinant exactly 1 — computing the equivalent single rotation matrix directly, R(60 rad), gives a determinant of 0.9999999999999999, essentially exact. The composed matrix has visibly drifted away from being a genuine rotation at all — its rows and columns are no longer quite perpendicular unit vectors — with a maximum per-entry difference of ≈8.97×10⁻¹² compared to the direct computation.
Why this matters, and what real engines do about it
An object whose orientation is updated every frame by multiplying its current rotation matrix by a small incremental rotation — a completely natural way to implement continuous spinning — accumulates exactly this drift over time, the same way Chapter 2's unwrapped angle accumulator lost precision. Left unchecked, the matrix can gradually stop being a pure rotation at all, distorting the object it represents (subtly scaling or shearing it, not just rotating it). Real engines periodically re-orthonormalize the matrix to correct this drift — and, as Chapter 7 covers, switching to quaternions sidesteps a large part of this problem in the first place.

Where This Connects

This chapter's findingWhat it sets up
Composing rotations via matrix multiplicationDirectly extends to 3D in Chapter 6 — with a genuinely new complication (order-dependence around different axes) that 2D rotation alone can't show
Arbitrary-pivot rotation via translate-rotate-translate-backThe same three-step pattern reappears in Chapter 8's coordinate-system transformations
Accumulated matrix-composition drift, verified over 200,000 stepsThe central, motivating problem Chapter 7's quaternions are specifically designed to reduce

Hands-On Exercises

Exercise 1

Using this chapter's own composition rule, verify by hand (using the angle-addition trigonometric identities cos(a+b)=cos a cos b − sin a sin b and sin(a+b)=sin a cos b + cos a sin b) that R(30°)·R(45°)'s top-left entry should equal cos(75°), and confirm it matches this chapter's own verified numeric result.

📄 View solution
Exercise 2

A game character standing at position (10, 0) needs to spin in place by 180°. Using this chapter's own arbitrary-pivot formula, compute the character's new position if the code incorrectly rotates around the world origin (0,0) instead of the character's own position, and explain what the player would actually observe.

📄 View solution
Exercise 3

Using this chapter's own verified 200,000-step drift experiment, explain why a game engine that updates an object's rotation by matrix-multiplying a small incremental rotation onto it every frame, for an object that spins continuously for a very long play session, could eventually cause visible problems beyond just "the angle is slightly off" — what specifically would start to look wrong?

📄 View solution

Chapter 5 Quick Reference

  • 2D rotation matrix: R(θ) = [[cos θ, −sin θ],[sin θ, cos θ]], built directly from Chapter 2's unit-circle point definition
  • Verified: R(30°)·R(45°) matches R(75°) to within ≈10⁻¹⁶ — matrix composition is angle addition
  • Arbitrary pivot: P' = C + R(θ)(P−C) — verified matching a hand calculation exactly
  • Verified: rotate-then-translate and translate-then-rotate give genuinely different results ((5,1) vs. (≈0,6)) from identical individual operations — the real mechanism behind "orbiting around the wrong pivot" bugs
  • Verified: 200,000 composed small rotations drift to determinant 1.0000000000188298 (should be exactly 1) vs. a fresh direct computation's 0.9999999999999999 — real, measurable degradation from repeated matrix composition
  • Next chapter: 3D rotations, Euler angles, and gimbal lock — where composing rotations gets a genuinely new complication