13. Segment-segment distance

If you think about how two segments can be arranged, you'll realize that there are a lot of special cases. The segments could intersect or they could be parallel. If the segments don't intersect and are not parallel, then the closest points could be on the segments' endpoints, in the segments' interiors, or a combination of the two.

Although the problem seems complicated, there are really only two cases that you need to worry about: when the segments intersect and when they don't.

If the segments intersect, then you can use the techniques used by Solution 29, Line-line intersection, to find the point of intersection.

If the segments don't intersect, then at least one of the segments' endpoints is the point closest to the other segment. In that case, you can use the method described for the preceding solution, Point-segment distance, to find the closest points. Any of the four segment endpoints could be one of the closest points, but you can simply try them all and see which produces the best result.

The last thing you might consider is the special case where the segments are parallel. In that case, multiple endpoints might give the same shortest distance. There may also be pairs of points that give the same shortest distance even though neither of them is an endpoint.

All of these cases give the same shortest distance, however, so it doesn't really matter which one you pick. Unless you have special needs, such as a requirement to find all pairs of points that give the shortest distance, then you may as well use the closest points that you find by using the Point-segment distance techniques.

The following code shows the SegmentSegmentClosestPoints method, which forms the heart of the example solution:

// Find the points where the segments p00-p01 and p10-p11 are closest.
private void SegmentSegmentClosestPoints(
PointF p00, PointF p01, PointF p10, PointF p11,
out PointF closestPoint0, out PointF closestPoint1,
out bool isOnSegment0, out bool isOnSegment1)
{
closestPoint0 = new PointF(-1, -1);
closestPoint1 = new PointF(-1, -1);
isOnSegment0 = false;
isOnSegment1 = false;

// Look for an intersection.
PointF intersection = IntersectLines(p00, p01, p10, p11,
out isOnSegment0, out isOnSegment1);
if (isOnSegment0 && isOnSegment1)
{
closestPoint0 = intersection;
closestPoint1 = intersection;
return;
}

// See which segment end points are closest to the other segment.
float testDist, bestDist = float.MaxValue;
PointF testPoint;
bool testIsOnSegment;

// Check p00.
testPoint = PointSegmentClosestPoint(p00,
p10, p11, out testIsOnSegment);
testDist = DistanceSquared(p00, testPoint);
if (testDist < bestDist)
{
closestPoint0 = p00;
closestPoint1 = testPoint;
isOnSegment0 = true;
isOnSegment1 = testIsOnSegment;
bestDist = testDist;
}

// Check p01.
testPoint = PointSegmentClosestPoint(p01,
p10, p11, out testIsOnSegment);
testDist = DistanceSquared(p01, testPoint);
if (testDist < bestDist)
{
closestPoint0 = p01;
closestPoint1 = testPoint;
isOnSegment0 = true;
isOnSegment1 = testIsOnSegment;
bestDist = testDist;
}

// Check p10.
testPoint = PointSegmentClosestPoint(p10,
p00, p01, out testIsOnSegment);
testDist = DistanceSquared(p10, testPoint);
if (testDist < bestDist)
{
closestPoint0 = testPoint;
closestPoint1 = p10;
isOnSegment0 = testIsOnSegment;
isOnSegment1 = true;
bestDist = testDist;
}

// Check p11.
testPoint = PointSegmentClosestPoint(p11,
p00, p01, out testIsOnSegment);
testDist = DistanceSquared(p11, testPoint);
if (testDist < bestDist)
{
closestPoint0 = testPoint;
closestPoint1 = p11;
isOnSegment0 = testIsOnSegment;
isOnSegment1 = true;
bestDist = testDist;
}
}

This method uses the IntersectLines method to see whether the segments intersect. That method is similar to the one used in Solution 29. Line-line intersection, modified to not throw an exception if the lines are parallel. See that solution for more information about the method.

Next, the SegmentSegmentClosestPoints method uses the PointSegmentClosestPoint method to see which of the segments' endpoints is closest to the other segment. That method is similar to the one used in Solution 31. Point-segment distance, so you can read more about it there.

That's all there is to this solution. It simply combines methods used by previous solutions to find the closest points. Download the SegmentSegmentDistance example solution and look at the previous solutions to see additional details.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.143.231.26