internal virtual int Find_prev_non_degenerate(com.epl.geometry.SegmentIterator segIter, int index) { segIter.ResetToVertex(index, -1); while (segIter.HasPreviousSegment()) { com.epl.geometry.Segment segment = segIter.PreviousSegment(); double length = segment.CalculateLength2D(); if (length != 0) { return(segIter.GetStartPointIndex()); } } return(-1); }
// Try to find two segements that are not degenerate internal virtual bool Calc_side(com.epl.geometry.Point2D inputPoint, bool bRight, com.epl.geometry.MultiPath multipath, int vertexIndex, int pathIndex) { com.epl.geometry.SegmentIterator segIter = multipath.QuerySegmentIterator(); this.Find_analysis_pair_from_index(inputPoint, segIter, vertexIndex, pathIndex); if (this.m_i1 != -1 && this.m_i2 == -1) { // could not find a pair of segments return(this.m_bRight1); } if (this.m_i1 != -1 && this.m_i2 != -1) { if (this.m_bRight1 == this.m_bRight2) { return(this.m_bRight1); } else { // no conflicting result for the side // the conflicting result, that we are trying to resolve, // happens in the obtuse (outer) side of the turn only. segIter.ResetToVertex(this.m_i1, -1); com.epl.geometry.Segment segment1 = segIter.NextSegment(); com.epl.geometry.Point2D tang1 = segment1._getTangent(1.0); segIter.ResetToVertex(this.m_i2, -1); com.epl.geometry.Segment segment2 = segIter.NextSegment(); com.epl.geometry.Point2D tang2 = segment2._getTangent(0.0); double cross = tang1.CrossProduct(tang2); if (cross >= 0) { // the obtuse angle is on the right side return(true); } else { // the obtuse angle is on the right side return(false); } } } else { System.Diagnostics.Debug.Assert((this.m_i1 == -1 && this.m_i2 == -1)); return(bRight); } }
public static com.epl.geometry.QuadTree BuildQuadTree(com.epl.geometry.MultiPath multipath) { com.epl.geometry.Envelope2D extent = new com.epl.geometry.Envelope2D(); multipath.QueryEnvelope2D(extent); com.epl.geometry.QuadTree quadTree = new com.epl.geometry.QuadTree(extent, 8); int hint_index = -1; com.epl.geometry.SegmentIterator seg_iter = multipath.QuerySegmentIterator(); while (seg_iter.NextPath()) { while (seg_iter.HasNextSegment()) { com.epl.geometry.Segment segment = seg_iter.NextSegment(); int index = seg_iter.GetStartPointIndex(); com.epl.geometry.Envelope2D boundingbox = new com.epl.geometry.Envelope2D(); segment.QueryEnvelope2D(boundingbox); hint_index = quadTree.Insert(index, boundingbox, hint_index); } } return(quadTree); }
internal static com.epl.geometry.Geometry PointMinusPolyline_(com.epl.geometry.Point point, com.epl.geometry.Polyline polyline, double tolerance, com.epl.geometry.ProgressTracker progress_tracker) { com.epl.geometry.Point2D pt = point.GetXY(); com.epl.geometry.SegmentIterator seg_iter = polyline.QuerySegmentIterator(); double tolerance_cluster = tolerance * System.Math.Sqrt(2.0) * 1.00001; double tolerance_cluster_sq = tolerance_cluster * tolerance_cluster; com.epl.geometry.Envelope2D env = new com.epl.geometry.Envelope2D(); while (seg_iter.NextPath()) { while (seg_iter.HasNextSegment()) { com.epl.geometry.Segment segment = seg_iter.NextSegment(); segment.QueryEnvelope2D(env); env.Inflate(tolerance_cluster, tolerance_cluster); if (!env.Contains(pt)) { continue; } if (segment.IsIntersecting(pt, tolerance)) { return(point.CreateInstance()); } // check segment end points to the cluster tolerance com.epl.geometry.Point2D end_point = segment.GetStartXY(); if (com.epl.geometry.Point2D.SqrDistance(pt, end_point) <= tolerance_cluster_sq) { return(point.CreateInstance()); } end_point = segment.GetEndXY(); if (com.epl.geometry.Point2D.SqrDistance(pt, end_point) <= tolerance_cluster_sq) { return(point.CreateInstance()); } } } return(point); }
public static void TestIntervalTree_RandomConstruction() { int pointcount = 0; int passcount = 1000; int figureSize = 50; com.epl.geometry.Envelope env = new com.epl.geometry.Envelope(); env.SetCoords(-10000, -10000, 10000, 10000); com.epl.geometry.RandomCoordinateGenerator generator = new com.epl.geometry.RandomCoordinateGenerator(System.Math.Max(figureSize, 10000), env, 0.001); System.Random random = new System.Random(2013); int rand_max = 98765; System.Collections.Generic.List <com.epl.geometry.Envelope1D> intervals = new System.Collections.Generic.List <com.epl.geometry.Envelope1D>(); com.epl.geometry.AttributeStreamOfInt8 intervalsFound = new com.epl.geometry.AttributeStreamOfInt8(0); for (int i = 0; i < passcount; i++) { int r = figureSize; if (r < 3) { continue; } com.epl.geometry.Polygon poly = new com.epl.geometry.Polygon(); com.epl.geometry.Point pt; for (int j = 0; j < r; j++) { int rand = random.Next(rand_max); bool bRandomNew = (r > 10) && ((1.0 * rand) / rand_max > 0.95); pt = generator.GetRandomCoord(); if (j == 0 || bRandomNew) { poly.StartPath(pt); } else { poly.LineTo(pt); } } { intervals.Clear(); com.epl.geometry.SegmentIterator seg_iter = poly.QuerySegmentIterator(); com.epl.geometry.Envelope1D interval; com.epl.geometry.Envelope1D range = poly.QueryInterval(com.epl.geometry.VertexDescription.Semantics.POSITION, 0); range.vmin -= 0.01; range.vmax += 0.01; while (seg_iter.NextPath()) { while (seg_iter.HasNextSegment()) { com.epl.geometry.Segment segment = seg_iter.NextSegment(); interval = segment.QueryInterval(com.epl.geometry.VertexDescription.Semantics.POSITION, 0); intervals.Add(interval); } } intervalsFound.Resize(intervals.Count, 0); // Just test construction for assertions com.epl.geometry.IntervalTreeImpl intervalTree = new com.epl.geometry.IntervalTreeImpl(true); Construct(intervalTree, intervals); for (int j_1 = 0; j_1 < intervals.Count; j_1++) { intervalTree.Insert(j_1); } com.epl.geometry.IntervalTreeImpl.IntervalTreeIteratorImpl iterator = intervalTree.GetIterator(range, 0.0); int count = 0; int handle; while ((handle = iterator.Next()) != -1) { count++; intervalsFound.Write(handle, unchecked ((byte)1)); } NUnit.Framework.Assert.IsTrue(count == intervals.Count); for (int j_2 = 0; j_2 < intervalsFound.Size(); j_2++) { interval = intervals[j_2]; NUnit.Framework.Assert.IsTrue(intervalsFound.Read(j_2) == 1); } for (int j_3 = 0; j_3 < intervals.Count >> 1; j_3++) { intervalTree.Remove(j_3); } iterator.ResetIterator(range, 0.0); count = 0; while ((handle = iterator.Next()) != -1) { count++; intervalsFound.Write(handle, unchecked ((byte)1)); } NUnit.Framework.Assert.IsTrue(count == intervals.Count - (intervals.Count >> 1)); for (int j_4 = (intervals.Count >> 1); j_4 < intervals.Count; j_4++) { intervalTree.Remove(j_4); } } } }
internal virtual bool RgHelper(com.epl.geometry.RasterizedGeometry2D rg, com.epl.geometry.MultiPath mp) { com.epl.geometry.SegmentIterator iter = mp.QuerySegmentIterator(); while (iter.NextPath()) { while (iter.HasNextSegment()) { com.epl.geometry.Segment seg = iter.NextSegment(); int count = 20; for (int i = 0; i < count; i++) { double t = (1.0 * i / count); com.epl.geometry.Point2D pt = seg.GetCoord2D(t); com.epl.geometry.RasterizedGeometry2D.HitType hit = rg.QueryPointInGeometry(pt.x, pt.y); if (hit != com.epl.geometry.RasterizedGeometry2D.HitType.Border) { return(false); } } } } if (mp.GetType() != com.epl.geometry.Geometry.Type.Polygon) { return(true); } com.epl.geometry.Polygon poly = (com.epl.geometry.Polygon)mp; com.epl.geometry.Envelope2D env = new com.epl.geometry.Envelope2D(); poly.QueryEnvelope2D(env); int count_1 = 100; for (int iy = 0; iy < count_1; iy++) { double ty = 1.0 * iy / count_1; double y = env.ymin * (1.0 - ty) + ty * env.ymax; for (int ix = 0; ix < count_1; ix++) { double tx = 1.0 * ix / count_1; double x = env.xmin * (1.0 - tx) + tx * env.xmax; com.epl.geometry.RasterizedGeometry2D.HitType hit = rg.QueryPointInGeometry(x, y); com.epl.geometry.PolygonUtils.PiPResult res = com.epl.geometry.PolygonUtils.IsPointInPolygon2D(poly, new com.epl.geometry.Point2D(x, y), 0); if (res == com.epl.geometry.PolygonUtils.PiPResult.PiPInside) { bool bgood = (hit == com.epl.geometry.RasterizedGeometry2D.HitType.Border || hit == com.epl.geometry.RasterizedGeometry2D.HitType.Inside); if (!bgood) { return(false); } } else { if (res == com.epl.geometry.PolygonUtils.PiPResult.PiPOutside) { bool bgood = (hit == com.epl.geometry.RasterizedGeometry2D.HitType.Border || hit == com.epl.geometry.RasterizedGeometry2D.HitType.Outside); if (!bgood) { return(false); } } else { bool bgood = (hit == com.epl.geometry.RasterizedGeometry2D.HitType.Border); if (!bgood) { return(false); } } } } } return(true); }
internal virtual void Find_analysis_pair_from_index(com.epl.geometry.Point2D inputPoint, com.epl.geometry.SegmentIterator segIter, int vertexIndex, int pathIndex) { this.m_i1 = this.Find_non_degenerate(segIter, vertexIndex, pathIndex); if (this.m_i1 != -1) { segIter.ResetToVertex(this.m_i1, -1); com.epl.geometry.Segment segment1 = segIter.NextSegment(); double t1 = segment1.GetClosestCoordinate(inputPoint, false); com.epl.geometry.Point2D p1 = segment1.GetCoord2D(t1); double d1 = com.epl.geometry.Point2D.SqrDistance(p1, inputPoint); com.epl.geometry.Point2D pq = new com.epl.geometry.Point2D(); pq.SetCoords(p1); pq.Sub(segment1.GetStartXY()); com.epl.geometry.Point2D pr = new com.epl.geometry.Point2D(); pr.SetCoords(inputPoint); pr.Sub(segment1.GetStartXY()); this.m_bRight1 = (pq.CrossProduct(pr) < 0); this.m_i2 = this.Find_next_non_degenerate(segIter, this.m_i1); if (this.m_i2 != -1) { segIter.ResetToVertex(this.m_i2, -1); com.epl.geometry.Segment segment2 = segIter.NextSegment(); double t2 = segment2.GetClosestCoordinate(inputPoint, false); com.epl.geometry.Point2D p2 = segment2.GetCoord2D(t2); double d2 = com.epl.geometry.Point2D.SqrDistance(p2, inputPoint); if (d2 > d1) { this.m_i2 = -1; } else { pq.SetCoords(p2); pq.Sub(segment2.GetStartXY()); pr.SetCoords(inputPoint); pr.Sub(segment2.GetStartXY()); this.m_bRight2 = (pq.CrossProduct(pr) < 0); } } if (this.m_i2 == -1) { this.m_i2 = this.Find_prev_non_degenerate(segIter, this.m_i1); if (this.m_i2 != -1) { segIter.ResetToVertex(this.m_i2, -1); com.epl.geometry.Segment segment2 = segIter.NextSegment(); double t2 = segment2.GetClosestCoordinate(inputPoint, false); com.epl.geometry.Point2D p2 = segment2.GetCoord2D(t2); double d2 = com.epl.geometry.Point2D.SqrDistance(p2, inputPoint); if (d2 > d1) { this.m_i2 = -1; } else { pq.SetCoords(p2); pq.Sub(segment2.GetStartXY()); pr.SetCoords(inputPoint); pr.Sub(segment2.GetStartXY()); this.m_bRight2 = (pq.CrossProduct(pr) < 0); int itemp = this.m_i1; this.m_i1 = this.m_i2; this.m_i2 = itemp; bool btemp = this.m_bRight1; this.m_bRight1 = this.m_bRight2; this.m_bRight2 = btemp; } } } } }
internal virtual com.epl.geometry.Proximity2DResult MultiPathGetNearestCoordinate(com.epl.geometry.MultiPath geom, com.epl.geometry.Point2D inputPoint, bool bTestPolygonInterior, bool bCalculateLeftRightSide) { if (geom.GetType() == com.epl.geometry.Geometry.Type.Polygon && bTestPolygonInterior) { com.epl.geometry.Envelope2D env = new com.epl.geometry.Envelope2D(); geom.QueryEnvelope2D(env); double tolerance = com.epl.geometry.InternalUtils.CalculateToleranceFromGeometry(null, env, false); com.epl.geometry.PolygonUtils.PiPResult pipResult; if (bCalculateLeftRightSide) { pipResult = com.epl.geometry.PolygonUtils.IsPointInPolygon2D((com.epl.geometry.Polygon)geom, inputPoint, 0.0); } else { pipResult = com.epl.geometry.PolygonUtils.IsPointInPolygon2D((com.epl.geometry.Polygon)geom, inputPoint, tolerance); } if (pipResult != com.epl.geometry.PolygonUtils.PiPResult.PiPOutside) { com.epl.geometry.Proximity2DResult result = new com.epl.geometry.Proximity2DResult(inputPoint, 0, 0.0); if (bCalculateLeftRightSide) { result.SetRightSide(true); } return(result); } } com.epl.geometry.SegmentIterator segIter = geom.QuerySegmentIterator(); com.epl.geometry.Point2D closest = new com.epl.geometry.Point2D(); int closestVertexIndex = -1; int closestPathIndex = -1; double closestDistanceSq = com.epl.geometry.NumberUtils.DoubleMax(); bool bRight = false; int num_candidates = 0; while (segIter.NextPath()) { while (segIter.HasNextSegment()) { com.epl.geometry.Segment segment = segIter.NextSegment(); double t = segment.GetClosestCoordinate(inputPoint, false); com.epl.geometry.Point2D point = segment.GetCoord2D(t); double distanceSq = com.epl.geometry.Point2D.SqrDistance(point, inputPoint); if (distanceSq < closestDistanceSq) { num_candidates = 1; closest = point; closestVertexIndex = segIter.GetStartPointIndex(); closestPathIndex = segIter.GetPathIndex(); closestDistanceSq = distanceSq; } else { if (distanceSq == closestDistanceSq) { num_candidates++; } } } } com.epl.geometry.Proximity2DResult result_1 = new com.epl.geometry.Proximity2DResult(closest, closestVertexIndex, System.Math.Sqrt(closestDistanceSq)); if (bCalculateLeftRightSide) { segIter.ResetToVertex(closestVertexIndex, closestPathIndex); com.epl.geometry.Segment segment = segIter.NextSegment(); bRight = (com.epl.geometry.Point2D.OrientationRobust(inputPoint, segment.GetStartXY(), segment.GetEndXY()) < 0); if (num_candidates > 1) { com.epl.geometry.OperatorProximity2DLocal.Side_helper sideHelper = new com.epl.geometry.OperatorProximity2DLocal.Side_helper(this); sideHelper.Reset(); bRight = sideHelper.Calc_side(inputPoint, bRight, geom, closestVertexIndex, closestPathIndex); } result_1.SetRightSide(bRight); } return(result_1); }
public static void TestRandom() { int passcount = 10; int figureSize = 100; int figureSize2 = 100; com.epl.geometry.Envelope extent1 = new com.epl.geometry.Envelope(); com.epl.geometry.Envelope extent2 = new com.epl.geometry.Envelope(); com.epl.geometry.Envelope extent3 = new com.epl.geometry.Envelope(); com.epl.geometry.Envelope extent4 = new com.epl.geometry.Envelope(); extent1.SetCoords(-10000, 5000, 10000, 25000); // red extent2.SetCoords(-10000, 2000, 10000, 8000); // blue extent3.SetCoords(-10000, -8000, 10000, -2000); // blue extent4.SetCoords(-10000, -25000, 10000, -5000); // red com.epl.geometry.RandomCoordinateGenerator generator1 = new com.epl.geometry.RandomCoordinateGenerator(System.Math.Max(figureSize, 10000), extent1, 0.001); com.epl.geometry.RandomCoordinateGenerator generator2 = new com.epl.geometry.RandomCoordinateGenerator(System.Math.Max(figureSize, 10000), extent2, 0.001); com.epl.geometry.RandomCoordinateGenerator generator3 = new com.epl.geometry.RandomCoordinateGenerator(System.Math.Max(figureSize, 10000), extent3, 0.001); com.epl.geometry.RandomCoordinateGenerator generator4 = new com.epl.geometry.RandomCoordinateGenerator(System.Math.Max(figureSize, 10000), extent4, 0.001); System.Random random = new System.Random(1982); int rand_max = 511; int qCount = 0; int eCount = 0; int bCount = 0; for (int c = 0; c < passcount; c++) { com.epl.geometry.Polygon polyRed = new com.epl.geometry.Polygon(); com.epl.geometry.Polygon polyBlue = new com.epl.geometry.Polygon(); int r = figureSize; if (r < 3) { continue; } com.epl.geometry.Point pt; for (int j = 0; j < r; j++) { int rand = random.Next(rand_max); bool bRandomNew = (r > 10) && ((1.0 * rand) / rand_max > 0.95); pt = generator1.GetRandomCoord(); if (j == 0 || bRandomNew) { polyRed.StartPath(pt); } else { polyRed.LineTo(pt); } } for (int j_1 = 0; j_1 < r; j_1++) { int rand = random.Next(rand_max); bool bRandomNew = (r > 10) && ((1.0 * rand) / rand_max > 0.95); pt = generator4.GetRandomCoord(); if (j_1 == 0 || bRandomNew) { polyRed.StartPath(pt); } else { polyRed.LineTo(pt); } } r = figureSize2; if (r < 3) { continue; } for (int j_2 = 0; j_2 < r; j_2++) { int rand = random.Next(rand_max); bool bRandomNew = (r > 10) && ((1.0 * rand) / rand_max > 0.95); pt = generator2.GetRandomCoord(); if (j_2 == 0 || bRandomNew) { polyBlue.StartPath(pt); } else { polyBlue.LineTo(pt); } } for (int j_3 = 0; j_3 < r; j_3++) { int rand = random.Next(rand_max); bool bRandomNew = (r > 10) && ((1.0 * rand) / rand_max > 0.95); pt = generator3.GetRandomCoord(); if (j_3 == 0 || bRandomNew) { polyBlue.StartPath(pt); } else { polyBlue.LineTo(pt); } } com.epl.geometry.Envelope2D env = new com.epl.geometry.Envelope2D(); // Quad_tree com.epl.geometry.QuadTree quadTree = BuildQuadTree(polyBlue); com.epl.geometry.QuadTree.QuadTreeIterator iterator = quadTree.GetIterator(); com.epl.geometry.SegmentIteratorImpl _segIterRed = ((com.epl.geometry.MultiPathImpl)polyRed._getImpl()).QuerySegmentIterator(); while (_segIterRed.NextPath()) { while (_segIterRed.HasNextSegment()) { com.epl.geometry.Segment segmentRed = _segIterRed.NextSegment(); segmentRed.QueryEnvelope2D(env); iterator.ResetIterator(env, 0.001); while (iterator.Next() != -1) { qCount++; } } } // Envelope_2D_intersector System.Collections.Generic.List <com.epl.geometry.Envelope2D> envelopes_red = new System.Collections.Generic.List <com.epl.geometry.Envelope2D>(); System.Collections.Generic.List <com.epl.geometry.Envelope2D> envelopes_blue = new System.Collections.Generic.List <com.epl.geometry.Envelope2D>(); com.epl.geometry.SegmentIterator segIterRed = polyRed.QuerySegmentIterator(); while (segIterRed.NextPath()) { while (segIterRed.HasNextSegment()) { com.epl.geometry.Segment segment = segIterRed.NextSegment(); env = new com.epl.geometry.Envelope2D(); segment.QueryEnvelope2D(env); envelopes_red.Add(env); } } com.epl.geometry.SegmentIterator segIterBlue = polyBlue.QuerySegmentIterator(); while (segIterBlue.NextPath()) { while (segIterBlue.HasNextSegment()) { com.epl.geometry.Segment segment = segIterBlue.NextSegment(); env = new com.epl.geometry.Envelope2D(); segment.QueryEnvelope2D(env); envelopes_blue.Add(env); } } com.epl.geometry.Envelope2DIntersectorImpl intersector = new com.epl.geometry.Envelope2DIntersectorImpl(); intersector.SetTolerance(0.001); intersector.StartRedConstruction(); for (int i = 0; i < envelopes_red.Count; i++) { intersector.AddRedEnvelope(i, envelopes_red[i]); } intersector.EndRedConstruction(); intersector.StartBlueConstruction(); for (int i_1 = 0; i_1 < envelopes_blue.Count; i_1++) { intersector.AddBlueEnvelope(i_1, envelopes_blue[i_1]); } intersector.EndBlueConstruction(); while (intersector.Next()) { eCount++; } NUnit.Framework.Assert.IsTrue(qCount == eCount); } }
// resets Iterators if they are used. private bool WeakIntersectionTest_(com.epl.geometry.Geometry geometryA, com.epl.geometry.Geometry geometryB, com.epl.geometry.SegmentIterator segIterA, com.epl.geometry.SegmentIterator segIterB) { /* const */ /* const */ if (geometryA.GetType() == com.epl.geometry.Geometry.Type.Polygon) { // test PolygonA vs. first segment of each of geometryB's paths while (segIterB.NextPath()) { if (segIterB.HasNextSegment()) { /* const */ com.epl.geometry.Segment segmentB = segIterB.NextSegment(); if (com.epl.geometry.PolygonUtils.IsPointInPolygon2D((com.epl.geometry.Polygon)geometryA, segmentB.GetEndXY(), 0) != com.epl.geometry.PolygonUtils.PiPResult.PiPOutside) { return(true); } } } segIterB.ResetToFirstPath(); } if (geometryB.GetType() == com.epl.geometry.Geometry.Type.Polygon) { // test PolygonB vs. first segment of each of geometryA's paths while (segIterA.NextPath()) { if (segIterA.HasNextSegment()) { /* const */ com.epl.geometry.Segment segmentA = segIterA.NextSegment(); if (com.epl.geometry.PolygonUtils.IsPointInPolygon2D((com.epl.geometry.Polygon)geometryB, segmentA.GetEndXY(), 0) != com.epl.geometry.PolygonUtils.PiPResult.PiPOutside) { return(true); } } } segIterA.ResetToFirstPath(); } return(false); }
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)); }
public static void TestQuadTreeWithDuplicates() { int pass_count = 10; int figure_size = 400; int figure_size2 = 100; com.epl.geometry.Envelope extent1 = new com.epl.geometry.Envelope(); extent1.SetCoords(-100000, -100000, 100000, 100000); com.epl.geometry.RandomCoordinateGenerator generator1 = new com.epl.geometry.RandomCoordinateGenerator(System.Math.Max(figure_size, 10000), extent1, 0.001); System.Random random = new System.Random(2013); int rand_max = 32; com.epl.geometry.Polygon poly_red = new com.epl.geometry.Polygon(); com.epl.geometry.Polygon poly_blue = new com.epl.geometry.Polygon(); int r = figure_size; for (int c = 0; c < pass_count; c++) { com.epl.geometry.Point pt; for (int j = 0; j < r; j++) { int rand = random.Next(rand_max); bool b_random_new = r > 10 && ((1.0 * rand) / rand_max > 0.95); pt = generator1.GetRandomCoord(); if (j == 0 || b_random_new) { poly_blue.StartPath(pt); } else { poly_blue.LineTo(pt); } } com.epl.geometry.Envelope2D env = new com.epl.geometry.Envelope2D(); com.epl.geometry.QuadTree quad_tree_blue = BuildQuadTree_((com.epl.geometry.MultiPathImpl)poly_blue._getImpl(), false); com.epl.geometry.QuadTree quad_tree_blue_duplicates = BuildQuadTree_((com.epl.geometry.MultiPathImpl)poly_blue._getImpl(), true); com.epl.geometry.Envelope2D e1 = quad_tree_blue.GetDataExtent(); com.epl.geometry.Envelope2D e2 = quad_tree_blue_duplicates.GetDataExtent(); NUnit.Framework.Assert.IsTrue(e1.Equals(e2)); NUnit.Framework.Assert.IsTrue(quad_tree_blue.GetElementCount() == poly_blue.GetSegmentCount()); com.epl.geometry.SegmentIterator seg_iter_blue = poly_blue.QuerySegmentIterator(); poly_red.SetEmpty(); r = figure_size2; if (r < 3) { continue; } for (int j_1 = 0; j_1 < r; j_1++) { int rand = random.Next(rand_max); bool b_random_new = r > 10 && ((1.0 * rand) / rand_max > 0.95); pt = generator1.GetRandomCoord(); if (j_1 == 0 || b_random_new) { poly_red.StartPath(pt); } else { poly_red.LineTo(pt); } } com.epl.geometry.QuadTree.QuadTreeIterator iterator = quad_tree_blue.GetIterator(); com.epl.geometry.SegmentIteratorImpl seg_iter_red = ((com.epl.geometry.MultiPathImpl)poly_red._getImpl()).QuerySegmentIterator(); System.Collections.Generic.Dictionary <int, bool> map1 = new System.Collections.Generic.Dictionary <int, bool>(0); int count = 0; int intersections_per_query = 0; while (seg_iter_red.NextPath()) { while (seg_iter_red.HasNextSegment()) { com.epl.geometry.Segment segment_red = seg_iter_red.NextSegment(); segment_red.QueryEnvelope2D(env); iterator.ResetIterator(env, 0.0); int count_upper = 0; int element_handle; while ((element_handle = iterator.Next()) != -1) { count_upper++; int index = quad_tree_blue.GetElement(element_handle); bool iter = map1.ContainsKey(index); if (!iter) { count++; map1[index] = true; } intersections_per_query++; } int intersection_count = quad_tree_blue.GetIntersectionCount(env, 0.0, -1); NUnit.Framework.Assert.IsTrue(intersection_count == count_upper); } } seg_iter_red.ResetToFirstPath(); System.Collections.Generic.Dictionary <int, bool> map2 = new System.Collections.Generic.Dictionary <int, bool>(0); com.epl.geometry.QuadTree.QuadTreeIterator iterator_duplicates = quad_tree_blue_duplicates.GetIterator(); int count_duplicates = 0; int intersections_per_query_duplicates = 0; while (seg_iter_red.NextPath()) { while (seg_iter_red.HasNextSegment()) { com.epl.geometry.Segment segment_red = seg_iter_red.NextSegment(); segment_red.QueryEnvelope2D(env); iterator_duplicates.ResetIterator(env, 0.0); int count_lower = 0; System.Collections.Generic.Dictionary <int, bool> map_per_query = new System.Collections.Generic.Dictionary <int, bool>(0); int count_upper = 0; int element_handle; while ((element_handle = iterator_duplicates.Next()) != -1) { count_upper++; int index = quad_tree_blue_duplicates.GetElement(element_handle); bool iter = map2.ContainsKey(index); if (!iter) { count_duplicates++; map2[index] = true; } bool iter_lower = map_per_query.ContainsKey(index); if (!iter_lower) { count_lower++; intersections_per_query_duplicates++; map_per_query[index] = true; } int q = quad_tree_blue_duplicates.GetQuad(element_handle); NUnit.Framework.Assert.IsTrue(quad_tree_blue_duplicates.GetSubTreeElementCount(q) >= quad_tree_blue_duplicates.GetContainedSubTreeElementCount(q)); } int intersection_count = quad_tree_blue_duplicates.GetIntersectionCount(env, 0.0, -1); bool b_has_data = quad_tree_blue_duplicates.HasData(env, 0.0); NUnit.Framework.Assert.IsTrue(b_has_data || intersection_count == 0); NUnit.Framework.Assert.IsTrue(count_lower <= intersection_count && intersection_count <= count_upper); NUnit.Framework.Assert.IsTrue(count_upper <= 4 * count_lower); } } NUnit.Framework.Assert.IsTrue(count == count_duplicates); NUnit.Framework.Assert.IsTrue(intersections_per_query == intersections_per_query_duplicates); } }
private com.epl.geometry.Geometry DensifyMultiPath(com.epl.geometry.MultiPath geom) { com.epl.geometry.MultiPath densifiedPoly = (com.epl.geometry.MultiPath)geom.CreateInstance(); com.epl.geometry.SegmentIterator iter = geom.QuerySegmentIterator(); while (iter.NextPath()) { bool bStartNewPath = true; while (iter.HasNextSegment()) { com.epl.geometry.Segment seg = iter.NextSegment(); if (seg.GetType().Value() != com.epl.geometry.Geometry.GeometryType.Line) { throw new com.epl.geometry.GeometryException("not implemented"); } bool bIsClosing = iter.IsClosingSegment(); double len = seg.CalculateLength2D(); if (len > m_maxLength) { // need to split double dcount = System.Math.Ceiling(len / m_maxLength); com.epl.geometry.Point point = new com.epl.geometry.Point(geom.GetDescription()); // LOCALREFCLASS1(Point, // VertexDescription, // point, // geom.getDescription()); if (bStartNewPath) { bStartNewPath = false; seg.QueryStart(point); densifiedPoly.StartPath(point); } double dt = 1.0 / dcount; double t = dt; for (int i = 0, n = (int)dcount - 1; i < n; i++) { seg.QueryCoord(t, point); densifiedPoly.LineTo(point); t += dt; } if (!bIsClosing) { seg.QueryEnd(point); densifiedPoly.LineTo(point); } else { densifiedPoly.ClosePathWithLine(); } bStartNewPath = false; } else { if (!bIsClosing) { densifiedPoly.AddSegment(seg, bStartNewPath); } else { densifiedPoly.ClosePathWithLine(); } bStartNewPath = false; } } } return((com.epl.geometry.Geometry)densifiedPoly); }