Example #1
0
        /**
         * This function handles the "slow path" of robustCrossing().
         */

        private int RobustCrossingInternal(S2Point d)
        {
            // ACB and BDA have the appropriate orientations, so now we check the
            // triangles CBD and DAC.
            var cCrossD = S2Point.CrossProd(c, d);
            var cbd     = -S2.RobustCcw(c, d, b, cCrossD);

            if (cbd != acb)
            {
                return(-1);
            }

            var dac = S2.RobustCcw(c, d, a, cCrossD);

            return((dac == acb) ? 1 : -1);
        }
Example #2
0
        /**
         * Like SimpleCrossing, except that points that lie exactly on a line are
         * arbitrarily classified as being on one side or the other (according to the
         * rules of S2.robustCCW). It returns +1 if there is a crossing, -1 if there
         * is no crossing, and 0 if any two vertices from different edges are the
         * same. Returns 0 or -1 if either edge is degenerate. Properties of
         * robustCrossing:
         *
         *  (1) robustCrossing(b,a,c,d) == robustCrossing(a,b,c,d) (2)
         * robustCrossing(c,d,a,b) == robustCrossing(a,b,c,d) (3)
         * robustCrossing(a,b,c,d) == 0 if a==c, a==d, b==c, b==d (3)
         * robustCrossing(a,b,c,d) <= 0 if a==b or c==d
         *
         *  Note that if you want to check an edge against a *chain* of other edges,
         * it is much more efficient to use an EdgeCrosser (above).
         */

        public static int RobustCrossing(S2Point a, S2Point b, S2Point c, S2Point d)
        {
            // For there to be a crossing, the triangles ACB, CBD, BDA, DAC must
            // all have the same orientation (clockwise or counterclockwise).
            //
            // First we compute the orientation of ACB and BDA. We permute the
            // arguments to robustCCW so that we can reuse the cross-product of A and B.
            // Recall that when the arguments to robustCCW are permuted, the sign of the
            // result changes according to the sign of the permutation. Thus ACB and
            // ABC are oppositely oriented, while BDA and ABD are the same.
            var aCrossB = S2Point.CrossProd(a, b);
            var acb     = -S2.RobustCcw(a, b, c, aCrossB);
            var bda     = S2.RobustCcw(a, b, d, aCrossB);

            // If any two vertices are the same, the result is degenerate.
            if ((bda & acb) == 0)
            {
                return(0);
            }

            // If ABC and BDA have opposite orientations (the most common case),
            // there is no crossing.
            if (bda != acb)
            {
                return(-1);
            }

            // Otherwise we compute the orientations of CBD and DAC, and check whether
            // their orientations are compatible with the other two triangles.
            var cCrossD = S2Point.CrossProd(c, d);
            var cbd     = -S2.RobustCcw(c, d, b, cCrossD);

            if (cbd != acb)
            {
                return(-1);
            }

            var dac = S2.RobustCcw(c, d, a, cCrossD);

            return((dac == acb) ? 1 : -1);
        }
Example #3
0
        /**
         * This method is equivalent to calling the S2EdgeUtil.robustCrossing()
         * function (defined below) on the edges AB and CD. It returns +1 if there
         * is a crossing, -1 if there is no crossing, and 0 if two points from
         * different edges are the same. Returns 0 or -1 if either edge is
         * degenerate. As a side effect, it saves vertex D to be used as the next
         * vertex C.
         */

        public int RobustCrossing(S2Point d)
        {
            // For there to be an edge crossing, the triangles ACB, CBD, BDA, DAC must
            // all be oriented the same way (CW or CCW). We keep the orientation
            // of ACB as part of our state. When each new point D arrives, we
            // compute the orientation of BDA and check whether it matches ACB.
            // This checks whether the points C and D are on opposite sides of the
            // great circle through AB.

            // Recall that robustCCW is invariant with respect to rotating its
            // arguments, i.e. ABC has the same orientation as BDA.
            var bda = S2.RobustCcw(a, b, d, aCrossB);
            int result;

            if (bda == -acb && bda != 0)
            {
                // Most common case -- triangles have opposite orientations.
                result = -1;
            }
            else if ((bda & acb) == 0)
            {
                // At least one value is zero -- two vertices are identical.
                result = 0;
            }
            else
            {
                // assert (bda == acb && bda != 0);
                result = RobustCrossingInternal(d); // Slow path.
            }
            // Now save the current vertex D as the next vertex C, and also save the
            // orientation of the new triangle ACB (which is opposite to the current
            // triangle BDA).
            c   = d;
            acb = -bda;
            return(result);
        }
Example #4
0
        /**
         * Call this function when your chain 'jumps' to a new place.
         */

        public void RestartAt(S2Point c)
        {
            this.c = c;
            acb    = -S2.RobustCcw(a, b, c, aCrossB);
        }