Cross product
a×b gives a vector perpendicular to both a and b. Its length equals the area of the parallelogram they span, twice the triangle area.
Math
Geometric definition (coordinate-free — direction + magnitude):
where is the unit vector perpendicular to both a and b, direction given by the right-hand rule. This form makes the area fact obvious for free: is exactly the parallelogram-area formula (two sides times the sine of the angle between them).
Why isn’t circular: is not solved for from this equation, it’s determined independently, straight from the right-hand rule applied to a and b (point fingers along a, curl toward b, thumb gives ) before the equation is ever evaluated. This works because “perpendicular to a” alone is a whole plane of directions, but “perpendicular to both a AND b” (assuming they’re not parallel) narrows that down to a single line through the origin, i.e. exactly two opposite unit vectors. The right-hand rule is just the convention that picks one of those two — there’s no unknown left to solve, is fixed before you plug numbers in.
Component form (equivalent, no angle needed — what you actually compute with):
Same definition, two views: the geometric form is for reasoning about what the result means (perpendicular vector, area); the component form is for computing it directly from coordinates without ever solving for θ.
Geometric meaning: the result is the unique (up to sign) vector perpendicular to both inputs, direction given by the right-hand rule (curl fingers from a to b, thumb points along a×b).
What the result means:
- Direction → the surface normal of the plane a and b lie in
- Length → area of the parallelogram spanned by a and b ( the triangle area if a,b are two edges of a triangle)
- Length = 0 → a and b are parallel or antiparallel (or one is the zero vector) — degenerate, no unique perpendicular direction exists
- For 2D vectors (), only the z-component survives:
its sign tells you whether rotating from a to b (short way) is CCW () or CW ()
Anticommutative: — swap the operand order, the sign flips.
Code
glm::vec3 edge1 = v1 - v0;
glm::vec3 edge2 = v2 - v0;
glm::vec3 faceNormal = glm::normalize(glm::cross(edge1, edge2));
float triArea = glm::length(glm::cross(edge1, edge2)) * 0.5f;
Uses in graphics
- Computing a triangle/face normal from two of its edges (above)
- Back-face culling — sign of the 2D cross product (winding order test)
- Point-in-triangle test: a point is inside if the cross product of each edge with (point - vertex) has consistent sign for all three edges
- Building an orthonormal basis / tangent space (TBN matrix) for normal mapping: bitangent = cross(normal, tangent)
- Physics: torque = r × F, angular momentum, angular velocity direction
Gotchas
- Order matters: — swapping two vertices in a winding-order or normal calculation flips the sign/direction.
- Length tells you area/degeneracy, not orientation — a zero-length result says the inputs are collinear, it doesn’t tell you anything about front/back-facing or CW/CCW.