Affine Transformations Lab
Linear, plus a shift
The Matrices lab's transformations stretch, rotate and shear space, but the origin never moves. Add one more ingredient — a translation — and you get the affine maps: the transformations of computer graphics, robotics and image processing, and the Wx + b inside every neural-network layer. One trick, homogeneous coordinates, turns all of them back into a single matrix multiply, and that is where both the elegance and the speed come from.Scale, shear, rotate and translate the letter F. The four steps are multiplied together into one 3×3 homogeneous matrix, shown live: its top-left 2×2 block (teal) is the linear part, its third column (orange) is the translation, and its bottom row is always 0 0 1. The faint teal grid is where the whole coordinate grid goes — straight lines stay straight and parallel lines stay parallel, whatever you do.
Transform explorer
Dashed outline: the original F. Yellow: its image. Orange: where the origin goes. Pink: a segment and its midpoint.
Experiments to try
Order matters
Rotate by 90° and translate x by 3. Switch between "translate last" and "translate first": the F lands in different places, because a shift that happens before the rotation gets rotated too.
Break the shape, keep the lines
Shear hard and scale x and y differently. Lengths and angles change, the area changes by det, yet the grid stays a grid of parallel lines and the midpoint stays the midpoint.
Watch the cost panel
Turn on one step, then all four. Step by step, every step is one more pass over a million points; composed, it is always one matrix and one pass.
A single neuron computes w·x + b and fires (through a ReLU) on one side of the line where that is zero. The weights w turn the line; the bias b slides it. Two clusters sit in the same direction from the origin — try to separate them with the bias switched off, then on.
Layer explorer
Shading shows how strongly the neuron fires (its ReLU output). Ringed points are on the wrong side.
What to look for
With the bias off, the line can only spin about the origin, and both clusters lie the same way from it: no angle splits them. Switch the bias on, set the direction near 45°, and slide b negative until the line falls between the clusters. The equation line shows the homogeneous view of the same neuron: b is just a third weight, multiplied by an input that is always 1 — the same trick that put the translation into the 3×3 matrix. (The "best possible" figures come from simply trying every angle and offset, not from training.)
An affine map is a linear map followed by a shift. Homogeneous coordinates write it as a single matrix, which is what makes it cheap to compose, cheap to apply in bulk, and the natural form for graphics hardware — and it is exactly what each layer of a neural network computes before its activation.
1. Linear versus affine
A linear map is $f(x) = Ax$: it can stretch, rotate and shear, but $f(0)=0$ always. An affine map adds a translation, $f(x) = Ax + t$. Translation is not linear — $f(x+y) \ne f(x)+f(y)$ once $t\ne0$ — so no 2×2 matrix can move the origin. That is the gap between the Matrices lab and the real transformations of graphics and machine learning.
2. The homogeneous trick
Give every point a third coordinate that is always 1, $(x, y) \to (x, y, 1)$. Then the affine map becomes one matrix product: $$\begin{pmatrix}x'\\y'\\1\end{pmatrix} = \begin{pmatrix}a&b&t_x\\c&d&t_y\\0&0&1\end{pmatrix}\begin{pmatrix}x\\y\\1\end{pmatrix}$$ The 2×2 block is the linear part, the last column is the translation, and the bottom row keeps the 1 in place. In 3-D the same idea gives the $4\times4$ matrices used by every graphics engine; a rigid motion there is a rotation from the Unit Sphere & Rotations lab plus a translation column.
3. What survives an affine map
Straight lines stay straight, parallel lines stay parallel, and ratios along a line are kept — so midpoints stay midpoints and centroids stay centroids. Lengths and angles are not kept in general, and every area is multiplied by $\det A$. The family nests: a rigid motion (rotation + translation) keeps lengths and angles; a similarity adds uniform scaling and keeps angles; a general affine map adds shear and uneven scaling and keeps only lines and ratios.
4. Why homogeneous coordinates are fast
The performance case is the main reason the whole graphics and robotics world works in homogeneous coordinates. It comes from five places:
- Compose once, apply once. A chain of $k$ transforms multiplies into one matrix before any point is touched, $M = M_k \cdots M_2 M_1$. Each point then costs one matrix–vector product — 4 multiplies and 4 adds in 2-D, 9 and 9 in 3-D — no matter how long the chain is. Applied step by step, the cost per point grows with $k$. A typical 3-D scene chains object → parent → world → camera → screen; for a million vertices, composing those five transforms first does one product per vertex instead of five, while composing the matrices themselves takes a few hundred operations in total.
- One pass over memory. Step by step, every stage reads and writes every point: $k$ full passes over the data. Composed, it is one pass. For large point sets, moving data costs more than the arithmetic, so this is often the larger saving.
- Batching becomes matrix multiplication. Stack all $N$ points as the columns of a $3\times N$ matrix $P$ and the whole job is the single product $MP$. Matrix multiplication is the most heavily optimized operation in computing (BLAS libraries, SIMD instructions, GPU tensor cores), so this runs close to the hardware's peak speed.
- One uniform code path. Rotation, scaling, shear and translation all become the same operation, so there is no branching on "what kind of transform is this?". GPUs are built around $4\times4$ matrix multiplies for exactly this reason, and undo, inverses and camera moves are all matrix operations too.
- Perspective comes free. Let the bottom row be something other than $0\ 0\ 1$ and divide by the last coordinate afterward: the same $4\times4$ machinery now does perspective projection, so a 3-D renderer's entire vertex pipeline is matrix multiplies plus one divide.
The honest limits: for a single transform applied once, the homogeneous form is not faster — it can cost a couple of extra additions, and well-written code skips multiplying by the constant bottom row. The gains come from composition, batching and uniformity, which is why they are largest in exactly the places that use them most: renderers, robot kinematics and point-cloud processing. In neural networks, absorbing the bias into the weight matrix is mostly bookkeeping, since libraries fuse the bias add into the multiply anyway.
5. Why every layer has a bias
A neural-network layer computes $Wx + b$ and then applies an activation such as ReLU. Without $b$ the layer is linear, and each neuron's boundary $w\cdot x = 0$ must pass through the origin — the Layer explorer shows how badly that can fail. The bias lets each boundary sit wherever the data needs it. In homogeneous form, $w\cdot x + b = [w,\ b]\cdot[x,\ 1]$: the bias is simply one more weight on a constant input of 1.
6. Affine combinations
A weighted average whose weights sum to 1, $\sum_i \lambda_i p_i$ with $\sum_i \lambda_i = 1$, is called an affine combination, and affine maps preserve it: transform the points and the average moves with them. That is why centroids and midpoints survive, why barycentric coordinates work inside triangles, and it describes the output of attention: softmax weights are positive and sum to 1, so each output is a weighted average of the value vectors.
Self check
Answer every question before checking.
