<style> .reveal-up, .reveal-left, .reveal-right, .reveal-stagger > * { opacity: 1 !important; transform: none !important; } </style>
  1. Learn
  2. BIM Math
  3. Vectors
All lessons in this course

Lesson 8 of 44 13 minBeginner

Length, distance and unit vectors

Pythagoras in 3D gives a vector’s length and the distance between points. Dividing by the length gives a unit vector, the tool for “move d metres in this direction”.

Length: Pythagoras in 3D

In 2D, the length of (x, y) is √(x² + y²): Pythagoras on the right-angled triangle formed by the two components. In 3D you use it twice, and the result is just as simple: |v| = √(x² + y² + z²). The vertical bars mean “length of”; some books write ‖v‖.

The distance between two points is the length of the vector between them: dist(A, B) = |B − A|.

Distance.cs
using V3 = (double X, double Y, double Z); static V3 Sub(V3 a, V3 b) => (a.X - b.X, a.Y - b.Y, a.Z - b.Z);static double Length(V3 v) => Math.Sqrt(v.X * v.X + v.Y * v.Y + v.Z * v.Z); V3 valve = (1, 2, 3);V3 outlet = (4, 6, 15); V3 pipe = Sub(outlet, valve);Console.WriteLine($"Pipe vector: {pipe}");Console.WriteLine($"Pipe length: {Length(pipe)} m");
Output
Pipe vector: (3, 4, 12)
Pipe length: 13 m

Unit vectors: direction only

A unit vector has length exactly 1. It carries only a direction, which makes it the right tool for “go d metres that way”: d × u has length d. You get one by dividing a vector by its own length; this is called normalising, and the result is often written with a hat, û.

Below, a door is placed 1.2 m along a wall from A. Switch to the version that skips normalising and see how far off it lands.

Interactive

Unit vectors: a door 1.2 m along a wall

Drag the wall ends A and B, and set the distance from A. Then switch normalising off to see the classic bug.

uAB
B − A⟨6.0, 5.0⟩
|B − A|7.810 m
u = (B − A) ÷ |B − A|⟨0.768, 0.640⟩
|u|1.000
A + u × d(1.92, 1.77)
A + (B − A) × d(8.20, 7.00)

door with u   door without normalising   ticks every 1 m

u has length 1, so stepping d = 1.2 along u moves exactly 1.2 m: the door lands at (1.92, 1.77).
DoorOnWall.cs
using V2 = (double X, double Y); V2 a = (2, 1), b = (8, 9);                 // wall location lineV2 d = (b.X - a.X, b.Y - a.Y);             // (6, 8)double len = Math.Sqrt(d.X * d.X + d.Y * d.Y);V2 u = (d.X / len, d.Y / len);             // length 1 double offset = 1.2;                       // door 1.2 m from AV2 door = (a.X + u.X * offset, a.Y + u.Y * offset); Console.WriteLine($"Wall length: {len} m");Console.WriteLine($"Unit direction: {u}");Console.WriteLine($"Door at: ({door.X:F2}, {door.Y:F2})");
Output
Wall length: 10 m
Unit direction: (0.6, 0.8)
Door at: (2.72, 1.96)
TryNormalize.cs
using V2 = (double X, double Y); static bool TryNormalize(V2 v, out V2 unit){    double len = Math.Sqrt(v.X * v.X + v.Y * v.Y);    if (len < 1e-9) { unit = (0, 0); return false; }    unit = (v.X / len, v.Y / len);    return true;} foreach (V2 v in new V2[] { (3, 4), (0, 0) })    Console.WriteLine(TryNormalize(v, out V2 u) ? $"{v} -> {u}" : $"{v} has no direction");
Output
(3, 4) -> (0.6, 0.8)
(0, 0) has no direction

Squared length: skip the square root when you can

A square root is slow compared with a multiplication, and when you only compare distances you do not need it: if |a| < |b| then |a|² < |b|², and the other way round. “Which column is nearest to where the user clicked?” or “is anything within 0.5 m?” can use squared lengths throughout. Compare with 0.5² = 0.25, not with 0.5.

Nearest.cs
using V2 = (double X, double Y); static double DistSq(V2 a, V2 b){    double dx = b.X - a.X, dy = b.Y - a.Y;    return dx * dx + dy * dy;} V2 click = (6.2, 3.9);V2[] columns = { (0, 0), (7.5, 0), (0, 6), (7.5, 6), (15, 6) }; V2 best = columns[0];foreach (V2 c in columns)    if (DistSq(click, c) < DistSq(click, best)) best = c; Console.WriteLine($"Nearest column: {best}, {Math.Sqrt(DistSq(click, best)):F2} m away");
Output
Nearest column: (7.5, 6), 2.47 m away
Quick check

What is the length of the vector (2, 3, 6)?

Quick check

Why compare squared distances when looking for the nearest point?

Practice

A sprinkler pipe runs from (0, 0, 3) to (12, 9, 3). Place a sprinkler every 3 m along it, starting at the first end. Print each position with one decimal.

Show a hint

The pipe is 15 m long and its unit direction is (0.8, 0.6, 0). Loop the distance s from 0 to the length in steps of 3; allow a tiny tolerance so the last one is not lost to rounding.

Show the solution
Solution.cs
using V3 = (double X, double Y, double Z); V3 a = (0, 0, 3), b = (12, 9, 3);V3 d = (b.X - a.X, b.Y - a.Y, b.Z - a.Z);double len = Math.Sqrt(d.X * d.X + d.Y * d.Y + d.Z * d.Z);V3 u = (d.X / len, d.Y / len, d.Z / len); for (double s = 0; s <= len + 1e-9; s += 3)    Console.WriteLine($"({a.X + u.X * s:F1}, {a.Y + u.Y * s:F1}, {a.Z + u.Z * s:F1})");
Output
(0.0, 0.0, 3.0)
(2.4, 1.8, 3.0)
(4.8, 3.6, 3.0)
(7.2, 5.4, 3.0)
(9.6, 7.2, 3.0)
(12.0, 9.0, 3.0)

Remember

  • |v| = √(x² + y² + z²), and the distance between two points is |B − A|.
  • A unit vector has length 1; normalise with v ÷ |v|. Then A + u × d is exactly d metres from A.
  • Never normalise a zero (or nearly zero) vector: check the length against a tolerance first.
  • Compare squared lengths when you only need to know which is nearer; it skips the square root.
  • Forgetting to normalise is one of the most common geometry bugs: the step is |v| times too long.
0 of 44 lessons completed