/**
         * 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);
            }
        }
        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));
        }
Ejemplo n.º 3
0
        /**
         * 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);
        }
Ejemplo n.º 4
0
        // S2Region interface (see {@code S2Region} for details):

        /** Return a bounding spherical cap. */

        /**
         * The point 'p' does not need to be normalized.
         */

        public bool Contains(S2Point p)
        {
            if (!_bound.Contains(p))
            {
                return(false);
            }

            var inside  = _originInside;
            var origin  = S2.Origin;
            var crosser = new EdgeCrosser(origin, p,
                                          _vertices[_numVertices - 1]);

            // The s2edgeindex library is not optimized yet for long edges,
            // so the tradeoff to using it comes with larger loops.
            if (_numVertices < 2000)
            {
                for (var i = 0; i < _numVertices; i++)
                {
                    inside ^= crosser.EdgeOrVertexCrossing(_vertices[i]);
                }
            }
            else
            {
                var it = GetEdgeIterator(_numVertices);
                it.GetCandidates(origin, p);
                var previousIndex = -2;
                foreach (var ai in it) // it.GetCandidates(origin, p); it.HasNext; it.Next())
                {
                    //var ai = it.Index;
                    if (previousIndex != ai - 1)
                    {
                        crosser.RestartAt(_vertices[ai]);
                    }
                    previousIndex = ai;
                    inside       ^= crosser.EdgeOrVertexCrossing(Vertex(ai + 1));
                }
            }

            return(inside);
        }
        /**
         * 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);
        }