Back to Articles

2026-11-07

Moving Shapes with Matrices

By Anthony Dito

Matrix multiplication is how digital art tools scale, move, and rotate shapes. Follow a square through each transformation and combine them all into one matrix.

In See Through the Matrix, we saw how multiplying RGBA colors by a 4 × 4 matrix can tint, mix, and reorder every color in an image. The same operation is also how digital art tools decide where things go. When you drag, scale, or rotate an item, a matrix multiplication is there.

Location is simpler than color. Instead of four channels, we only have x and y coordinates, so we just need a 2 × 2 matrix. Multiplying it against a point looks like this:

A two-by-two matrix with entries m11, m12, m21, m22 times the vector x, y equals m11 x plus m12 y over m21 x plus m22 y

To see how this works, let's work through an example of moving a square around. We start with a 3 × 3 square whose bottom-left corner is at the origin.

A 3 by 3 orange square on a grid with its bottom-left corner at the origin
The original 3 × 3 square, before any transformations. Its bottom-left corner is at (0, 0).

Scale

First, let's change the scale to make the square 2 units wide and 4 units tall. To do this, we multiply each x coordinate by 2/3 and each y coordinate by 4/3. These scale factors go on the diagonal of our matrix:

The matrix 2/3, 0, 0, 4/3 times x, y equals two thirds x and four thirds y

For example, the top-right corner moves from (3, 3) to (2, 4):

The scale matrix times the point 3, 3 equals the point 2, 4
The square scaled into a 2 by 4 rectangle, with the original square shown as a dashed outline
Scaling the original square by 2/3 horizontally and 4/3 vertically produces a 2 × 4 rectangle. The dashed outline shows the original square. The origin stays fixed.

Translation

To move the rectangle up and to the right we... Wait, with our current approach there is no way to move something left, right, up, or down. Every entry in a 2 × 2 matrix multiplies x or y, so there is nowhere to put a plain offset. We need something else.

The fix is a mathematical trick called homogeneous coordinates. To perform a translation, we need to add to the x and y components without scaling them. With homogeneous coordinates, we add another dimension, so our x and y become x, y, and z, with z being a throwaway value that is 1. Our matrices become 3 × 3, and the rightmost column is used to add to and subtract from the x and y components. Once done, we simply ignore z and everything works out.

To move our scaled rectangle 2 units to the right and 1 unit up, we put those offsets in the rightmost column:

A three-by-three translation matrix with 2 and 1 in the rightmost column times x, y, 1 equals x plus 2, y plus 1, 1

The bottom-left corner moves from (0, 0) to (2, 1), while the top-right corner moves from (2, 4) to (4, 5):

The translation matrix times the point 2, 4, 1 equals the point 4, 5, 1
The 2 by 4 rectangle moved 2 units right and 1 unit up, with its previous position shown as a dashed outline
The 2 × 4 rectangle translated 2 units right and 1 unit up. The dashed outline shows its previous position. Its size stays the same.

That works: using just the rightmost column, we can move our item without changing its scale or rotation.

Rotation around the center

What if we wanted to rotate the rectangle around its center? Let's try applying a 45° rotation to our translated rectangle. This matrix rotates counterclockwise using trigonometry:

The rotation matrix R with cosine 45 degrees, negative sine 45 degrees, sine 45 degrees, and cosine 45 degrees, which equals root 2 over 2 entries

The rectangle's center starts at (3, 3). Applying this matrix moves it:

R times the point 3, 3, 1 equals 0, 3 root 2, 1, approximately 0, 4.24, 1
The rectangle rotated 45 degrees around the origin, swinging its center from 3, 3 to about 0, 4.24
A 45° counterclockwise rotation around the origin. The dashed outline shows the rectangle before rotation, and the curved arrow follows its center. The center moves from (3, 3) to approximately (0, 4.24); a rotation around the rectangle's center would leave that point fixed.

This didn't work! The rectangle swung around the origin of the canvas, because the origin is the point around which rotation happens. The trick to rotating around the center is to move the center to the origin, do the rotation, and then move it back.

Let's return to the scaled 2 × 4 rectangle, before the translation. Its bottom-left corner is at (0, 0) and its center is at (1, 2). To rotate around that center, we apply three transformations in order.

First, move the center to the origin by subtracting 1 from every x coordinate and 2 from every y coordinate:

T1 is a translation matrix with negative 1 and negative 2 in the rightmost column

Next, apply the same 45° counterclockwise rotation as before, now with the rectangle centered at the origin:

R is the 45 degree rotation matrix with root 2 over 2 entries

Finally, move the center back to (1, 2) by adding the offsets we subtracted:

T2 is a translation matrix with 1 and 2 in the rightmost column
The rectangle moved so its center is at the origin, rotated 45 degrees, and moved back so its center returns to 1, 2
Rotating the scaled rectangle around its center in three steps: blue moves the center to the origin, purple rotates 45° counterclockwise, and orange moves it back. The dashed outline shows the original rectangle. The original and final rectangles share the center (1, 2).

The center follows (1, 2) → (0, 0) → (0, 0) → (1, 2). The combined transformation is T₂ · R · T₁: the matrix on the right acts first.

To see the points actually move, let's follow the bottom-left corner (0, 0) through each step. First, T₁ moves it so the center sits at the origin:

T1 times the point 0, 0, 1 equals negative 1, negative 2, 1

Then R rotates it around the origin:

R times the point negative 1, negative 2, 1 equals root 2 over 2, negative 3 root 2 over 2, 1

Finally, T₂ moves it back:

T2 times that point equals 1 plus root 2 over 2, 2 minus 3 root 2 over 2, 1, approximately 1.707, negative 0.121, 1

Putting it all together

As with colors, when we multiply all of the matrices together in reverse order and apply the result to our original square, we get the same end result as applying each step one after another. Why matrix composition works walks through the proof. This means that no matter how much you move your objects around, the program has to do the same amount of work.

To get the last result directly from our original 3 × 3 square, combine the scale S with T₁, R, and T₂ from the center rotation:

M equals T2 times R times T1 times S
M equals the matrix root 2 over 3, negative 2 root 2 over 3, 1 plus root 2 over 2; root 2 over 3, 2 root 2 over 3, 2 minus 3 root 2 over 2; 0, 0, 1

Rounded to three decimal places, this is:

M is approximately 0.471, negative 0.943, 1.707; 0.471, 0.943, negative 0.121; 0, 0, 1

For example, take the original square's top-right corner (3, 3):

M times the point 3, 3, 1 equals 1 minus root 2 over 2, 2 plus 3 root 2 over 2, 1, approximately 0.293, 4.121, 1

Running (3, 3) through all four matrices one at a time lands on the same point. Applying M once gives the same final rectangle as the full sequence, and the original bottom-left corner (0, 0) maps to (1.707, −0.121), the same position we found by following it step by step.

The original 3 by 3 square as a dashed outline and the final rotated 2 by 4 rectangle produced by the single composite matrix
The complete transformation in one step. The dashed outline is the original 3 × 3 square. Orange is the final 2 × 4 rectangle after scaling and a 45° rotation around its center.

Scaling, moving, and rotating all come down to the same compact operation. However many transformations you stack up, a single 3 × 3 matrix can apply them all at once.

Try it in BrushCue Python

The notebook used to generate these graphs includes the full workflow for scaling, translating, and rotating the rectangle.