What happens when your coordinate axes aren't at right angles?
Say you've got two directions in the plane, and . They're not parallel, so together they can still reach every point around them. But they lean into each other. Distances get warped. Angles lie to you. Every formula that quietly assumes "" and "" are perpendicular breaks the moment they aren't.
We want to fix that, without changing what the vectors can reach.
We want a new pair of vectors that span the same space but stand at a perfect right angle to each other. That's what the Gram-Schmidt process does. And it does the whole thing with one repeated trick: subtract the shadow.
What does it mean for a vector to "lean into" another?
Picture a flagpole standing straight up, and the sun directly overhead of some other vector, . The sun casts a shadow of straight down onto the flagpole's line.
That shadow is a real, measurable thing. It's the part of that already points in the flagpole's direction. We call it the projection of onto .
Drag around below and watch its shadow move along .
Drag the tip of b. The shadow it casts onto a is its projection.
Notice what happens at 90°. When is perpendicular to , the shadow shrinks to nothing. That makes sense, a vector that points straight up over a flagpole casts no shadow along it at all. Zero shadow is exactly what "perpendicular" means.
Now for the notation. We write the shadow, the projection of onto , as:
The dot product measures how much agrees with 's direction. Dividing by accounts for 's own length. Multiplying back by points the result back along the flagpole. Three moves, one shadow.
How do we make two vectors perpendicular?
Once you can compute a shadow, orthogonalizing two vectors is almost anticlimactic: subtract it.
Keep the first vector exactly as it is, call it . It becomes your first axis, the flagpole. Then take the second vector and strip out the part that already leans toward :
Whatever's left has, by construction, nothing pointing along anymore. It's exactly perpendicular. Every time, no matter where you started.
Try it with small numbers. Let and .
- ✓
Now drag in the visualizer below and watch snap to a right angle from , no matter where you drop it.
Drag v₂ anywhere. u₂ = v₂ − shadow always lands at exactly 90° from u₁.
That's the whole algorithm. Everything else is just doing this move more times.
What happens with three vectors, or thirty?
We just keep going. Repeat the same move, remove the shadow, once for every axis you've already built.
For a third vector , we subtract its shadow on and its shadow on :
Think about why both subtractions matter. If we only removed the shadow on , the result would be perpendicular to , but it might still lean toward . We have to strip out every direction we've already claimed before what's left counts as genuinely new.
Watch the process unfold step by step, in three dimensions this time.
Watch the shadow-removal step chain across a third vector.
Start: three independent vectors
For a fourth vector, you'd subtract three shadows. For a hundredth, ninety-nine. The pattern never changes, it just repeats.
Why go through all this trouble?
Because perpendicular, unit-length vectors, what we call an orthonormal basis, don't distort anything.
Once you have orthogonal vectors , the last step is trivial: shrink each one to length 1 by dividing by its own length.
Here's the payoff. Measure distances and angles using a skewed basis, and your ruler lies to you, a circle of "radius 1" in that basis stretches into an ellipse in reality. Measure using an orthonormal basis, and a circle stays a circle. Nothing gets stretched, squeezed, or tilted.
Drag the skew angle. The skewed basis warps the circle, the orthonormal one never does.
Slide the skew angle toward 90° and watch the amber shape (the skewed basis) collapse onto the dashed reference circle. Push it toward 0° or 180° and watch it thin into a needle. The emerald shape, built from the Gram-Schmidt orthonormal basis, never budges. It's always a perfect circle, no matter the angle you started with.
That's why Gram-Schmidt matters far outside a linear algebra homework set. It's the backbone of the QR decomposition, the numerical foundation under least-squares regression, and the reason a computer can trust its own answer when it solves a system with a thousand unknowns.
Putting it all together
For vectors , the full Gram-Schmidt process is:
Then normalize each one: .
The short version
Gram-Schmidt turns any set of independent vectors into a perpendicular one, without changing what they can reach. The tool doing all the work is the projection, the "shadow" one vector casts on another. Subtract that shadow and what remains is guaranteed perpendicular. Chain the subtraction across every vector you've already processed, and the whole set falls into place, axis by axis. Normalize the lengths at the end, and you're left with a basis that measures distance and angle honestly.
All visualizations are interactive React components running entirely in your browser, using nothing beyond React. The stepper animation uses requestAnimationFrame to interpolate between each stage of the algorithm.