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
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");Pipe vector: (3, 4, 12) Pipe length: 13 m
Unit vectors: direction only
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})");Wall length: 10 m Unit direction: (0.6, 0.8) Door at: (2.72, 1.96)
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");(3, 4) -> (0.6, 0.8) (0, 0) has no direction
Squared length: skip the square root when you can
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");Nearest column: (7.5, 6), 2.47 m away
Show a hint
Show the solution
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})");(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.