Linear Algebra for Graphics

A hands-on introduction to the vectors and matrices behind computer graphics. Play with the arrows and sliders.

What is a vector?

A vector describes a length and a direction. In a 2D coordinate plane with an x-axis and a y-axis, the vector (43)\begin{pmatrix}4\\3\end{pmatrix} means 4 units in the x direction and 3 units in the y direction.

Diagram
43v
Playground: drag or type to change the vector
|v| = 5.00

Unit vectors & normalization

Often you care about direction, not length. Dividing a vector by its magnitude produces a unit vector of length 1 in the same direction:

v^=v∣v∣\hat{\mathbf{v}}=\dfrac{\mathbf{v}}{|\mathbf{v}|}

Unit vectors show up everywhere in graphics: surface normals, light directions, camera axes, and ray directions. The dashed circle below has radius 1; the solid arrow always lands on it.

Diagram
vv̂
Playground: drag or type to change v. Solid arrow is the unit vector
|v| = 5.00
v^\hat{v} = (0.80, 0.60)

Addition & subtraction

For a=(axay)\mathbf{a}=\begin{pmatrix}a_x\\a_y\end{pmatrix} and b=(bxby)\mathbf{b}=\begin{pmatrix}b_x\\b_y\end{pmatrix}, add the corresponding components:

a+b=(ax+bxay+by)\mathbf{a}+\mathbf{b}=\begin{pmatrix}a_x+b_x\\a_y+b_y\end{pmatrix}

Subtraction works the same way, with the second vector negated: a−b=a+(−b)\mathbf{a}-\mathbf{b}=\mathbf{a}+(-\mathbf{b}).

Diagram
aba+b
Playground: drag or type to change a and b
a + b = (4.00, 4.00)

Dot product

The dot product of two vectors gives a scalar. It measures how much one vector points in the direction of another.

a⋅b=axbx+ayby\mathbf{a}\cdot\mathbf{b}=a_xb_x+a_yb_y

It also relates to the angle between the vectors, a⋅b=∣a∣∣b∣cos⁡θ\mathbf{a}\cdot\mathbf{b}=|\mathbf{a}||\mathbf{b}|\cos\theta, and to the signed length of the projection of a onto b, d=a⋅b∣b∣d=\dfrac{\mathbf{a}\cdot\mathbf{b}}{|\mathbf{b}|}.

Diagram
abd
Playground: drag or type to change a and b. The gray arrow is the projection of a onto b
a · b = 11.00
θ = 42.27°
d = 3.05

Projection

The orthogonal projection of a\mathbf{a} onto b\mathbf{b} is the shadow of a\mathbf{a} on the line spanned by b\mathbf{b}. It is the part of a\mathbf{a} that lies parallel to b\mathbf{b}:

projba=a⋅bb⋅b b\mathrm{proj}_{\mathbf{b}}\mathbf{a}=\dfrac{\mathbf{a}\cdot\mathbf{b}}{\mathbf{b}\cdot\mathbf{b}}\,\mathbf{b}

What is left over is the rejection, perpendicular to b\mathbf{b}: a−projba\mathbf{a}-\mathrm{proj}_{\mathbf{b}}\mathbf{a}. Lighting, constraints, and sliding along a surface all use this split.

Diagram
abproj
Playground: gray arrow is projection; dashed is rejection
proj = (4.00, 0.00)
rej = (0.00, 3.00)

Cross product

The cross product takes two vectors, a and b, and produces a third vector perpendicular to both, following the right-hand rule. In 2D we only see its z-component: a signed number equal to the area of the parallelogram the two vectors span.

axby−aybxa_xb_y-a_yb_x

A positive value means b is counterclockwise from a; negative means clockwise.

Diagram
abarea
Playground: drag or type to change a and b
a × b = 8.00
counterclockwise

Matrices

A matrix is an array of numbers with rules for multiplying vectors and other matrices. In graphics, each column is where a basis vector lands: the first column is the image of (1,0)(1,0), the second of (0,1)(0,1).

Matrix multiplication composes transforms. Order matters: ABAB means “apply BB first, then AA” (right to left). In general AB≠BAAB\neq BA.

AB=(abcd)(efgh)=(ae+bgaf+bhce+dgcf+dh)AB=\begin{pmatrix}a&b\\c&d\end{pmatrix}\begin{pmatrix}e&f\\g&h\end{pmatrix}=\begin{pmatrix}ae+bg&af+bh\\ce+dg&cf+dh\end{pmatrix}
Diagram
AB ≠ BA
Playground: A = rotation, B = scaling along x. Toggle the order
θ (A = rotation)
slidernumber input
sx (B = scaling along x)
slidernumber input
A·B
1.23-0.641.030.77

Rotation

To rotate a vector by θ, picture rotating the basis vectors and watching where they land. The x-axis unit vector (10)\begin{pmatrix}1\\0\end{pmatrix} becomes (cos⁡θsin⁡θ)\begin{pmatrix}\cos\theta\\\sin\theta\end{pmatrix}, and the y-axis unit vector (01)\begin{pmatrix}0\\1\end{pmatrix} becomes (−sin⁡θcos⁡θ)\begin{pmatrix}-\sin\theta\\\cos\theta\end{pmatrix}. Those two new columns are the rotation matrix:

R(θ)=(cos⁡θ−sin⁡θsin⁡θcos⁡θ)R(\theta)=\begin{pmatrix}\cos\theta & -\sin\theta\\\sin\theta & \cos\theta\end{pmatrix}

The first column is where the new x-axis points; the second is where the new y-axis points. Multiplying a vector by R gives the rotated vector:

R(θ)(xy)=(cos⁡θ⋅x−sin⁡θ⋅ysin⁡θ⋅x+cos⁡θ⋅y)R(\theta)\begin{pmatrix}x\\y\end{pmatrix}=\begin{pmatrix}\cos\theta\cdot x-\sin\theta\cdot y\\\sin\theta\cdot x+\cos\theta\cdot y\end{pmatrix}
Diagram
θx'y'
Playground: move the slider or type θ
θ (vector shown dashed is (42)\begin{pmatrix}4\\2\end{pmatrix})
slidernumber input
cos θ = 0.87, sin θ = 0.50
result = (2.46, 3.73)

Scale

Scaling works the same way. To stretch x by 3 and shrink y to half, the new x-axis unit vector becomes (30)\begin{pmatrix}3\\0\end{pmatrix} and the new y-axis unit vector becomes (00.5)\begin{pmatrix}0\\0.5\end{pmatrix}:

S=(sx00sy)S(xy)=(sx⋅xsy⋅y)S=\begin{pmatrix}s_x & 0\\0 & s_y\end{pmatrix}\qquad S\begin{pmatrix}x\\y\end{pmatrix}=\begin{pmatrix}s_x\cdot x\\s_y\cdot y\end{pmatrix}
Diagram
unit squarescaled
Playground: move the sliders or type sx, sy
sx
slidernumber input
sy
slidernumber input

Shear

Shear slides one axis along the other. A horizontal shear (kxk_x) keeps heights fixed and pushes xx by an amount proportional to yy. Vertical shear (kyk_y) does the opposite. Together they form the matrix:

H=(1kxky1)H(xy)=(x+kxykyx+y)H=\begin{pmatrix}1 & k_x\\k_y & 1\end{pmatrix}\qquad H\begin{pmatrix}x\\y\end{pmatrix}=\begin{pmatrix}x+k_xy\\k_yx+y\end{pmatrix}

Shear is still a linear map (the origin stays put), but it is not a pure rotation or scaling. Reflection is related: flipping an axis is equivalent to applying a negative scale, as shown in the Scale playground.

Diagram
originalsheared
Playground: move the sliders or type kx, ky
kx (horizontal)
slidernumber input
ky (vertical)
slidernumber input

Translation

Translation shifts every point by a fixed offset: a=(12)\mathbf{a}=\begin{pmatrix}1\\2\end{pmatrix} translated by (11)\begin{pmatrix}1\\1\end{pmatrix} lands at (23)\begin{pmatrix}2\\3\end{pmatrix}.

Unlike rotation and scaling, translation cannot be written as a matrix multiplied by a 2D vector: there is no matrix M for which M(xy)M\begin{pmatrix}x\\y\end{pmatrix} produces (x+txy+ty)\begin{pmatrix}x+t_x\\y+t_y\end{pmatrix} for every x and y. Homogeneous coordinates solve this problem.

Diagram
a = (1, 2)a + t = (2, 3)t
Playground: move the sliders or type tx, ty
tx
slidernumber input
ty
slidernumber input

Homogeneous coordinates

To fold translation into matrix multiplication, we add an extra dimension. A 2D vector (xy)\begin{pmatrix}x\\y\end{pmatrix} becomes (xy1)\begin{pmatrix}x\\y\\1\end{pmatrix}, and translation becomes:

T=(10tx01ty001)T(xy1)=(x+txy+ty1)T=\begin{pmatrix}1&0&t_x\\0&1&t_y\\0&0&1\end{pmatrix}\quad T\begin{pmatrix}x\\y\\1\end{pmatrix}=\begin{pmatrix}x+t_x\\y+t_y\\1\end{pmatrix}

Rotation and scaling extend the same way: add a third row and column that pass the extra coordinate through unchanged:

R=(cos⁡θ−sin⁡θ0sin⁡θcos⁡θ0001)S=(sx000sy0001)R=\begin{pmatrix}\cos\theta&-\sin\theta&0\\\sin\theta&\cos\theta&0\\0&0&1\end{pmatrix}\qquad S=\begin{pmatrix}s_x&0&0\\0&s_y&0\\0&0&1\end{pmatrix}

Now every affine transformation, including rotation, scaling, and translation, is represented by a 3×3 matrix. These transformations all compose through ordinary matrix multiplication.

Inverse transforms

Every nonsingular transform has an inverse that undoes it. Invert a translation with −t-t, a rotation with −θ-\theta, and a nonzero scale with 1/s1/s. For a rotation matrix, the inverse is simply the transpose: R−1=RTR^{-1}=R^{\mathsf{T}}.

R(θ)−1=R(−θ)=(cos⁡θsin⁡θ−sin⁡θcos⁡θ)=R(θ)TR(\theta)^{-1}=R(-\theta)=\begin{pmatrix}\cos\theta&\sin\theta\\-\sin\theta&\cos\theta\end{pmatrix}=R(\theta)^{\mathsf{T}}

For a composite M=SRTM=SRT, the inverse reverses the order: M−1=T−1R−1S−1M^{-1}=T^{-1}R^{-1}S^{-1}. Apply MM, then M−1M^{-1}, and you return to the original coordinates.

Playground: green is M·shape; orange is M⁻¹ applied to the green result
tx
slidernumber input
ty
slidernumber input
θ
slidernumber input
sx
slidernumber input
sy
slidernumber input
M⁻¹
0.550.48-3.00-0.380.68-2.000.000.001.00

Determinant

The determinant of a 2×2 matrix is the signed area of the parallelogram formed by its columns. If M=(abcd)M=\begin{pmatrix}a&b\\c&d\end{pmatrix}, then:

det⁡M=ad−bc\det M=ad-bc

A positive value means orientation is preserved (a counterclockwise basis stays counterclockwise). A negative value means the shape is flipped by a reflection. The absolute value tells us how much the matrix scales area. Zero means the matrix collapses space onto a line.

Diagram
area = det
Playground: try negative sx to flip orientation. Fill turns orange when det < 0
sx
slidernumber input
sy
slidernumber input
kx (shear)
slidernumber input
det M = 1.80
orientation preserved

Putting it together

Suppose a table asset must be transformed. First translate it by (txty)\begin{pmatrix}t_x\\t_y\end{pmatrix}, then rotate it counterclockwise by θ, and finally scale it by sxs_x and sys_y. Transformations apply from right to left, so the combined matrix is:

M=S⋅R(θ)⋅TM=S\cdot R(\theta)\cdot T

Multiply the three matrices once in composition order, with translation innermost because it is rightmost. Reuse that single M for every vertex of the table, no matter how complex the mesh.

Playground: move the sliders or type values. The dashed rectangle is the original table; the vertex (12)\begin{pmatrix}1\\2\end{pmatrix} is marked before and after.

tx
slidernumber input
ty
slidernumber input
θ
slidernumber input
sx
slidernumber input
sy
slidernumber input
M = S·R(θ)·T
1.73-1.004.660.751.308.950.000.001.00
vertex (1, 2) → (4.39, 12.29)

Loading 3D sections…

Next: Part II: Viewing