/// <summary> /// Visits all crossings of the current edge with all edges of the given index /// cell of B. Terminates early and returns false if visitor_ returns false. /// </summary> private bool VisitEdgeCellCrossings(ShapeEdge a, S2ShapeIndexCell b_cell) { // Test the current edge of A against all edges of "b_cell". // Note that we need to use a new S2EdgeCrosser (or call Init) whenever we // replace the contents of b_shape_edges_, since S2EdgeCrosser requires that // its S2Point arguments point to values that persist between Init() calls. GetShapeEdges(b_index_, b_cell, b_shape_edges_); var crosser = new S2EdgeCrosser(a.V0, a.V1); foreach (var b in b_shape_edges_) { if (crosser.C == S2Point.Empty || crosser.C != b.V0) { crosser.RestartAt(b.V0); } int sign = crosser.CrossingSign(b.V1); if (sign >= min_crossing_sign_) { if (!VisitEdgePair(a, b, sign == 1)) { return(false); } } } return(true); }
/// <summary> /// Given a vector of edges within an S2ShapeIndexCell, visit all pairs of /// crossing edges (of the given CrossingType). /// </summary> private static bool VisitCrossings(ShapeEdgeVector shape_edges, CrossingType type, bool need_adjacent, EdgePairVisitor visitor) { var min_crossing_sign = type == CrossingType.INTERIOR ? 1 : 0; var num_edges = shape_edges.Count; for (int i = 0; i + 1 < num_edges; i++) { var a = shape_edges[i]; var j = i + 1; // A common situation is that an edge AB is followed by an edge BC. We // only need to visit such crossings if "need_adjacent" is true (even if // AB and BC belong to different edge chains). if (!need_adjacent && a.V1 == shape_edges[j].V0) { j++; if (j >= num_edges) { break; } } var crosser = new S2EdgeCrosser(a.V0, a.V1); for (; j < num_edges; j++) { var b = shape_edges[j]; if (crosser.C == S2Point.Empty || crosser.C != b.V0) { crosser.RestartAt(b.V0); } var sign = crosser.CrossingSign(b.V1); if (sign >= min_crossing_sign) { if (!visitor(a, b, sign == 1)) { return(false); } } } } return(true); }
// Visits all crossings of any edge in "a_edges" with any edge in "b_edges". private bool VisitEdgesEdgesCrossings(ShapeEdgeVector a_edges, ShapeEdgeVector b_edges) { // Test all edges of "a_edges" against all edges of "b_edges". foreach (var a in a_edges) { var crosser = new S2EdgeCrosser(a.V0, a.V1); foreach (var b in b_edges) { if (crosser.C == S2Point.Empty || crosser.C != b.V0) { crosser.RestartAt(b.V0); } int sign = crosser.CrossingSign(b.V1); if (sign >= min_crossing_sign_) { if (!VisitEdgePair(a, b, sign == 1)) { return(false); } } } } return(true); }