I’m trying to find the minimum distance between two line segments (specifically I want the actual line that exists between the points of minimum separation)
So I’m using the LineLine intersection but when you say it should use finite lengths it does not appear to be playing correctly. See the attached example where the closest point between the two infinite lines is outside the bounds of the red segment.
It appears that when one parameter is outside the bound 0>1 this parameter alone is just snapped to the closest bound. But that’s not correct if the function should return the closest parameters as described in http://developer.rhino3d.com/api/RhinoCommon/html/M_Rhino_Geometry_Intersect_Intersection_LineLine_1.htm
Any help appreciated.
Hi James, maybe Line.MinimumDistanceTo is more appropriate here.
Edit 1: That doesn’t actually return the params, so maybe not, my bad.
Edit 2: I’m getting the behaviour I would expect here, maybe upload your file for further inspection:
180516_ClosestLine_00.gh (6.2 KB)
I am not sure, but I would say the red line is clearly not the shortest distance between lineA and lineB, as it is supposed to be according to the API. In particular Point A is not the closest Point to lineB, but the intersection point of the infinite lines, which is not the behaviour I would expect according to the API.
shortestDistance.gh (7.1 KB)
Its the intersection points of the finite lines within tolerance, which is the expected behaviour (I would say). There might be other ways around this, but one approach would be to check/catch these cases by evaluating whether the length of the resulting minimum line is equal to the
MinimumDistance (as in my example above). If not, use Line.ClosestPoint from the two intersection points onto the their opposing lines, and return the shorter of these two (which should result in what we’re looking for).
Edit: Like so:
180516_ClosestLine_01.gh (3.5 KB)
Its the intersection points of the finite lines within tolerance, which is the expected behaviour (I would say).
That’s actually a fair point but it’s not what the API says as far as I can tell, which is why I posted here.
I actually already implemented something similar to your suggestion to solve my specific problem. EDIT - my method was a lot less elegant than the one you just posted. So thanks!
The API says the following, which suggests the output points a and b should give the “shortest distance between the lines” which would then not be the projected intersection point, but the shortest link.
First line for intersection.
Second line for intersection.
Parameter on lineA that is closest to LineB. The shortest distance between the lines is the chord from lineA.PointAt(a) to lineB.PointAt(b)
Parameter on lineB that is closest to LineA. The shortest distance between the lines is the chord from lineA.PointAt(a) to lineB.PointAt(b)
If tolerance > 0.0, then an intersection is reported only if the distance between the points is <= tolerance. If tolerance <= 0.0, then the closest point between the lines is reported.
If true, the input lines are treated as finite segments. If false, the input lines are treated as infinite lines.
Ah I see, yes that can surely be confusing. I think this maybe simply boils down to the particular semantics used here and what expectations one comes pre-loaded with in terms of line-line-intersections then. That said, I feel like there is a method does actually return the shortest line between two curves in RhinoCommon
Edit: God damn it:
Ah. Yes. Good catch that man. Rhino has a way!
Also: Curve.GetDistancesBetweenCurves() would work and gives ALL THE INFOS regarding the parameters for mindistances etc. That just requires the lines to be cast to curves.
Anyways - to any McNeel people reading this, I do believe the API description specifically notes “shortest distance between the lines” which perhaps needs to be considered for an update, even if the method itself does what is wanted.