The cross product: normals, area, left or right
The cross product builds a vector perpendicular to two others. It gives face normals and areas in 3D, and in plan it tells you whether a point is left or right of a wall.
Direction: a × b is perpendicular to both a and b, so it is perpendicular to the plane they lie in. That is exactly what a face normal is. Which way: it follows the right-hand rule. Fingers along a, curl towards b, and your thumb points along a × b. So x × y = z in a right-handed system. Length: |a × b| = |a| |b| sin θ, the area of the parallelogram spanned by a and b. Half of that is the area of the triangle. Order matters: b × a = −(a × b). Swapping the two flips the normal. Parallel vectors give zero: sin 0° = 0, so a × b = 0 is the standard test for parallel directions.
using V3 = (double X, double Y, double Z); static V3 Cross(V3 a, V3 b) => (a.Y * b.Z - a.Z * b.Y, a.Z * b.X - a.X * b.Z, a.X * b.Y - a.Y * b.X); Console.WriteLine($"X x Y = {Cross((1, 0, 0), (0, 1, 0))}");Console.WriteLine($"Y x Z = {Cross((0, 1, 0), (0, 0, 1))}");Console.WriteLine($"Y x X = {Cross((0, 1, 0), (1, 0, 0))}");X x Y = (0, 0, 1) Y x Z = (1, 0, 0) Y x X = (0, 0, -1)
In plan: one number, two answers
Its sign gives the turn: positive when b is counter-clockwise from a (to its left), negative when clockwise (to its right), zero when they are parallel. Its size gives the area: the parallelogram’s area, or twice the triangle’s. Side of a wall: with a = B − A (the wall) and b = P − A, the sign says whether P is left or right of the wall as you walk from A to B. Divide by |B − A| and you get the distance from the line too.
using V2 = (double X, double Y); static double Cross(V2 a, V2 b) => a.X * b.Y - a.Y * b.X; V2 a = (0, 0), b = (10, 0); // wall from A to B, walking eastV2[] points = { (4, 2), (4, -1.5), (12, 0) }; foreach (V2 p in points){ double c = Cross((b.X - a.X, b.Y - a.Y), (p.X - a.X, p.Y - a.Y)); string side = c > 1e-9 ? "left" : c < -1e-9 ? "right" : "on the line"; Console.WriteLine($"{p}: cross = {c}, {side}");}(4, 2): cross = 20, left (4, -1.5): cross = -15, right (12, 0): cross = 0, on the line
In 3D: the normal of a face
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 V3 Cross(V3 a, V3 b) => (a.Y * b.Z - a.Z * b.Y, a.Z * b.X - a.X * b.Z, a.X * b.Y - a.Y * b.X);static double Length(V3 v) => Math.Sqrt(v.X * v.X + v.Y * v.Y + v.Z * v.Z); V3 p0 = (0, 0, 0), p1 = (4, 0, 0), p2 = (0, 4, 3); // eaves corners and a ridge cornerV3 n = Cross(Sub(p1, p0), Sub(p2, p0));double len = Length(n);V3 unit = (n.X / len, n.Y / len, n.Z / len); Console.WriteLine($"Cross: {n}");Console.WriteLine($"Unit normal: {unit}");Console.WriteLine($"Triangle area: {len / 2} square metres");Console.WriteLine($"Roof slope: {Math.Acos(unit.Z) * 180 / Math.PI:F2} deg");Cross: (0, -12, 16) Unit normal: (0, -0.6, 0.8) Triangle area: 10 square metres Roof slope: 36.87 deg
unit.Z.
Building a frame from one direction
TriangleArea(a, b, c) using the cross product and print the total roof area.
Show a hint
Show the solution
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 V3 Cross(V3 a, V3 b) => (a.Y * b.Z - a.Z * b.Y, a.Z * b.X - a.X * b.Z, a.X * b.Y - a.Y * b.X);static double Length(V3 v) => Math.Sqrt(v.X * v.X + v.Y * v.Y + v.Z * v.Z);static double TriangleArea(V3 a, V3 b, V3 c) => Length(Cross(Sub(b, a), Sub(c, a))) / 2; var roof = new (V3 A, V3 B, V3 C)[]{ ((0, 0, 0), (4, 0, 0), (0, 4, 3)), ((4, 0, 0), (4, 4, 3), (0, 4, 3))}; double total = 0;foreach (var t in roof) total += TriangleArea(t.A, t.B, t.C);Console.WriteLine($"Roof area: {total} square metres");Roof area: 20 square metres
Remember
a × b is perpendicular to both a and b, follows the right-hand rule, and has length |a||b| sin θ. Order matters: b × a = −(a × b). Parallel vectors give the zero vector. The 2D cross product a.x·b.y − a.y·b.x gives the turn direction (sign) and twice the triangle area (size). Its sign tells whether a point is left or right of a wall: the basis of point-in-polygon and intersection tests. The cross product of two edges gives a face’s normal and area; corner order decides which way the normal points.