The Cross Product & Working in 3D
Linear Algebra Fundamentals
Chapter 3 · The Cross Product & Working in 3D
Chapter 2's dot product takes two vectors and returns a single number. The cross product is a different kind of operation entirely: it takes two 3D vectors and returns a third vector — one that's perpendicular to both of the originals. It's specifically a 3D operation, which is itself worth understanding, not just the formula.
The Formula
For a = [a₁, a₂, a₃] and b = [b₁, b₂, b₃], the cross product is:
a × b = [a₂b₃ − a₃b₂, a₃b₁ − a₁b₃, a₁b₂ − a₂b₁]
It looks arbitrary at first, but there's a pattern: each output component skips the matching input index (the first output component has no a₁/b₁ in it, and so on), and the two products in each pair are subtracted in a "cross" pattern. Chapter 7's own determinant will give this same formula a cleaner, more memorable form once determinants are available.
The Right-Hand Rule
The direction of a × b is found with the right-hand rule: point your right hand's fingers along a, curl them toward b, and your thumb points in the direction of the result. This is also why order matters — the cross product is anti-commutative:
i × j = [0, 0, 1], but j × i = [0, 0, −1] — same axis, opposite direction.
Geometric Meaning: Perpendicular, With a Meaningful Length
Two things are true about a × b at once, and both matter in practice:
- Direction: it's perpendicular to both
aandb— confirmed by the fact that(a × b) · a = 0and(a × b) · b = 0always hold, using Chapter 2's own dot product as the perpendicularity test. - Magnitude:
|a × b| = |a| |b| sin(θ)— which is exactly the area of the parallelogram thataandbspan.
Worked example: a = [2, 1, 0], b = [1, 0, 2].
| Quantity | Value |
|---|---|
| a × b | [2, −4, −1] |
| (a × b) · a | 0 ✓ perpendicular to a |
| (a × b) · b | 0 ✓ perpendicular to b |
| |a × b| | √(2² + 4² + 1²) = √21 ≈ 4.583 |
| |a| |b| sin(θ) | √5 × √5 × 0.9165 ≈ 4.583 — an exact match |
Testing for Parallel Vectors
Since sin(θ) = 0 exactly when θ is 0° or 180°, the cross product of two parallel (or anti-parallel) vectors is always the zero vector, regardless of their lengths. This gives a direct, practical test: if a × b = [0, 0, 0], the two vectors point along the same line.
[0, 0, 0] is fragile — rounding error means "should be zero" often comes out as something like [1e-16, -3e-17, 0] instead. The practical version of this test checks whether the magnitude of the cross product is below a small tolerance, not whether it's exactly zero.
2D vs. 3D: There's No True 2D Cross Product
The cross product as defined above genuinely requires three dimensions — "perpendicular to both a and b" only pins down a unique direction (up to sign) when there's a third axis to be perpendicular into. In 2D, a lot of code still uses a "cross product," but it's really a shortcut scalar, not a true cross product:
a = [a₁, a₂] and b = [b₁, b₂], extending both into 3D with a zero third component ([a₁, a₂, 0]) and taking the real cross product leaves only a z-component: a₁b₂ − a₂b₁. That single number is what 2D code usually means by "the cross product" — it's really the z-component of the true 3D cross product, and its sign tells you whether b is a clockwise or counter-clockwise turn from a. Reusing Chapter 2's own worked vectors a = [3, 4], b = [1, 2]: a₁b₂ − a₂b₁ = 3×2 − 4×1 = 2, which matches extending both to [3, 4, 0] and [1, 2, 0] and computing the real cross product — [0, 0, 2].
Where This Shows Up: Surface Normals
In 3D graphics, a flat triangular face is usually stored as three corner points. To light that face correctly, the renderer needs its normal — a vector pointing straight out from the surface. That's computed by taking two of the triangle's edges as vectors and crossing them:
u = [2, 0, 0] and v = [0, 3, 0], u × v = [0, 0, 6] — pointing out of the page. But v × u = [0, 0, −6] — pointing straight into it. This is exactly why 3D modelling tools like Blender care about a face's winding order (the order its corner points are listed in): it determines which way u × v points, which determines which side of the surface is treated as the "front" for lighting and backface culling.
Cross Products in Code — NumPy
Hands-On Exercises
Compute e × f by hand for e = [1, -2, 3] and f = [2, 0, -1], showing each component's calculation. Then verify your result is genuinely perpendicular to both e and f by computing the two dot products.
Given g = [2, 4, -2] and h = [-1, -2, 1], use the cross product to determine whether they're parallel. Show the calculation, and separately confirm your conclusion by checking whether one vector is a scalar multiple of the other.
A triangular face has two edge vectors u = [2, 0, 0] and v = [0, 3, 0]. Compute the surface normal as u × v, then compute it the other order as v × u. Explain, in terms of the right-hand rule, why a 3D modelling tool listing this triangle's corner points in the opposite order would flip which side of the surface is treated as the front.
Chapter 3 Quick Reference
- Cross product:
a × b = [a₂b₃−a₃b₂, a₃b₁−a₁b₃, a₁b₂−a₂b₁]— a 3D-only operation returning a vector, not a scalar - Direction: perpendicular to both inputs, given by the right-hand rule; anti-commutative —
a × b = −(b × a) - Magnitude:
|a × b| = |a||b|sin(θ)= the area of the parallelogram spanned by a and b - A zero cross product (within floating-point tolerance) means the two vectors are parallel or anti-parallel
- There's no true 2D cross product — the "2D cross product" (
a₁b₂ − a₂b₁) is a scalar shortcut equal to the z-component of the 3D version - Surface normals in graphics are computed by crossing two edge vectors of a face; the order of the edges (winding order) determines which way the normal points
- Next chapter: Matrices — representation and basic operations