Cross Product
Summary
The cross product takes two vectors and produces a third vector that's perpendicular to both of them — pointing straight "out" of the plane the first two vectors define. Where the dot product (see [[CON-0048]]) answers "how aligned are these two directions" with a single number, the cross product answers "what direction is perpendicular to both of these" with an entirely new vector, which is exactly what's needed for computing surface normals, turning direction (left vs. right), and rotation axes.
Why This Matters
Some gameplay questions can only be answered with an actual perpendicular direction, not a single alignment number — which way does a flat surface face, should the character turn left or right to reach a target, what axis should an object rotate around to align with a given orientation. The dot product can tell you "these two vectors aren't aligned," but it cannot tell you which direction is perpendicular to both — only the cross product produces that. Recognizing which of the two operations a given problem actually needs (a number vs. a new direction) is the core skill this Concept builds.
Mental Model
The cross product is a screw's turning axis, not the amount it turned. Picture two sticks laid flat on a table, pointing in different directions. Imagine screwing them together with a bolt that goes straight up through the table at the point where they'd rotate into each other — the bolt's axis, pointing straight up out of the table, is the cross product's direction. Which way "up" actually is (up through the table, or down through it) depends on which stick you consider first — swap the order, and the bolt points the opposite way.
Core Explanation
- Produces a new vector, not a number. Unlike the dot product,
cross(A, B)returns a fullVector3, perpendicular to bothAandB— this distinction is the single most important thing to remember when choosing between the two operations. - Only meaningfully defined in 3D (and a simplified 2D variant). The "true" cross product exists for 3D vectors; some engines offer a 2D cross-product-like operation that returns a single number representing signed area/rotation direction instead of a vector, since a true perpendicular in 2D would need a third dimension to point into.
- Order matters — the result flips sign if the inputs are swapped.
cross(A, B) = -cross(B, A)— reversing the order of the two input vectors produces a perpendicular vector pointing the exact opposite way, which is why cross product order needs to be chosen deliberately, not arbitrarily. - The result's length relates to how "unaligned" the two inputs are. Two nearly-parallel vectors produce a very short cross product result (close to zero length); two perpendicular vectors produce the longest possible result for their given lengths — the mirror image of how the dot product behaves.
Syntax / Theory
Engine-neutral (formula)
cross(A, B) = (Ay*Bz - Az*By, Az*Bx - Ax*Bz, Ax*By - Ay*Bx)
Result is perpendicular to both A and B.
cross(A, B) = -cross(B, A) — order matters.
C# (Unity)
Vector3 right = Vector3.Cross(Vector3.up, transform.forward); // A perpendicular "right" direction.
C++ (Unreal)
FVector Right = FVector::CrossProduct(FVector::UpVector, GetActorForwardVector());
Both engines expose Cross/CrossProduct directly, taking two
Vector3/FVector inputs and returning a new perpendicular vector — the
formula above is rarely written by hand in practice, but understanding it
clarifies why order matters and why the result is itself a direction, not
a number.
Practical Example
Deriving a consistent "right" direction from an object's forward direction and the world's up direction is a direct, common cross-product use.
Vector3 forward = transform.forward;
Vector3 worldUp = Vector3.up;
Vector3 right = Vector3.Cross(worldUp, forward).normalized;
This produces a "right" vector that's always perpendicular to both the object's facing direction and the world's up axis — useful for constructing a full local coordinate frame (forward, right, up) from just one known direction.
Common Mistakes
- Using the cross product where the dot product was actually needed
(or vice versa). Reaching for
Crossto answer an alignment question produces a perpendicular vector, not the alignment number the question actually needed — the two operations are not interchangeable. - Not accounting for cross product order. Computing
cross(A, B)whencross(B, A)was intended produces a result pointing the exact opposite direction — a subtle bug that flips left/right or inside/outside logic without an obvious error. - Applying the cross product formula to 2D vectors directly. A true 3D cross product needs three components per input; a 2D cross-product-style operation returns a single scalar (signed area) instead of a vector, and conflating the two produces a type mismatch or a nonsensical result.
- Forgetting to normalize the result when only the direction (not the magnitude) is needed. The cross product's raw length depends on both input vectors' lengths and the angle between them — code that only wants "which way is perpendicular," not "how much," should normalize the result.
Game Development Example
A path-following AI determines whether to steer left or right toward the next waypoint using the sign of a cross product's vertical component.
public class PathSteering : MonoBehaviour
{
float GetSteerDirection(Vector3 forward, Vector3 directionToWaypoint)
{
Vector3 cross = Vector3.Cross(forward, directionToWaypoint);
return cross.y > 0 ? 1f : -1f; // Positive Y-component means "turn right," negative means "turn left."
}
}
The cross product's Y component's sign directly encodes which side of the forward direction the waypoint is on — a common, efficient technique for 2D-plane steering decisions in a 3D world with a consistent up axis.
Best Practices
- Reach for the cross product specifically when a perpendicular direction is needed (surface normals, turning axes, constructing a coordinate frame) — use the dot product for alignment/angle questions instead.
- Be deliberate and consistent about input order, since swapping it reverses the result's direction.
- Normalize the cross product's result when only the perpendicular direction matters, not its magnitude.
- Remember the true (3D) cross product and a 2D "cross-product-like" scalar operation are related but distinct — check which one a given engine API actually provides before using it.
Exercises
- Compute
cross((1, 0, 0), (0, 1, 0))by hand using the formula, and confirm it points along the third axis,(0, 0, 1). - Take the
PathSteeringexample and swap the arguments toVector3.Cross, then explain how the steering direction output changes as a result. - You're building a flight-sim aircraft that needs a full local orientation frame (forward, right, up) derived from just its current forward direction and the world's up axis. Decide how to use the cross product (possibly twice) to construct all three consistently, and justify your approach.
- Research how the cross product is used to compute a triangle's surface normal from its three vertices, and explain, in your own words, which two vectors (derived from the vertices) are crossed to produce it.
Related Concepts
- Dot Product — the other fundamental two-vector operation; understanding both together clarifies when each is the right tool (a number vs. a perpendicular direction).
- Direction Vectors — cross product inputs are frequently direction vectors (an object's forward, a world axis), and the result is itself commonly normalized into a new direction vector.
- Coordinate Systems — cross products are the standard way to construct a consistent local coordinate frame (forward/right/up) from a starting direction, directly tying into how coordinate axes relate to one another.
Further Reading
KNOWLEDGE_SCHEMA.md— GDKB's concept maturity ladder and cross-linking rules, which this document follows.- Unity documentation — Vector3.Cross: https://docs.unity3d.com/ScriptReference/Vector3.Cross.html
- Unreal Engine documentation — FVector::CrossProduct: https://dev.epicgames.com/documentation/en-us/unreal-engine/API/Runtime/Core/Math/FVector