private void assertCrossing(S2Point a, S2Point b, S2Point c, S2Point d, int robust, bool edgeOrVertex, bool simple) { a = S2Point.Normalize(a); b = S2Point.Normalize(b); c = S2Point.Normalize(c); d = S2Point.Normalize(d); compareResult(S2EdgeUtil.RobustCrossing(a, b, c, d), robust); if (simple) { assertEquals(robust > 0, S2EdgeUtil.SimpleCrossing(a, b, c, d)); } var crosser = new EdgeCrosser(a, b, c); compareResult(crosser.RobustCrossing(d), robust); compareResult(crosser.RobustCrossing(c), robust); assertEquals(S2EdgeUtil.EdgeOrVertexCrossing(a, b, c, d), edgeOrVertex); assertEquals(edgeOrVertex, crosser.EdgeOrVertexCrossing(d)); assertEquals(edgeOrVertex, crosser.EdgeOrVertexCrossing(c)); }
/** * Find all points where the polygon B intersects the edge (a0,a1), and add * the corresponding parameter values (in the range [0,1]) to "intersections". */ private static void ClipEdge(S2Point a0, S2Point a1, S2LoopSequenceIndex bIndex, bool addSharedEdges, System.Collections.Generic.ICollection <ParametrizedS2Point> intersections) { var it = new S2EdgeIndex.DataEdgeIterator(bIndex); it.GetCandidates(a0, a1); var crosser = new EdgeCrosser(a0, a1, a0); //S2Point from; var to = default(S2Point); foreach (var index in it) { var previousTo = to; var fromTo = bIndex.EdgeFromTo(index); var from = fromTo.Start; to = fromTo.End; if (previousTo != from) { crosser.RestartAt(from); } var crossing = crosser.RobustCrossing(to); if (crossing < 0) { continue; } AddIntersection(a0, a1, from, to, addSharedEdges, crossing, intersections); } }
/** * This method encapsulates the common code for loop containment and * intersection tests. It is used in three slightly different variations to * implement contains(), intersects(), and containsOrCrosses(). * * In a nutshell, this method checks all the edges of this loop (A) for * intersection with all the edges of B. It returns -1 immediately if any edge * intersections are found. Otherwise, if there are any shared vertices, it * returns the minimum value of the given WedgeRelation for all such vertices * (returning immediately if any wedge returns -1). Returns +1 if there are no * intersections and no shared vertices. */ private int CheckEdgeCrossings(S2Loop b, IWedgeRelation relation) { var it = GetEdgeIterator(b._numVertices); var result = 1; // since 'this' usually has many more vertices than 'b', use the index on // 'this' and loop over 'b' for (var j = 0; j < b.NumVertices; ++j) { var crosser = new EdgeCrosser(b.Vertex(j), b.Vertex(j + 1), Vertex(0)); var previousIndex = -2; it.GetCandidates(b.Vertex(j), b.Vertex(j + 1)); foreach (var i in it) // it.GetCandidates(b.vertex(j), b.vertex(j + 1)); it.HasNext; it.Next()) { // var i = it.Index; if (previousIndex != i - 1) { crosser.RestartAt(Vertex(i)); } previousIndex = i; var crossing = crosser.RobustCrossing(Vertex(i + 1)); if (crossing < 0) { continue; } if (crossing > 0) { return(-1); // There is a proper edge crossing. } if (Vertex(i + 1).Equals(b.Vertex(j + 1))) { result = Math.Min(result, relation.Test( Vertex(i), Vertex(i + 1), Vertex(i + 2), b.Vertex(j), b.Vertex(j + 2))); if (result < 0) { return(result); } } } } return(result); }
/** * If this method returns false, the region does not intersect the given cell. * Otherwise, either region intersects the cell, or the intersection * relationship could not be determined. */ public bool MayIntersect(S2Cell cell) { if (NumVertices == 0) { return(false); } // We only need to check whether the cell contains vertex 0 for correctness, // but these tests are cheap compared to edge crossings so we might as well // check all the vertices. for (var i = 0; i < NumVertices; ++i) { if (cell.Contains(Vertex(i))) { return(true); } } var cellVertices = new S2Point[4]; for (var i = 0; i < 4; ++i) { cellVertices[i] = cell.GetVertex(i); } for (var j = 0; j < 4; ++j) { var crosser = new EdgeCrosser(cellVertices[j], cellVertices[(j + 1) & 3], Vertex(0)); for (var i = 1; i < NumVertices; ++i) { if (crosser.RobustCrossing(Vertex(i)) >= 0) { // There is a proper crossing, or two vertices were the same. return(true); } } } return(false); }