Matrices as Transformations

Linear Algebra Fundamentals

Chapter 5 · Matrices as Transformations

Chapter 4 ended with a forward reference: a matrix is "a rule for transforming vectors." This chapter makes that literal. Multiplying a matrix by a vector — a special case of Chapter 4's own matrix multiplication, where the second matrix has just one column — produces a new vector, and a small, well-known family of matrices produce specific, useful transformations: scaling, rotating, reflecting, and shearing.

Matrix-Vector Multiplication — The Same Rule, One Column Wide

A vector v = [3, 4] can be written as a 2×1 matrix, a single column: [[3], [4]]. Multiplying a 2×2 matrix by it uses exactly Chapter 4's row-by-column rule — each output entry is the dot product of a matrix row and the vector's single column.

def transform(M, v): # M is a 2x2 matrix, v is a 2-element vector return [ M[0][0]*v[0] + M[0][1]*v[1], M[1][0]*v[0] + M[1][1]*v[1], ]

Scaling

A scaling matrix has the scale factors on the diagonal, zeros elsewhere:

Scaling matrix
S = [[sₓ, 0], [0, sᵧ]] — stretches x by sₓ, y by sᵧ, independently.

With S = [[2, 0], [0, 0.5]] and v = [3, 4]: S v = [2×3, 0.5×4] = [6, 2] — twice as wide, half as tall.

Rotation

A rotation by angle θ (counter-clockwise) uses:

Rotation matrix
R(θ) = [[cos θ, −sin θ], [sin θ, cos θ]]

For θ = 90°: cos(90°) = 0, sin(90°) = 1, so R(90°) = [[0, −1], [1, 0]]. Applied to v = [3, 4]: R v = [0×3 + (−1)×4, 1×3 + 0×4] = [−4, 3].

A rotation matrix always preserves length
|v| = √(3² + 4²) = 5, and |R v| = √((−4)² + 3²) = √25 = 5 — identical. A genuine rotation never stretches or shrinks anything, which is a useful sanity check: if a "rotation" matrix changes a vector's length, it isn't actually a pure rotation.

Reflection

Reflecting across the x-axis flips the sign of y only; reflecting across the y-axis flips the sign of x only:

ReflectionMatrixv = [3, 4] becomes
Across the x-axis[[1, 0], [0, −1]][3, −4]
Across the y-axis[[−1, 0], [0, 1]][−3, 4]

Shear

A shear slides one axis's coordinates sideways in proportion to the other axis, turning a rectangle into a parallelogram without changing its area:

Horizontal shear matrix
Sh(k) = [[1, k], [0, 1]]

With k = 1: Sh v = [1×3 + 1×4, 0×3 + 1×4] = [7, 4] — x shifted by an amount proportional to y, y unchanged.

Composing Transformations — And Why Order Matches Chapter 4

To apply two transformations in sequence, multiply their matrices together — and because Chapter 4 already established that matrix multiplication isn't commutative, the order genuinely changes the result. R × S means "apply S first, then R" (read right to left, matching how it's applied to a vector: (R × S) v = R (S v)).

Reusing S = [[2, 0], [0, 0.5]], R = [[0, −1], [1, 0]], and v = [3, 4]:

OrderMeaningCombined matrixResult on v
R × SScale first, then rotate[[0, −0.5], [2, 0]][−2, 6]
S × RRotate first, then scale[[0, −2], [0.5, 0]][−8, 1.5]
Same two operations, genuinely different outcomes
Scaling v by 2× horizontally and 0.5× vertically, then rotating 90° gives [−2, 6]. Rotating 90° first, then applying that exact same scale, gives [−8, 1.5] — a visibly different point. This is exactly why 3D modelling and game-engine transform stacks are so careful about ordering "scale, then rotate, then translate" consistently — swapping the order silently changes the result.

Homogeneous Coordinates — Why Translation Needs a Trick

Every transformation above is linear — algebraically, a 2×2 matrix multiplication always sends the origin [0, 0] to itself (M × [0,0] = [0,0], for any M). Translation — sliding every point by a fixed offset — genuinely moves the origin, so no plain 2×2 matrix can represent it at all.

The fix is homogeneous coordinates: pad every 2D vector with an extra 1, turning [x, y] into [x, y, 1], and use a 3×3 matrix. The extra row and column let a translation "leak" into the result through that constant 1:

Translation matrix (homogeneous form)
T = [[1, 0, tₓ], [0, 1, tᵧ], [0, 0, 1]]

Translating v = [3, 4] (as [3, 4, 1]) by (tₓ, tᵧ) = (5, −2): T × [3, 4, 1] = [1×3 + 0×4 + 5×1, 0×3 + 1×4 + (−2)×1, 1] = [8, 2, 1] — the point (8, 2), exactly (3+5, 4−2), as expected.

Why this matters for graphics tools
Every scaling, rotation, and shear matrix from earlier in this chapter also has a 3×3 homogeneous version (just pad with a row/column of [0, 0, 1]), which is precisely why every practical transform in Blender, Figma, or a game engine can be combined into a single matrix multiplication chain — translation included — instead of treating translation as a special case handled separately from everything else.

Hands-On Exercises

Exercise 1

Given w = [2, -1], apply the scaling matrix S = [[3, 0], [0, 2]], then separately apply the 90° rotation matrix R = [[0, -1], [1, 0]] to the original w (not the scaled result). Show both calculations, and verify the rotated result has the same magnitude as w.

📄 View solution
Exercise 2

Using S = [[3, 0], [0, 2]] and R = [[0, -1], [1, 0]] from Exercise 1, compute the combined matrix R × S and the combined matrix S × R, then apply each combined matrix to w = [2, -1]. Confirm the two final results are different, and state in one sentence which real-world order each one represents ("scale then rotate" or "rotate then scale").

📄 View solution
Exercise 3

Using homogeneous coordinates, translate the point [2, -1] by (tₓ, tᵧ) = (-3, 4). Write out the 3×3 translation matrix, the homogeneous form of the point, and the full matrix-vector multiplication. Then explain, using this chapter's own "translation moves the origin" argument, why no ordinary 2×2 matrix could have achieved the same result.

📄 View solution

Chapter 5 Quick Reference

  • Scaling: [[sₓ, 0], [0, sᵧ]] — stretches/shrinks each axis independently
  • Rotation: [[cos θ, −sin θ], [sin θ, cos θ]] — always preserves length
  • Reflection: flip the sign of one axis's coefficient in the identity matrix
  • Shear: [[1, k], [0, 1]] — slides one axis proportionally to the other, preserving area
  • Composing: multiply the matrices; A × B means "apply B first, then A" — order matters, per Chapter 4's non-commutativity
  • A plain matrix transformation always fixes the origin — translation genuinely can't be represented by a 2×2 matrix alone
  • Homogeneous coordinates: pad vectors with a 1 and use a 3×3 matrix so translation becomes just another matrix multiplication
  • Next chapter: Systems of linear equations and Gaussian elimination