How do you compute the orthogonal projection of one vector b onto another vector a?
answer
- split b into along-a and perpendicular
- the residual dots to zero
- denominator is a dot a
- scalar version divides by the length once
- unit a makes it just a dot b
basics
~20 sThe projection of b onto a is (a . b / a . a) times a: scale a by the dot product of a and b over a with itself. The residual, b minus that projection, is perpendicular to a.
solid answer
~50 sProject by scaling `a` to reach the closest point on the line through `a`: `proj_a(b) = ((a . b) / (a . a)) * a`. The denominator is `a . a = ||a||^2`, not `||a||` — it falls straight out of solving `a . (b - t*a) = 0` for `t`. With `a = (3, 0)` and `b = (2, 4)`: `a . b = 6`, `a . a = 9`, so the scalar is `2/3` and the projection is `(2, 0)`. The residual `b - proj_a(b) = (0, 4)` dots with `a` to give 0, exactly as the algebra guarantees. The related **scalar** projection `(a . b) / ||a|| = 2` is the signed length of that projection. If `a` has unit length the formula reduces to `(a . b) * a`; if `a` is the zero vector the projection is undefined.
go deeper
Be ready to state the formula and apply it to small integer vectors without hesitating over the denominator. Sketching the shadow picture alongside the arithmetic shows you understand what you computed.
Expect to derive it: set the dot product of a with the residual to zero and solve for the scalar. Explaining why the squared length appears is the whole point of the question at this tier.
Talk through the decomposition into parallel and perpendicular parts, the fact that squared lengths add, and the degenerate cases — orthogonal inputs, a zero target vector, and rescaled targets that change nothing.
Frame projection as the general move of splitting a quantity into an explained part and a remainder, and be prepared to argue why the orthogonality of the remainder is the property that makes the split meaningful rather than arbitrary.
## What a projection is Projecting `b` onto `a` means splitting `b` into two pieces: the part that lies along the direction of `a`, and the part that has nothing to do with `a`. The first piece is the **vector projection**, the second is the **residual** or perpendicular component. The defining property is that the residual is orthogonal to `a`. That is not a bonus fact — it is what makes the projection the closest point to `b` on the line through `a`. ## Deriving the formula Any point on the line through the origin in the direction of `a` has the form `t * a` for some scalar `t`. We want the `t` that makes `b - t*a` perpendicular to `a`. Perpendicular means the dot product vanishes: `a . (b - t*a) = 0` `a . b - t * (a . a) = 0` `t = (a . b) / (a . a)` So the vector projection is `proj_a(b) = ((a . b) / (a . a)) * a` and since `a . a = ||a||^2`, the same formula is often written `((a . b) / ||a||^2) * a`. Note carefully that the denominator is the **squared** length. Writing `||a||` there is the single most common slip, and it silently changes the answer whenever `a` is not a unit vector. An equivalent reading: `proj_a(b) = (b . u) * u`, where `u = a / ||a||` is the unit vector in the direction of `a`. The quantity `b . u = (a . b) / ||a||` is the **scalar projection** — a signed number giving how far along `u` you travel. Multiplying it by `u` turns that number back into a vector. Keeping the scalar and vector versions straight matters, because interviewers ask for one and candidates hand back the other. ## A concrete case Let `a = (3, 0)` and `b = (2, 4)`. - `a . b = 3*2 + 0*4 = 6` - `a . a = 9`, so `t = 6/9 = 2/3` - `proj_a(b) = (2/3) * (3, 0) = (2, 0)` - residual `r = b - proj_a(b) = (2, 4) - (2, 0) = (0, 4)` - check: `a . r = 3*0 + 0*4 = 0`, so the residual really is orthogonal to `a` Here `a` points along the horizontal axis, so the projection just keeps the horizontal coordinate of `b` and the residual keeps the vertical one. The scalar projection is `6 / 3 = 2`, which matches the length of `(2, 0)`. The geometry also reproduces the cosine: `cos(theta) = (a . b) / (||a|| * ||b||) = 6 / (3 * sqrt(20))`, about 0.447, and `||b|| * cos(theta) = sqrt(20) * 0.447 = 2` — the length of a projection is always `||b|| * |cos(theta)|`. ## Properties worth naming **Direction, not length, of the target matters.** Replacing `a` with `5a` leaves the projection unchanged: the numerator picks up a 5 and the denominator picks up 25, and the extra `a` in front supplies the missing factor. Projection depends only on the line that `a` spans. **Idempotence.** Projecting an already-projected vector again onto `a` returns the same vector: it is already on the line, so there is nothing left to remove. **Orthogonal inputs give zero.** If `a . b = 0`, the projection is the zero vector and the residual is all of `b`. Geometrically, `b` casts no shadow on `a`. **Asymmetry.** `proj_a(b)` and `proj_b(a)` are different vectors — they even live on different lines. Ask which vector you are projecting onto before computing. **Degenerate input.** If `a` is the zero vector, `a . a = 0` and the projection is undefined. There is no direction to project onto. **Length bound.** Since `||proj_a(b)|| = ||b|| * |cos(theta)|` and `|cos(theta)| <= 1`, the projection is never longer than `b` itself. Equality holds exactly when `b` already lies along `a`. ## The decomposition view The cleanest way to hold all of this is as a decomposition: `b = proj_a(b) + r`, with `proj_a(b)` parallel to `a` and `r` perpendicular to `a` The two pieces are orthogonal to each other, so their squared lengths add: `||b||^2 = ||proj_a(b)||^2 + ||r||^2`. In the worked example, `||b||^2 = 20`, `||proj||^2 = 4`, `||r||^2 = 16`, and indeed `4 + 16 = 20`. This single-vector projection is the atom that larger constructions are built from — orthogonalising a set of vectors, for instance, repeatedly subtracts projections until nothing parallel remains.
- What is the difference between the scalar projection and the vector projection of b onto a?The scalar projection is `(a . b) / ||a||`, a signed number saying how far along the direction of `a` you travel — negative when the angle exceeds 90 degrees. The vector projection multiplies that number by the unit vector `a / ||a||`, giving an actual vector on the line through `a`. Same information, different type.
- Why is a . a in the denominator rather than the length of a?Two divisions by `||a||` are needed and they combine. One turns `a` into a unit direction; the other converts the dot product `a . b` into a coordinate along that unit direction. Formally it drops out of solving `a . (b - t*a) = 0` for `t`, which gives `t = (a . b) / (a . a)`. Using `||a||` instead is only correct when `a` already has unit length.
- What does the projection look like when a and b are orthogonal?It is the zero vector. Orthogonality means `a . b = 0`, so the scalar multiplier is 0 and nothing of `b` lies along `a`. The residual is then all of `b`, and the decomposition `b = projection + residual` degenerates to `b = 0 + b`.
- Does replacing a with 5a change the projection of b onto it?No. The numerator `a . b` gains a factor of 5, the denominator `a . a` gains 25, and the trailing `a` supplies another 5, so the factors cancel exactly. Projection depends only on the line that `a` spans, not on how long `a` happens to be — which is why you may normalise `a` freely first.
The projection is the shadow that b casts on the line through a when the light shines exactly perpendicular to that line. The residual is the height of b above the line, which the shadow cannot see.
saying these in an interview costs you the question
- Divides by the norm of a instead of a dot a
- Projects onto b when asked to project onto a
- Claims the residual is parallel to a
- Says the formula requires a to be a unit vector
- Ignores that projection onto the zero vector is undefined