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
