private double BruteForceMultiPathMultiPoint_(com.epl.geometry.MultiPath geometryA, com.epl.geometry.MultiPoint geometryB, bool geometriesAreDisjoint) { /* const */ /* const */ com.epl.geometry.SegmentIterator segIterA = geometryA.QuerySegmentIterator(); com.epl.geometry.Envelope2D env2DSegmentA = new com.epl.geometry.Envelope2D(); double minSqrDistance = com.epl.geometry.NumberUtils.DoubleMax(); com.epl.geometry.Point2D inputPoint = new com.epl.geometry.Point2D(); double t = -1; double sqrDistance = minSqrDistance; /* const */ com.epl.geometry.MultiPointImpl multiPointImplB = (com.epl.geometry.MultiPointImpl)geometryB._getImpl(); int pointCountB = multiPointImplB.GetPointCount(); bool bDoPiPTest = !geometriesAreDisjoint && (geometryA.GetType() == com.epl.geometry.Geometry.Type.Polygon); while (segIterA.NextPath()) { while (segIterA.HasNextSegment()) { /* const */ com.epl.geometry.Segment segmentA = segIterA.NextSegment(); segmentA.QueryEnvelope2D(env2DSegmentA); // if multipointB has only 1 vertex then it is faster to not // test for // env2DSegmentA.distance(env2DgeometryB) if (pointCountB > 1 && env2DSegmentA.SqrDistance(this.m_env2DgeometryB) > minSqrDistance) { continue; } for (int i = 0; i < pointCountB; i++) { multiPointImplB.GetXY(i, inputPoint); if (bDoPiPTest) { // Test for polygon containment. This takes the // place of a more general intersection test at the // beginning of the operator if (com.epl.geometry.PolygonUtils.IsPointInPolygon2D((com.epl.geometry.Polygon)geometryA, inputPoint, 0) != com.epl.geometry.PolygonUtils.PiPResult.PiPOutside) { return(0.0); } } t = segmentA.GetClosestCoordinate(inputPoint, false); inputPoint.Sub(segmentA.GetCoord2D(t)); sqrDistance = inputPoint.SqrLength(); if (sqrDistance < minSqrDistance) { if (sqrDistance == 0.0) { return(0.0); } minSqrDistance = sqrDistance; } } // No need to do point-in-polygon anymore (if it is a // polygon vs polyline) bDoPiPTest = false; } } return(System.Math.Sqrt(minSqrDistance)); }
private double BruteForceMultiPathMultiPath_(com.epl.geometry.MultiPath geometryA, com.epl.geometry.MultiPath geometryB, bool geometriesAreDisjoint) { /* const */ /* const */ // It may be beneficial to have the geometry with less vertices // always be geometryA. com.epl.geometry.SegmentIterator segIterA = geometryA.QuerySegmentIterator(); com.epl.geometry.SegmentIterator segIterB = geometryB.QuerySegmentIterator(); com.epl.geometry.Envelope2D env2DSegmentA = new com.epl.geometry.Envelope2D(); com.epl.geometry.Envelope2D env2DSegmentB = new com.epl.geometry.Envelope2D(); double minSqrDistance = com.epl.geometry.NumberUtils.DoubleMax(); if (!geometriesAreDisjoint) { // Geometries might be non-disjoint. Check if they intersect // using point-in-polygon tests if (this.WeakIntersectionTest_(geometryA, geometryB, segIterA, segIterB)) { return(0.0); } } // if geometries are known disjoint, don't bother to do any tests // for polygon containment // nested while-loop insanity while (segIterA.NextPath()) { while (segIterA.HasNextSegment()) { /* const */ com.epl.geometry.Segment segmentA = segIterA.NextSegment(); segmentA.QueryEnvelope2D(env2DSegmentA); if (env2DSegmentA.SqrDistance(this.m_env2DgeometryB) > minSqrDistance) { continue; } while (segIterB.NextPath()) { while (segIterB.HasNextSegment()) { /* const */ com.epl.geometry.Segment segmentB = segIterB.NextSegment(); segmentB.QueryEnvelope2D(env2DSegmentB); if (env2DSegmentA.SqrDistance(env2DSegmentB) < minSqrDistance) { // get distance between segments double sqrDistance = segmentA.Distance(segmentB, geometriesAreDisjoint); sqrDistance *= sqrDistance; if (sqrDistance < minSqrDistance) { if (sqrDistance == 0.0) { return(0.0); } minSqrDistance = sqrDistance; } } } } segIterB.ResetToFirstPath(); } } return(System.Math.Sqrt(minSqrDistance)); }