Shortest Line between two Lines
Windows only
Overview
Two lines in three dimensions generally do not intersect at a point. They may be parallel (no intersections) or they may be coincident (infinite intersections) but most often only their projection onto a plane intersects. When they do not exactly intersect at a point they can be connected by a line segment, the shortest line segment is unique and is often considered to be their intersection in 3D.
Example
The following example code demonstrates how to calculate the shortest line between two line segments using RhinoScript…
Option Explicit ' Description: ' Returns the shortest line segment between ' two infinite line segments. ' Parameters: ' p1 - the starting point of the first line ' p2 - the ending point of the first line ' p3 - the starting point of the second line ' p4 - the ending point of the second line ' Returns ' Array - the shortest line segment if successful ' Null - if not successful or on error Function LineLineIntersect(p1, p2, p3, p4) LineLineIntersect = Null Const EPS = 2.2204460492503131e-016 Dim p13(2), p43(2), p21(2) Dim d1343, d4321, d1321, d4343, d2121, numer, denom, mua, mub Dim pa(2), pb(2) p13(0) = p1(0) - p3(0) p13(1) = p1(1) - p3(1) p13(2) = p1(2) - p3(2) p43(0) = p4(0) - p3(0) p43(1) = p4(1) - p3(1) p43(2) = p4(2) - p3(2) If Abs(p43(0)) < EPS And Abs(p43(1)) < EPS And Abs(p43(2)) < EPS Then Exit Function p21(0) = p2(0) - p1(0) p21(1) = p2(1) - p1(1) p21(2) = p2(2) - p1(2) If Abs(p21(0)) < EPS And Abs(p21(1)) < EPS And Abs(p21(2)) < EPS Then Exit Function d1343 = p13(0) * p43(0) + p13(1) * p43(1) + p13(2) * p43(2) d4321 = p43(0) * p21(0) + p43(1) * p21(1) + p43(2) * p21(2) d1321 = p13(0) * p21(0) + p13(1) * p21(1) + p13(2) * p21(2) d4343 = p43(0) * p43(0) + p43(1) * p43(1) + p43(2) * p43(2) d2121 = p21(0) * p21(0) + p21(1) * p21(1) + p21(2) * p21(2) denom = d2121 * d4343 - d4321 * d4321 If Abs(denom) < EPS Then Exit Function numer = d1343 * d4321 - d1321 * d4343 mua = numer / denom mub = (d1343 + d4321 * mua) / d4343 pa(0) = p1(0) + mua * p21(0) pa(1) = p1(1) + mua * p21(1) pa(2) = p1(2) + mua * p21(2) pb(0) = p3(0) + mub * p43(0) pb(1) = p3(1) + mub * p43(1) pb(2) = p3(2) + mub * p43(2) LineLineIntersect = Array(pa, pb) End Function
You can test the above function as follows:
Sub Test Dim l0 : l0 = Rhino.GetObject("Select first line", 4) Dim l1 : l1 = Rhino.GetObject("Select second line", 4) Dim p1 : p1 = Rhino.CurveStartPoint(l0) Dim p2 : p2 = Rhino.CurveEndPoint(l0) Dim p3 : p3 = Rhino.CurveStartPoint(l1) Dim p4 : p4 = Rhino.CurveEndPoint(l1) Dim rc : rc = LineLineIntersect(p1, p2, p3, p4) If IsArray(rc) Then Rhino.AddPoints rc End If End Sub