Calculating the shortest distance between two lines line segments in 3D
Master System Design with Codemia
Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.
Introduction
Finding the shortest distance between two lines in 3D is a standard geometry problem, but the segment version is the one that usually matters in code. Infinite lines extend forever, while segments stop at endpoints, so a formula that works for lines is not enough for collision tests, CAD tools, or simulation code.
The reliable way to think about the problem is to find the two closest points, one on each object, and then measure the distance between them. For infinite lines, those points lie on a common perpendicular when the lines are not parallel. For segments, the closest points may instead sit on one or both endpoints.
Parametric Setup
Write the two objects in parametric form:
Here, and are starting points, and and are direction vectors. For infinite lines, and can be any real values. For line segments, they are restricted to the interval .
The squared distance between points on the two objects is:
Using the squared distance keeps the algebra simpler and avoids an unnecessary square root while solving the minimization problem.
Shortest Distance for Infinite Lines
Let:
and define the dot products:
For non-parallel lines, the minimizing parameters are:
The denominator becomes zero only when the direction vectors are parallel or numerically very close to parallel.
There is also a compact distance-only formula. If , then the distance between two skew lines is:
That expression is useful for quick reasoning, but many implementations also need the closest points, so the parameter-based form is usually the better starting point.
Why Segments Need Extra Work
For segments, the unconstrained solution for and may fall outside . When that happens, the closest point on a segment is not an interior point anymore; it is an endpoint.
So the segment problem is a constrained minimization problem:
A practical routine usually follows this logic:
- Solve for the closest points on the infinite lines.
- Clamp the parameters into if they fall outside the segment bounds.
- Recompute the paired parameter after clamping, because fixing one endpoint changes the best point on the other segment.
That last step is easy to miss. Clamping one parameter and leaving the other untouched can produce the wrong answer.
Runnable Python Example
The following function returns the shortest distance and the actual closest points between two 3D line segments:
For this example, the distance is 1.0. The closest points are (1.0, 1.0, 0.0) and (1.0, 1.0, 1.0).
Interpreting Special Cases
Three cases matter.
First, intersecting lines or segments have distance 0. In floating-point code, compare against a tolerance instead of exact equality.
Second, parallel objects make the denominator very small. That does not mean the algorithm failed; it means there is no unique common perpendicular direction, so the implementation has to fall back to endpoint and projection logic.
Third, degenerate segments can happen when the two endpoints are identical. In that case, one segment is just a point, and the problem reduces to point-to-segment distance.
Common Pitfalls
- Using the infinite-line formula directly for segments and forgetting to clamp the parameters.
- Comparing floating-point values to exact zero instead of using a tolerance for parallel or intersecting cases.
- Returning only the distance when downstream code also needs the closest points for visualization or contact resolution.
- Forgetting that a zero-length segment is a point and needs special handling.
- Computing the square root too early instead of minimizing squared distance first.
Summary
- Model each line or segment with a parametric equation.
- For infinite lines, solve for the minimizing parameters with dot products.
- For skew lines, the cross-product formula gives a compact distance check.
- For segments, clamp parameters into and recompute when an endpoint becomes active.
- A robust implementation should handle parallel lines, intersections, and zero-length segments.

