示例#1
0
        /// <summary>
        /// Visits all pairs of crossing edges in the given S2ShapeIndex, terminating
        /// early if the given EdgePairVisitor function returns false (in which case
        /// VisitCrossings returns false as well).  "type" indicates whether all
        /// crossings should be visited, or only interior crossings.
        ///
        /// If "need_adjacent" is false, then edge pairs of the form (AB, BC) may
        /// optionally be ignored (even if the two edges belong to different edge
        /// chains).  This option exists for the benefit of FindSelfIntersection(),
        /// which does not need such edge pairs (see below).
        /// </summary>
        private static bool VisitCrossings(S2ShapeIndex index, CrossingType type, bool need_adjacent, EdgePairVisitor visitor)
        {
            // TODO(ericv): Use brute force if the total number of edges is small enough
            // (using a larger threshold if the S2ShapeIndex is not constructed yet).
            var count = index.GetEnumerableCount();

            for (var pos = 0; pos < count; pos++)
            {
                var shape_edges = new ShapeEdgeVector();
                var icell       = index.GetIndexCell(pos);
                var indexCell   = icell.Value.Item2;
                GetShapeEdges(index, indexCell, shape_edges);
                if (!VisitCrossings(shape_edges, type, need_adjacent, visitor))
                {
                    return(false);
                }
            }
            return(true);
        }
示例#2
0
        /// <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);
        }
示例#3
0
 // 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);
 }
示例#4
0
 /// <summary>
 /// Returns a vector containing all edges in the given S2ShapeIndexCell vector.
 /// (The result is returned as an output parameter so that the same storage can
 /// be reused, rather than allocating a new temporary vector each time.)
 /// </summary>
 private static void GetShapeEdges(S2ShapeIndex index, List <S2ShapeIndexCell> cells, ShapeEdgeVector shape_edges)
 {
     shape_edges.Clear();
     foreach (var cell in cells)
     {
         AppendShapeEdges(index, cell, shape_edges);
     }
 }
示例#5
0
 /// <summary>
 /// Returns a vector containing all edges in the given S2ShapeIndexCell.
 /// (The result is returned as an output parameter so that the same storage can
 /// be reused, rather than allocating a new temporary vector each time.)
 /// </summary>
 private static void GetShapeEdges(S2ShapeIndex index, S2ShapeIndexCell cell, ShapeEdgeVector shape_edges)
 {
     shape_edges.Clear();
     AppendShapeEdges(index, cell, shape_edges);
 }
示例#6
0
 /// <summary>
 /// Appends all edges in the given S2ShapeIndexCell to the given vector.
 /// </summary>
 private static void AppendShapeEdges(S2ShapeIndex index, S2ShapeIndexCell cell, ShapeEdgeVector shape_edges)
 {
     for (int s = 0; s < cell.NumClipped(); ++s)
     {
         var clipped   = cell.Clipped(s);
         var shape     = index.Shape(clipped.ShapeId);
         var num_edges = clipped.NumEdges;
         for (int i = 0; i < num_edges; i++)
         {
             shape_edges.Add(new ShapeEdge(shape, clipped.Edge(i)));
         }
     }
 }