Computer graphics · foundation

2D affine transformations

A 2D affine transformation maps points with a linear part plus a translation, so it can move, rotate, scale, reflect, or shear shapes while preserving straight lines and parallelism.

Why it matters

UI rendering, animation, gesture coordinates, and hit testing repeatedly convert points between local and parent spaces. Understanding the combined matrix makes transform order and inverse mapping predictable instead of trial and error.

Mental model

How to reason about 2D affine transformations

Treat every point as a column vector [x, y, 1]. A 3×3 homogeneous matrix maps it to a new point; multiplying transform matrices composes several steps into one mapping, and changing their order usually changes the result.

Analogy

Imagine drawing on transparent sheets. Each sheet defines a coordinate space; moving, turning, or stretching one sheet changes every mark together, while stacking the sheets in a different order produces a different final alignment.

Interactive model

Build the matrix with your hands

Change one operation at a time. The ghost arrow stays in local space; the green arrow shows where the combined matrix maps it.

Local shapeMapped shapePoint A
xyA

Point mapping

A(60, 0) → (135.60, 7.74)

Preserved

Lines stay straight. Parallel edges stay parallel.

Start with a pattern

Apply operations in this order

Combined matrix

With column vectors, the operation on the right acts first.

1.06-0.4072.000.660.64-32.000.000.001.00

What to notice

Scale, then rotate, then move

Select Order matters, then switch the two order buttons without touching a slider. The numbers are identical, but the green arrow moves because matrix multiplication is not commutative.

Scale, then rotate, then move. Point A is now at x 135.60, y 7.74.

Examples

See the boundary, not just the happy path

Worked example · Map one point

[x′]   [a c tx] [x]
[y′] = [b d ty] [y]
[ 1]   [0 0  1] [1]

The upper-left 2×2 part applies rotation, scale, reflection, or shear. The final column adds translation, which is why homogeneous coordinates use the extra 1.

Worked example · Compose in a deliberate order

scale → rotate → translate
M = T × R × S

With column vectors, the rightmost matrix acts first. Scaling a local shape before moving it differs from moving first and then scaling the already translated coordinates.

Worked example · Paint a transformed Flutter child

Transform.rotate(
  angle: pi / 4,
  child: const Icon(Icons.navigation),
)

Flutter's Transform changes how its child is painted. More general combinations use a Matrix4, but the same local-to-parent coordinate-space model applies.

Useful contrast · Perspective is not affine

farther points appear smaller

A perspective projection can make parallel lines converge, so it is projective rather than affine. An affine mapping preserves parallel lines even when lengths and angles change.

Common mistakes

Misconceptions to remove early

Assuming transform order does not matter

Matrix multiplication is generally not commutative. Rotate-then-translate and translate-then-rotate can place the same shape in different positions because each step uses the coordinate space produced before it.

Mixing local and global coordinates

A point only has meaning relative to a coordinate space. Before comparing a pointer position with a transformed shape, map both into the same space, often by applying the inverse of the rendering transform.

Expecting every visual property to survive

Affine transforms preserve lines, parallelism, and ratios along a line. Non-uniform scaling and shear do not generally preserve lengths, angles, circles, or perpendicularity.

Quick check

Can you predict the result?

1. Which properties must every affine transformation preserve?
  • Straight lines and parallel lines remain straight and parallel
  • Every angle and length remains unchanged
  • Every circle remains a circle
Answer: Straight lines and parallel lines remain straight and parallel
2. For column vectors, what is the combined matrix for scale, then rotate, then translate?
  • T × R × S
  • S × R × T
  • T + R + S
Answer: T × R × S
3. Why is an inverse transform useful during hit testing?
Answer: It maps the pointer from a parent or global space back into the shape's local coordinate space for a direct containment test.

Keep building

Authoritative references

Make the idea retrievable.

Concepts are coming to Terminaster in the next update. You'll be able to study this one with spaced repetition, next to the commands where you use it.

Get Terminaster