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

Lesson 20 of 44 14 minIntermediate

Line–plane and plane–plane intersection

Find where a pipe passes through a slab, or a pick ray hits a work plane, with one division. Then intersect two planes to get ridges, hips and valleys, and see why a hip is always flatter than the roof.

Where does this pipe pass through the floor, so a sleeve can be placed? Where does the mouse ray hit the work plane? Where do two roof slopes meet? These are intersections: a line with a plane, and a plane with a plane.

Interactive

Where lines and planes meet

ABX
n·(B − A)3.999
n·A + d−2.340
t = −(n·A + d) ÷ n·(B − A)0.585
X = A + t(B − A)(2.11, 2.48, 2.94)
t = 0.585: the pipe passes through the slab at X, 59% of the way from A to B. That is where the sleeve (the opening in the slab) goes.

A line and a plane

Write the line as A + t·u and the plane as n·X + d = 0. Substitute the line into the plane: n·(A + t·u) + d = 0, so t = −(n·A + d) ÷ (n·u). The top is the signed distance of A (times |n|), and the bottom says how fast the line approaches the plane.

ResultMeaning
n·u ≈ 0 and n·A + d ≈ 0the line lies in the plane
n·u ≈ 0, otherwisethe line is parallel to the plane and never meets it
0 ≤ t ≤ 1 (with u = B − A)the segment AB passes through the plane at A + t·u
t < 0 or t > 1the line meets the plane, but beyond an end of the segment
SleevePosition.cs
var a = new V3(1, 2, 0.5);                // pipe startvar b = new V3(4, 6, 5.5);                // pipe endvar up = new V3(0, 0, 1); foreach (var (name, level) in new[] { ("Slab top", 3.0), ("Slab soffit", 2.75) }){    double? t = Hit(a, b - a, up, -level);    Console.WriteLine(t is double v && v >= 0 && v <= 1        ? $"{name}: t = {v}, at {a + (b - a) * v}"        : $"{name}: no crossing");} static double? Hit(V3 a, V3 u, V3 n, double d){    double nu = V3.Dot(n, u);    if (Math.Abs(nu) < 1e-12) return null;   // parallel to the plane    return -(V3.Dot(n, a) + d) / nu;} readonly record struct V3(double X, double Y, double Z){    public static V3 operator +(V3 a, V3 b) => new(a.X + b.X, a.Y + b.Y, a.Z + b.Z);    public static V3 operator -(V3 a, V3 b) => new(a.X - b.X, a.Y - b.Y, a.Z - b.Z);    public static V3 operator *(V3 v, double k) => new(v.X * k, v.Y * k, v.Z * k);    public static double Dot(V3 a, V3 b) => a.X * b.X + a.Y * b.Y + a.Z * b.Z;    public static V3 Cross(V3 a, V3 b) =>        new(a.Y * b.Z - a.Z * b.Y, a.Z * b.X - a.X * b.Z, a.X * b.Y - a.Y * b.X);    public double Length => Math.Sqrt(Dot(this, this));    public V3 Normalized() => this * (1 / Length);    public override string ToString() => $"({X:0.###}, {Y:0.###}, {Z:0.###})";}
Output
Slab top: t = 0.5, at (2.5, 4, 3)
Slab soffit: t = 0.45, at (2.35, 3.8, 2.75)

The two points are offset in plan because the pipe is sloping: the opening has to be long enough to cover both, plus the pipe’s radius and insulation. A pick ray works the same way: the mouse position gives a ray from the camera, and t says how far along it the work plane is.

Two planes

Two planes that are not parallel meet in a line. Its direction lies in both planes, so it is at right angles to both normals: n1 × n2. For a point on it, write the planes as n·X = h (h = −d) and look for the point that is a mix c1·n1 + c2·n2 of the two normals. Putting that into both equations gives:

  • c1 = (h1·(n2·n2) − h2·(n1·n2)) ÷ |n1 × n2|²
  • c2 = (h2·(n1·n1) − h1·(n1·n2)) ÷ |n1 × n2|²
  • The point c1·n1 + c2·n2 is the point of the line closest to the origin. If n1 × n2 ≈ 0, the planes are parallel.
RoofLines.cs
var slopeA = (N: new V3(0, -0.6, 0.8), H: 2.4);   // n.X = h, rising from eaves at y = 0var slopeB = (N: new V3(0, 0.6, 0.8), H: 7.2);    // the opposite slope, eaves at y = 8var endC = (N: new V3(0.6, 0, 0.8), H: 2.4);      // the hipped end, eaves at x = 0 Report("Ridge", slopeA.N, slopeA.H, slopeB.N, slopeB.H);Report("Hip", slopeA.N, slopeA.H, endC.N, endC.H); static void Report(string name, V3 n1, double h1, V3 n2, double h2){    V3 dir = V3.Cross(n1, n2);    double det = V3.Dot(dir, dir);    if (det < 1e-12) { Console.WriteLine($"{name}: parallel planes"); return; }    double n12 = V3.Dot(n1, n2);    double c1 = (h1 * V3.Dot(n2, n2) - h2 * n12) / det;    double c2 = (h2 * V3.Dot(n1, n1) - h1 * n12) / det;    V3 p = n1 * c1 + n2 * c2;                     // the point of the line nearest the origin    V3 u = dir.Normalized();    Console.WriteLine($"{name}: through {p}, direction {u}, slope {Math.Asin(Math.Abs(u.Z)) * 180 / Math.PI:F2} deg");} readonly record struct V3(double X, double Y, double Z){    public static V3 operator +(V3 a, V3 b) => new(a.X + b.X, a.Y + b.Y, a.Z + b.Z);    public static V3 operator -(V3 a, V3 b) => new(a.X - b.X, a.Y - b.Y, a.Z - b.Z);    public static V3 operator *(V3 v, double k) => new(v.X * k, v.Y * k, v.Z * k);    public static double Dot(V3 a, V3 b) => a.X * b.X + a.Y * b.Y + a.Z * b.Z;    public static V3 Cross(V3 a, V3 b) =>        new(a.Y * b.Z - a.Z * b.Y, a.Z * b.X - a.X * b.Z, a.X * b.Y - a.Y * b.X);    public double Length => Math.Sqrt(Dot(this, this));    public V3 Normalized() => this * (1 / Length);    public override string ToString() => $"({X:0.###}, {Y:0.###}, {Z:0.###})";}
Output
Ridge: through (0, 4, 6), direction (-1, 0, 0), slope 0.00 deg
Hip: through (0.878, -0.878, 2.341), direction (-0.625, 0.625, 0.469), slope 27.94 deg

The ridge is level, 6 m up and 4 m in from both eaves. The hip runs at 45° in plan (both slopes have the same pitch), but it rises at only about 27.9°, against 36.87° for the roof. A hip or valley is always flatter than the slopes it joins, because it covers more ground for the same rise. The printed point is just the point of the line nearest the origin, which here is outside the building; the hip also passes through the corner (0, 0, 3), where the two eaves meet.

Quick check

For a line A + t·u and a plane, n·u = 0. What does that tell you?

Quick check

Why is the direction of the line where two planes meet n1 × n2?

Practice

A wall face is the plane x = 4. Write a function that tests a pipe from A to B against it and prints the crossing point, “parallel to the wall” or “does not reach the wall”. Try the pipes (1, 1, 3) → (7, 3, 3) and (1, 1, 3) → (1, 5, 3).

Show a hint

The wall has n = (1, 0, 0) and d = −4. Compute n·u first: for the second pipe it is 0.

Show the solution
Solution.cs
var wallN = new V3(1, 0, 0);double wallD = -4;                        // the wall face x = 4 Test(new V3(1, 1, 3), new V3(7, 3, 3));Test(new V3(1, 1, 3), new V3(1, 5, 3)); void Test(V3 a, V3 b){    V3 u = b - a;    double nu = V3.Dot(wallN, u);    if (Math.Abs(nu) < 1e-12) { Console.WriteLine($"{a} to {b}: parallel to the wall"); return; }    double t = -(V3.Dot(wallN, a) + wallD) / nu;    Console.WriteLine(t >= 0 && t <= 1 ? $"{a} to {b}: crosses at {a + u * t}" : $"{a} to {b}: does not reach the wall");} readonly record struct V3(double X, double Y, double Z){    public static V3 operator +(V3 a, V3 b) => new(a.X + b.X, a.Y + b.Y, a.Z + b.Z);    public static V3 operator -(V3 a, V3 b) => new(a.X - b.X, a.Y - b.Y, a.Z - b.Z);    public static V3 operator *(V3 v, double k) => new(v.X * k, v.Y * k, v.Z * k);    public static double Dot(V3 a, V3 b) => a.X * b.X + a.Y * b.Y + a.Z * b.Z;    public static V3 Cross(V3 a, V3 b) =>        new(a.Y * b.Z - a.Z * b.Y, a.Z * b.X - a.X * b.Z, a.X * b.Y - a.Y * b.X);    public double Length => Math.Sqrt(Dot(this, this));    public V3 Normalized() => this * (1 / Length);    public override string ToString() => $"({X:0.###}, {Y:0.###}, {Z:0.###})";}
Output
(1, 1, 3) to (7, 3, 3): crosses at (4, 2, 3)
(1, 1, 3) to (1, 5, 3): parallel to the wall

Remember

  • Line A + t·u meets plane n·X + d = 0 at t = −(n·A + d) ÷ (n·u).
  • n·u ≈ 0 means parallel: test it before dividing, with a tolerance relative to |u|.
  • For a segment, only 0 ≤ t ≤ 1 is a real crossing: that is where sleeves and openings go.
  • Two planes meet along n1 × n2; a point on the line comes from mixing the two normals.
  • Ridges, hips and valleys are plane–plane intersections, and hips are flatter than the roof.
0 of 44 lessons completed