Vectors

A vector is an arrow — a direction and a length — long before it is three numbers. Adding arrows tip-to-tail steers everything that moves; subtracting two positions gives the arrow between them; normalizing strips the length away so only direction remains.

Core Idea

A vector is an arrow: a direction and a length, and nothing else. The three numbers are only the arrow’s shadow on some coordinate frame — the same arrow casts different numbers in different frames, which is why a bare (3, 2, 0) means nothing until you know whose axes it’s measured in (coordinate spaces makes that point touchable).

The swarm above is vectors at work: every agent carries its velocity as an arrow, and the gold wind vector is added to all ninety of them at once — drag it and feel a single addition steer the whole field. That is most of gameplay, physics, and animation programming: arrows added to arrows, every frame.

A Point Is Not a Vector

A point is a somewhere; a vector is a which-way-and-how-far. They trade through one rule — end minus start:

b − a   =  the arrow FROM a TO b        |b − a|  =  the distance between them

Get the order backwards and everything downstream points the wrong way: lightPos − surfacePoint aims at the light, surfacePoint − lightPos aims away from it. (The pipeline encodes the point/vector distinction as w = 1 vs w = 0homogeneous coordinates tells that story.)

Arrow Arithmetic

Addition is tip-to-tail: carry b so it starts where a ends. In the demo both dashed routes — b after a, and a after b — land on the same corner of the parallelogram: a + b = b + a, which is why forces and velocities can be accumulated in any order. Subtraction is that gold b − a arrow between the tips — and it is not symmetric: a − b is the same arrow reversed.

Length, and Why It Must Be 1

Magnitude is Pythagoras run through every component:

|v| = √(x² + y² + z²)

Normalizingv / |v| — slides the arrow onto the unit circle (press â = a/|a| in the demo): direction kept, length surrendered. Unit vectors matter because most formulas silently assume them; the dot product only reads as an angle when both arrows have length 1. It’s also an everyday movement bug: pressing forward and right together gives an input of length √2 — diagonal motion 41% too fast — until you normalize and rescale:

velocity = input.normalize().multiplyScalar(speed)   // same speed in every direction

The wind demo’s clamp toggle is the same move at scale: normalize(v) · max — every arrow keeps its direction, no arrow may exceed the cap. One caution: the zero vector has no direction, so normalizing it divides by zero — guard with a length check.

Three Ways to Multiply

Operation Output What it’s for
component-wise (aₓbₓ, a_yb_y, a_zb_z) vector non-uniform scaling
dot product a·b scalar angles, projection, lighting
cross product a×b vector perpendiculars, normals, winding

Knowing which multiplication a problem wants is half of graphics debugging.

Connections

Vectors are the raw material everything else here refines: the dot product measures them against each other, the cross product builds normals out of them, and a matrix is nothing but the arrows its columns say the basis becomes. Their numbers only mean something inside a frame — the founding idea of coordinate spaces — and the pipeline’s point/direction split is homogeneous coordinates giving the arrow itself a w.