15. Geometric transformations: rotation, reflection, scaling, shear
§18.1 proved every linear transformation \mathbb{R}^n\to\mathbb{R}^m is \vec x\mapsto A\vec x for a unique matrix A. This lesson makes that correspondence concrete with the four transformations of the plane easiest to see: they're the clearest illustration available of what a matrix "does" to space, and they connect several earlier results — §16.4's determinant-as-area, §16.2's noncommutativity — to pictures.
Rotation
Rotation by angle \theta (counterclockwise, about the origin) sends \vec e_1=(1,0)\mapsto(\cos\theta,\sin\theta) and \vec e_2=(0,1)\mapsto(-\sin\theta,\cos\theta) — read directly off the unit circle, since a rotated \vec e_1 is by definition the point at angle \theta, and a rotated \vec e_2 is 90° further around. By §18.1, stacking these as columns gives the standard matrix:
R_\theta=\begin{pmatrix}\cos\theta&-\sin\theta\\\sin\theta&\cos\theta\end{pmatrix}
\det R_\theta=\cos^2\theta+\sin^2\theta=1 always — matching §16.4's claim that determinant 1 means area and orientation are both exactly preserved, precisely what rotation should do to a shape. R_{\theta_1}R_{\theta_2}=R_{\theta_1+\theta_2} (composing two rotations is a single rotation by the summed angle — confirmed directly in §18.5), and R_\theta^{-1}=R_{-\theta} (undo a rotation by rotating back).
Reflection
Reflection across the x-axis sends (x,y)\mapsto(x,-y): M_x=\begin{pmatrix}1&0\\0&-1\end{pmatrix}. Reflection across the line y=x swaps coordinates: (x,y)\mapsto(y,x), M_{y=x}=\begin{pmatrix}0&1\\1&0\end{pmatrix}. Both have \det=-1: area is preserved in magnitude, but orientation flips — exactly §16.4's sign-of-determinant claim, made visible (trace a counterclockwise triangle through a reflection and it comes out clockwise). Every reflection matrix satisfies M^2=I (reflecting twice returns to the start), so M^{-1}=M — a reflection is its own inverse.
Scaling
Scaling by factors (s_x,s_y) along the axes: S=\begin{pmatrix}s_x&0\\0&s_y\end{pmatrix} sends (x,y)\mapsto(s_xx,\,s_yy). \det S=s_xs_y — literally the area scale factor, the cleanest possible instance of §16.4's geometric meaning of the determinant, since a unit square visibly becomes an s_x\times s_y rectangle. s_x=s_y=k is uniform scaling (everything grows or shrinks by the same factor k, det =k^2); s_x=1,s_y=-1 recovers the x-axis reflection above — reflection is just scaling by -1 in one direction.
Shear
A horizontal shear slides each point right by an amount proportional to its height: (x,y)\mapsto(x+ky,\,y), \text{Sh}_k=\begin{pmatrix}1&k\\0&1\end{pmatrix}. Points on the x-axis (y=0) don't move at all; higher points shift further. A unit square becomes a parallelogram with the same base and height, so \det\text{Sh}_k=1(1)-k(0)=1 — area is preserved even though the shape visibly isn't rigid (unlike rotation, angles and lengths are not preserved by a shear, only area).
Composition, and why order matters
Applying T_2 after T_1 corresponds to the matrix product T_2T_1 (applied right-to-left, matching function composition — formalized fully in §18.5). Because matrix multiplication is not commutative (§16.2), the order two geometric transformations are applied in generally matters: rotate-then-shear looks different from shear-then-rotate. R_{90°}\text{Sh}_1\neq\text{Sh}_1R_{90°} is a fast way to see noncommutativity, rather than just algebraically verify it.
Doing it in Python
import numpy as np
theta = np.pi / 6 # 30 degrees
R = np.array([[np.cos(theta), -np.sin(theta)],
[np.sin(theta), np.cos(theta)]])
square = np.array([[0, 1, 1, 0], [0, 0, 1, 1]]) # unit square, columns are corners
rotated = R @ square
print("det(R) =", round(float(np.linalg.det(R)), 4), " (rotation preserves area)")
print("rotated corners:")
for col in rotated.T.tolist():
print([round(v, 4) for v in col])
det(R) = 1.0 (rotation preserves area)
rotated corners:
[0.0, 0.0]
[0.866, 0.5]
[0.366, 1.366]
[-0.5, 0.866]
Confirming noncommutativity geometrically — rotate-then-shear versus shear-then-rotate on the same point:
import numpy as np
R90 = np.array([[0, -1], [1, 0]]) # 90-degree rotation
Sh = np.array([[1, 1], [0, 1]]) # horizontal shear, k=1
p = np.array([1, 0])
print("rotate then shear:", list(Sh @ (R90 @ p)))
print("shear then rotate:", list(R90 @ (Sh @ p)))
print("same matrix?", np.array_equal(Sh @ R90, R90 @ Sh))
rotate then shear: [1, 1]
shear then rotate: [0, 1]
same matrix? False
Worked example
A unit square is reflected across y=x, then scaled by (2,1). Find the combined matrix and its determinant.
M=\begin{pmatrix}0&1\\1&0\end{pmatrix} (reflection), S=\begin{pmatrix}2&0\\0&1\end{pmatrix} (scaling). "Reflect, then scale" is scale-applied-after-reflect: A=SM.
A=\begin{pmatrix}2&0\\0&1\end{pmatrix}\begin{pmatrix}0&1\\1&0\end{pmatrix}=\begin{pmatrix}0&2\\1&0\end{pmatrix}
\det A=0(0)-2(1)=-2
\boxed{A=\begin{pmatrix}0&2\\1&0\end{pmatrix},\quad\det A=-2}
Sanity check. \det M\cdot\det S=(-1)(2)=-2 ✓, matching §16.4's multiplicative property \det(SM)=\det S\det M exactly. The sign is negative (orientation flips, from the reflection) and the magnitude is 2 (area doubles, from the scaling) — both readable directly from the individual transformations without ever multiplying the matrices, a useful cross-check independent of the matrix arithmetic above.
Your turn
1. Write the matrix for reflection across the y-axis, and verify M^2=I.
2. A shape has area 6. After applying A=\begin{pmatrix}3&0\\0&2\end{pmatrix}, what is the new area?
3. True or false: rotation matrices are the only 2\times2 matrices with determinant 1.
Solutions
1. (x,y)\mapsto(-x,y): M=\begin{pmatrix}-1&0\\0&1\end{pmatrix}. M^2=\begin{pmatrix}-1&0\\0&1\end{pmatrix}\begin{pmatrix}-1&0\\0&1\end{pmatrix}=\begin{pmatrix}1&0\\0&1\end{pmatrix}=I ✓.
2. \det A=3(2)-0=6. New area =6\times6=36 (original area times |\det A|, §16.4's geometric meaning applied directly).
3. False. Any shear \text{Sh}_k=\begin{pmatrix}1&k\\0&1\end{pmatrix} has determinant 1 for every k but is not a rotation for k\neq0 (it doesn't preserve lengths or angles the way rotation does — a rotation matrix additionally satisfies R^TR=I, a much stronger condition developed fully in §21.1's unitary/orthogonal matrices). Determinant 1 only guarantees area and orientation are preserved, not that the transformation is rigid.
Check yourself in code
Compose a 90° rotation followed by a reflection across the x-axis (rotate first, then reflect), find the combined matrix, and apply it to the point (1,2).
Print exactly this:
combined matrix A =
[0, -1]
[-1, 0]
A @ (1,2) = [-2, -1]
import numpy as np
R90 = np.array([[0, -1], [1, 0]])
Mx = np.array([[1, 0], [0, -1]])
A = Mx @ R90 # reflect after rotate
print("combined matrix A =")
for row in A.tolist():
print(row)
# print "A @ (1,2) = ..." applying A to the point (1, 2)
import numpy as np
R90 = np.array([[0, -1], [1, 0]])
Mx = np.array([[1, 0], [0, -1]])
A = Mx @ R90
print("combined matrix A =")
for row in A.tolist():
print(row)
p = np.array([1, 2])
print("A @ (1,2) =", list(A @ p))
Rotation, reflection, scaling, and shear are the most visual instances of §18.1's matrix-transformation correspondence: rotation matrices have determinant 1 and preserve everything rigid; reflections have determinant -1 and flip orientation; scaling's determinant is literally the area factor; shear preserves area while distorting angles. Composing them is matrix multiplication, and since that's not commutative, order visibly changes the result.
Next: two subspaces attached to any linear transformation — kernel and image — the transformation analogues of §17.4's null space and column space.