Coordinate Spaces and Handedness

To say where anything is in 3-D you need three axes — x, y, z — meeting at an origin. Place a point and its coordinates are how far you walk along each axis. So far, so harmless. The trap is that there are two incompatible ways to orient those three axes, and they disagree on which direction "out of the screen" even is.

Right-handed vs left-handed, line by line

Fix x pointing right and y pointing up. The only freedom left is where z goes — and the cross product decides it for us. By definition the cross product of the first two basis vectors gives the third, and the right-hand rule fixes its direction.

Step 1 — curl from x to y with your right hand. Point your right fingers along +x, curl them toward +y; your thumb points out of the screen, toward you. The cross product agrees:

\hat{x} \times \hat{y} = +\hat{z} \qquad (\text{right-handed: } +z \text{ comes toward you}).

Step 2 — do it again with your left hand. Same curl from +x to +y, but the left thumb points into the screen, away from you. To keep the cross-product rule, the whole frame flips the sign of z:

\hat{x} \times \hat{y} = -\hat{z} \qquad (\text{left-handed: } +z \text{ goes into the screen}).

Step 3 — read off the consequence. The two frames differ by a single sign flip on one axis, a mirror reflection. There is no rotation that turns one into the other — a left hand is not a rotated right hand. So every quantity built from the cross product (a surface normal, a torque, "which way is out") points the opposite way between the two conventions.

(\vec{a} \times \vec{b})_{\text{left}} = -\,(\vec{a} \times \vec{b})_{\text{right}}.

Step 4 — and the engines really do disagree. This is not a textbook nicety. OpenGL (and Maya, and the usual maths convention) is right-handed; DirectX and Unity are left-handed. Port a mesh between them without flipping a z and it comes out mirrored.

Two more conventions that bite

Handedness is the famous one, but two cousins cause just as many late nights.

The "up" axis. Even among right-handed frames, engines disagree on which axis points up. Many graphics engines are y-up (y is the sky); many modelling tools and CAD systems are z-up (z is the sky, y goes into the distance). Import a z-up model into a y-up engine and it lies on its back.

Row vs column vectors. Is a vector a tall column the matrix multiplies on the right (M\vec{v}, the OpenGL/maths convention), or a wide row it multiplies on the left (\vec{v}\,M, the DirectX convention)? The two store the transpose of each other's matrices, and chain transforms in the opposite order. Mix them up and your rotations compose backwards.

A 3-D coordinate frame is three axes \hat{x}, \hat{y}, \hat{z} through an origin. Its conventions are not universal:

When a handedness mismatch slips through, the symptoms are weirdly specific. Models come out mirrored — text on a sign reads backwards, a character's holster jumps to the wrong hip. Triangle winding order reverses, so the engine thinks every front face is a back face: surfaces turn inside-out, and either the whole model vanishes (back faces culled) or its insides render while its outsides don't.

Lighting goes haywire too, because the surface normal — a cross product — now points into the wall: lit faces go dark and shadowed faces glow. The usual fix is a single reflection — negate the z column of the conversion matrix and reverse the winding — applied once, consistently, at the import boundary. Apply it twice and you are back where you started, which is its own special kind of bug.