3D geometry
line segment
plane intersection
mathematical concepts
computational geometry

3D Line Segment and Plane Intersection

Master System Design with Codemia

Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.

Introduction

A 3D line segment and a plane intersect only if the infinite line crosses the plane at a parameter value that lies between the segment endpoints. The clean way to compute that is to parameterize the segment, plug it into the plane equation, solve for the parameter, and then check whether the result lies in the segment range.

This is a standard operation in graphics, collision detection, CAD, and simulation code. The math is compact once you express everything in vector form.

Represent the Segment and the Plane

Let the segment run from point A to point B. Write the segment as:

  • 'P(t) = A + t(B - A)'
  • 't in the range 0 to 1'

Let the plane be defined by a point Q on the plane and a normal vector N. A point X lies on the plane when:

  • 'N · (X - Q) = 0'

Substitute the segment equation into the plane equation:

  • 'N · (A + t(B - A) - Q) = 0'

Solve for t:

  • 't = N · (Q - A) / N · (B - A)'

That is the core formula.

Interpret the Result

The denominator N · (B - A) tells you whether the segment direction is parallel to the plane.

  • if the denominator is zero, the segment is parallel to the plane
  • if the numerator is also zero, the entire segment lies in the plane
  • otherwise there is no single intersection point

If the denominator is not zero, compute t.

  • if 0 <= t <= 1, the segment intersects the plane
  • if t < 0 or t > 1, the infinite line intersects the plane, but the finite segment does not

A Runnable Python Example

python
1from typing import Optional, Tuple
2
3Vector = Tuple[float, float, float]
4
5def dot(a: Vector, b: Vector) -> float:
6    return a[0] * b[0] + a[1] * b[1] + a[2] * b[2]
7
8def subtract(a: Vector, b: Vector) -> Vector:
9    return (a[0] - b[0], a[1] - b[1], a[2] - b[2])
10
11def add(a: Vector, b: Vector) -> Vector:
12    return (a[0] + b[0], a[1] + b[1], a[2] + b[2])
13
14def scale(v: Vector, s: float) -> Vector:
15    return (v[0] * s, v[1] * s, v[2] * s)
16
17def segment_plane_intersection(a: Vector, b: Vector, q: Vector, n: Vector) -> Optional[Vector]:
18    ab = subtract(b, a)
19    denominator = dot(n, ab)
20    numerator = dot(n, subtract(q, a))
21
22    if abs(denominator) < 1e-9:
23        return None
24
25    t = numerator / denominator
26    if 0.0 <= t <= 1.0:
27        return add(a, scale(ab, t))
28    return None
29
30point = segment_plane_intersection(
31    a=(0.0, 0.0, 0.0),
32    b=(0.0, 0.0, 10.0),
33    q=(0.0, 0.0, 5.0),
34    n=(0.0, 0.0, 1.0)
35)
36
37print(point)

This returns (0.0, 0.0, 5.0) because the segment crosses the plane z = 5.

Numerical Robustness Matters

In floating-point code, do not compare the denominator to zero exactly. Use an epsilon threshold instead. Small rounding errors can make a near-parallel segment look like a valid intersection or vice versa.

That is why the example checks:

  • 'abs(denominator) < 1e-9'

The exact epsilon depends on the scale and precision of your geometry.

Special Cases You May Need to Distinguish

Depending on the application, None may not be enough for all parallel cases. You may want separate outcomes for:

  • no intersection
  • segment parallel to plane
  • segment lying completely in plane
  • proper single intersection point

Game engines and CAD tools often need this distinction because the downstream behavior differs.

Common Pitfalls

  • Solving for the infinite line and forgetting to check that t lies in the segment range.
  • Dividing by a denominator that is nearly zero without an epsilon check.
  • Treating a segment contained in the plane as if it had one unique intersection point.
  • Using an unnormalized or incorrect plane normal without realizing it affects the sign and stability of the calculation.

Summary

  • Parameterize the segment as A + t(B - A) and solve against the plane equation.
  • Use t = N · (Q - A) / N · (B - A) when the denominator is not zero.
  • The segment intersects the plane only when t is between 0 and 1.
  • Handle parallel and in-plane cases explicitly if the application needs them.
  • Use an epsilon threshold for numerical stability in real floating-point code.

Course illustration
Course illustration

All Rights Reserved.