McNeel Wiki
Calculating the Shortest Line between two Lines
edit · print · help · all topics
Main Pages

AccuRender

Bongo

Brazil r/s

Developer

Flamingo

Penguin

Rhino Blogs

Rhino

Rhino Labs

Search

Languages

Česky

Deutsch

English

Español

Français

Italiano

Polish

日本語

한국어

中文(繁體)

中文(简体)

 
.
DeveloperRhinoScript
VersionRhino 4.0
SummaryDemonstrates how to calculate the shortest line between two lines using RhinoScript.

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 3-D.

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
rename · changes · history · subscriptions · lost and found · references · file upload