Core Idea
The cross product takes two 3D vectors and returns a new vector, perpendicular to both. Its length is the area of the parallelogram the inputs span. It exists only in 3D (and, as a mathematical curiosity, 7D).
cross(a, b) = (a.y·b.z − a.z·b.y,
a.z·b.x − a.x·b.z,
a.x·b.y − a.y·b.x)
|cross(a, b)| = |a| · |b| · sin(θ)
Everything in that formula is visible in the machine above: the perpendicular result, the shaded area, the vanishing at sin(0) when you drag the vectors parallel — and the flip when you swap the order:
- Anti-commutative:
cross(a, b) = −cross(b, a). Order decides which way the result points. - Right-hand rule: fingers along
a, curl towardb— the thumb iscross(a, b).
What It’s For
| Use case | Construction |
|---|---|
| Surface normal of a triangle | cross(edge1, edge2) — see normals |
| Camera basis (“up”) | right = cross(forward, worldUp), then up = cross(right, forward) — the heart of lookAt |
| Triangle facing / winding | sign of the projected cross — demo below |
| Triangle area | ` |
| Align an object to terrain | cross look-direction with the surface normal, then cross again — orthonormalization |
| Rotation axis / torque | cross(r, F) in physics |
| TBN matrix (normal mapping) | bitangent = cross(normal, tangent) |
The pattern in the middle rows: cross twice and you’ve built a coordinate system. Given any one reliable direction, two cross products manufacture the other two axes of a clean basis — see coordinate spaces.
Winding Order: A Triangle Knows Its Front
Mesh data never stores which side of a triangle is the front — it’s implied by the order of the vertices, and the cross product extracts it. Drag a vertex through the opposite edge and watch the face flip:
This is why vertex order in mesh data is a convention that must never be mixed: the GPU uses exactly this test to cull back faces — by default, half of every closed mesh is skipped before shading. See meshes.
Handedness
The cross product defines the handedness of a coordinate system: X × Y = Z in a right-handed system (math, OpenGL, Three.js), X × Y = −Z in a left-handed one (some engines). Neither is wrong — but mixing them inverts normals, rotations, and culling all at once. Pick one and stay consistent.
Connections
The dot product and cross product are complementary questions about the same pair of vectors: how aligned are they? (scalar, cos θ) versus what’s perpendicular to their plane? (vector, sin θ). Normals are the cross product’s most direct product; coordinate spaces shows the basis-building recipe in full; and camera-path frames (Frenet frames) rebuild that basis at every point along a curve.