<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 10 of 44 16 minBeginner

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.

The dot product turns two vectors into a number. The cross product turns two 3D vectors into a third vector:

a × 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)

The formula is easiest to remember by its pattern: for the X part, use the Y and Z parts, and so on round the cycle X → Y → Z → X. What matters more is what the result means:

  • 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.
AxisCross.cs
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))}");
Output
X x Y = (0, 0, 1)
Y x Z = (1, 0, 0)
Y x X = (0, 0, -1)

In plan: one number, two answers

For two vectors lying flat in the XY plane, the X and Y parts of the cross product are zero and only the Z part is left: a.x·b.y − a.y·b.x. This number is often called the 2D cross product or the perp-dot product, and it is one of the most used expressions in plan geometry.

Interactive

The cross product: area and side

Drag the tips of a and b. Green means b is counter-clockwise from a (to its left); red means clockwise.

⊙ab
a⟨4, 1⟩
b⟨1.5, 3.5⟩
a × b (z)4×3.5 − 1×1.5
= 12.5
parallelogram|z| = 12.5
triangle 0, a, b|z| ÷ 2 = 6.25
|a| |b| sin θ4.12 × 3.81 × 0.796
3D a × b⟨0, 0, 12.5⟩
a × b = 12.5 > 0: turning from a to b is counter-clockwise, b is to the LEFT of a, and in 3D the cross product points up out of the screen (⊙). The parallelogram’s area is 12.5.
  • 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.
WhichSide.cs
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}");}
Output
(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

Take any three corners of a flat face, P0, P1 and P2. The two edges P1 − P0 and P2 − P0 lie in the face, so their cross product points straight out of it. Normalise it and you have the unit normal; take half its length and you have the triangle’s area. Here is a sloping roof face:

RoofNormal.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 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");
Output
Cross: (0, -12, 16)
Unit normal: (0, -0.6, 0.8)
Triangle area: 10 square metres
Roof slope: 36.87 deg

The normal points up and towards −Y, so this roof face looks south (with Y as north): exactly what the dot-product solar check in the previous lesson needs. And the angle between the normal and straight up (0, 0, 1) is the roof’s slope: since both are unit vectors, their dot product is just unit.Z.

Building a frame from one direction

Two cross products turn a single wall direction into a full set of axes for the wall: side = dir × up points to the wall’s right, and up = side × dir recovers a true vertical. This “frame from a direction” pattern is how tools orient doors, windows and section boxes, and you will use it in the Matrices module.

Quick check

a × b = (0, 0, 6). What is b × a?

Quick check

For a wall from A to B, the 2D cross product of B − A and P − A is negative. Where is P?

Practice

A roof plane is split into two triangles: (0,0,0)–(4,0,0)–(0,4,3) and (4,0,0)–(4,4,3)–(0,4,3). Write TriangleArea(a, b, c) using the cross product and print the total roof area.

Show a hint

Area = |(b − a) × (c − a)| ÷ 2. Add the two areas. (Check: the plane is 4 m wide and 5 m up the slope.)

Show the solution
Solution.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 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");
Output
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.
0 of 44 lessons completed