Skip to content

Instantly share code, notes, and snippets.

@azrafe7
Created January 10, 2020 22:38
Show Gist options
  • Select an option

  • Save azrafe7/d329c7ff548d5189e9d68ee03b51cea2 to your computer and use it in GitHub Desktop.

Select an option

Save azrafe7/d329c7ff548d5189e9d68ee03b51cea2 to your computer and use it in GitHub Desktop.
The shortest line between two lines in 3D (based on http://paulbourke.net/geometry/pointlineplane/ (Paul Bourke 1988))
# [START] The shortest line between two lines in 3D ###
#
# credits to the following sources:
# - http://paulbourke.net/geometry/pointlineplane/ (Paul Bourke 1988)
# - code from http://paulbourke.net/geometry/pointlineplane/source.mel (Dan Wills [dan@rsp.com.au] 2003)
def d_function(m, n, o, p):
return ((m.x - n.x) * (o.x - p.x) + (m.y - n.y) * (o.y - p.y) + (m.z - n.z) * (o.z - p.z))
def interpolate(a, b, factor):
return b * factor + (1 - factor) * a
def nearestPtsBetweenLinesPts(lineA_pt0, lineA_pt1, lineB_pt0, lineB_pt1, mustLieOnSegments=True):
p1, p2, p3, p4 = lineA_pt0, lineA_pt1, lineB_pt0, lineB_pt1
mu_A = (d_function(p1, p3, p4, p3) * d_function(p4, p3, p2, p1) - d_function(p1, p3, p2, p1) * d_function(p4, p3, p4, p3)) / \
(d_function(p2, p1, p2, p1) * d_function(p4, p3, p4, p3) - d_function(p4, p3, p2, p1) * d_function(p4, p3, p2, p1))
mu_B = (d_function(p1, p3, p4, p3) + mu_A * d_function(p4, p3, p2, p1)) / d_function(p4, p3, p4, p3)
# clamp the values between [0..1], constraining the solution to lie on the original curves
if mustLieOnSegments and ((mu_A < 0 or mu_A > 1) or (mu_B < 0 or mu_B > 1)):
#mu_A = clamp(mu_A, 0, 1)
#mu_B = clamp(mu_B, 0, 1)
raise RuntimeError("[nearestPtsBetweenLinesPts] No constrained solution found.")
# get the actual points by linearly interpolating
pt_A = interpolate(p1, p2, mu_A)
pt_B = interpolate(p3, p4, mu_B)
return pt_A, pt_B
def nearestPtsBetweenLines(lineA, lineB, mustLieOnSegments=True, **kwargs):
linesPts = convertToPts((lineA.ep[0], lineA.ep[-1], lineB.ep[0], lineB.ep[-1]))
pt_A, pt_B = nearestPtsBetweenLinesPts(*linesPts, mustLieOnSegments=mustLieOnSegments)
return pt_A, pt_B
def intersectLinesWrapper_Bourke(crv1, crv2, **kwargs):
res = nearestPtsBetweenLines(crv1, crv2, **kwargs)
return res[0]
# [END] The shortest line between two lines in 3D ###
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment