Adding, subtracting and scaling vectors
Add vectors head to tail, subtract them to get relative positions, and scale them to stretch or flip. Then use all three to route a pipe, lay out a column grid and set out a stair.
| Operation | Rule | Picture |
|---|---|---|
Adding: chaining steps
using V3 = (double X, double Y, double Z); static V3 Add(V3 a, V3 b) => (a.X + b.X, a.Y + b.Y, a.Z + b.Z); V3[] runs = { (3, 0, 0), (0, 2, 0), (0, 0, 1.5), (-1, 0, 0) }; V3 total = (0, 0, 0);foreach (V3 run in runs) total = Add(total, run); V3 start = (10, 4, 2.5);Console.WriteLine($"Total displacement: {total}");Console.WriteLine($"Pipe ends at: {Add(start, total)}");Total displacement: (2, 2, 1.5) Pipe ends at: (12, 6, 4)
Subtracting: where is it relative to me?
using V2 = (double X, double Y); V2 gridC3 = (12, 6);V2 column = (12.5, 7.25); V2 offset = (column.X - gridC3.X, column.Y - gridC3.Y);Console.WriteLine($"Column is {offset} from grid C/3");Column is (0.5, 1.25) from grid C/3
Scaling: repeats and arrays
using V2 = (double X, double Y); static V2 Add(V2 a, V2 b) => (a.X + b.X, a.Y + b.Y);static V2 Scale(V2 v, double k) => (v.X * k, v.Y * k); V2 origin = (0, 0);V2 along = (7.5, 0); // bay spacing in XV2 across = (0, 6); // bay spacing in Y for (int j = 0; j < 2; j++){ var row = new List<string>(); for (int i = 0; i < 3; i++) row.Add(Add(origin, Add(Scale(along, i), Scale(across, j))).ToString()); Console.WriteLine(string.Join(" ", row));}(0, 0) (7.5, 0) (15, 0) (0, 6) (7.5, 6) (15, 6)
The rules you can rely on
Order does not matter for adding: a + b = b + a, and (a + b) + c = a + (b + c). Subtracting is adding the opposite: a − b = a + (−1)b. But a − b = −(b − a), so order matters here. Scaling spreads over adding: k(a + b) = ka + kb. Scaling everything about the origin keeps every shape the same, just bigger or smaller. The zero vector (0, 0, 0) is “no step”. It is the only vector with no direction, and it will need special care when you normalise.
Show a hint
:F3.
Show the solution
using V3 = (double X, double Y, double Z); static V3 Add(V3 a, V3 b) => (a.X + b.X, a.Y + b.Y, a.Z + b.Z);static V3 Scale(V3 v, double k) => (v.X * k, v.Y * k, v.Z * k); V3 bottom = (2, 5, 0);V3 step = (0.28, 0, 0.175);V3 top = Add(bottom, Scale(step, 12)); Console.WriteLine($"Top: ({top.X:F3}, {top.Y:F3}, {top.Z:F3})");Console.WriteLine($"Going: {12 * step.X:F2} m, rise: {12 * step.Z:F2} m");Top: (5.360, 5.000, 2.100) Going: 3.36 m, rise: 2.10 m
Remember
Add, subtract and scale vectors component by component. a + b chains two steps (head to tail); the order does not change where you end up. B − A is the position of B relative to A: offsets, setting-out dimensions, local positions. k × v stretches v by k; a negative k also reverses it. An array is start + i × spacing. Writing positions as start + combinations of vectors keeps code working for rotated layouts too.