Created
January 10, 2020 22:38
-
-
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))
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| # [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