Esempio n. 1
0
        /* Function used for Sort2
         */
        private int Compare2(cVertex tpi, cVertex tpj)
        {
            int     a = 0;        /* TriangleSign result */
            float   x = 0, y = 0; /* projections in 1st quadrant */
            cVertex pi, pj;

            pi = tpi;
            pj = tpj;
            cPointi Origin = new cPointi();

            /* A vector in the open   upper halfplane is after
             * a vector in the closed lower halfplane. */
            if ((pi.Point.Y > 0) && (pj.Point.Y <= 0))
            {
                return(1);
            }
            else if ((pi.Point.Y <= 0) && (pj.Point.Y > 0))
            {
                return(-1);
            }

            /* A vector on the x-axis and one in the lower halfplane
             * are handled by the Left computation below. */

            /* Both vectors on the x-axis requires special handling. */
            else if ((pi.Point.Y == 0) && (pj.Point.Y == 0))
            {
                if ((pi.Point.X < 0) && (pj.Point.X > 0))
                {
                    return(-1);
                }
                if ((pi.Point.X > 0) && (pj.Point.X < 0))
                {
                    return(1);
                }
                else if (Math.Abs(pi.Point.X) < Math.Abs(pj.Point.X))
                {
                    return(-1);
                }
                else if (Math.Abs(pi.Point.X) > Math.Abs(pj.Point.X))
                {
                    return(1);
                }
                else
                {
                    return(0);
                }
            }

            /* Otherwise, both in open upper halfplane,
             * or both in closed lower halfplane, but not both on x-axis. */
            else
            {
                a = Origin.TriangleSign(Origin, pi.Point, pj.Point);
                if (a > 0)
                {
                    return(-1);
                }
                else if (a < 0)
                {
                    return(1);
                }
                else
                { /* Begin collinear */
                    x = Math.Abs(pi.Point.X) - Math.Abs(pj.Point.X);
                    y = Math.Abs(pi.Point.Y) - Math.Abs(pj.Point.Y);

                    if ((x < 0) || (y < 0))
                    {
                        return(-1);
                    }
                    else if ((x > 0) || (y > 0))
                    {
                        return(1);
                    }
                    else /* points are coincident */
                    {
                        return(0);
                    }
                } /* End collinear */
            }
        }
Esempio n. 2
0
        /*---------------------------------------------------------------------
        * Consult the book for explanations
        *--------------------------------------------------------------------*/
        private void ConvexIntersect(cVertexList P, cVertexList Q, int n, int m)
        /* P has n pointCloud, Q has m pointCloud. */
        {
            /* Initialize variables. */
            a          = new cVertex();
            b          = new cVertex();
            a          = P.head; b = Q.head;
            aa         = ba = 0;
            Origin     = new cPointi(); /* (0,0) */
            inflag     = new cInFlag();
            FirstPoint = true;
            cVertex a1, b1;

            A  = new cPointi();
            B  = new cPointi();
            p  = new cPointd();
            q  = new cPointd();
            p0 = new cPointd();

            do
            {
                /* System.Diagnostics.Debug.WriteLine("Before Advances:a="+a.v.x+","+a.v.y+
                 * ", b="+b.v.x+","+b.v.y+"; aa="+aa+", ba="+ba+"; inflag="+
                 * inflag.f); */
                /* Computations of key variables. */
                a1 = a.PrevVertex;
                b1 = b.PrevVertex;

                SubVec(a.Point, a1.Point, A);
                SubVec(b.Point, b1.Point, B);

                cross = Origin.TriangleSign(Origin, A, B);
                aHB   = b1.Point.TriangleSign(b1.Point, b.Point, a.Point);
                bHA   = a1.Point.TriangleSign(a1.Point, a.Point, b.Point);
                System.Diagnostics.Debug.WriteLine("cross=" + cross + ", aHB=" + aHB + ", bHA=" + bHA);

                /* If A & B intersect, update inflag. */
                code = a1.Point.SegSegInt(a1.Point, a.Point, b1.Point, b.Point, p, q);
                System.Diagnostics.Debug.WriteLine("SegSegInt: code = " + code);

                if (code == '1' || code == 'v')
                {
                    if (inflag.f == cInFlag.Unknown && FirstPoint)
                    {
                        aa         = ba = 0;
                        FirstPoint = false;
                        p0.x       = p.x; p0.y = p.y;
                        InsertInters(p0.x, p0.y);
                    }
                    inflag = InOut(p, inflag, aHB, bHA);
                    System.Diagnostics.Debug.WriteLine("InOut sets inflag=" + inflag.f);
                }

                /*-----Advance rules-----*/

                /* Special case: A & B overlap and oppositely oriented. */
                if ((code == 'e') && (Dot(A, B) < 0))
                {
                    InsertSharedSeg(p, q);
                    return;
                }

                /* Special case: A & B parallel and separated. */
                if ((cross == 0) && (aHB < 0) && (bHA < 0))
                {
                    System.Diagnostics.Debug.WriteLine("P and Q are disjoint.");
                    return;
                }


                /* Special case: A & B collinear. */
                else if ((cross == 0) && (aHB == 0) && (bHA == 0))
                {
                    /* Advance but do not output point. */
                    if (inflag.f == cInFlag.Pin)
                    {
                        b = Advance(b, "ba", inflag.f == cInFlag.Qin, b.Point);
                    }
                    else
                    {
                        a = Advance(a, "aa", inflag.f == cInFlag.Pin, a.Point);
                    }
                }

                /* Generic cases. */
                else if (cross >= 0)
                {
                    if (bHA > 0)
                    {
                        a = Advance(a, "aa", inflag.f == cInFlag.Pin, a.Point);
                    }
                    else
                    {
                        b = Advance(b, "ba", inflag.f == cInFlag.Qin, b.Point);
                    }
                }
                else /* if ( cross < 0 ) */
                {
                    if (aHB > 0)
                    {
                        b = Advance(b, "ba", inflag.f == cInFlag.Qin, b.Point);
                    }
                    else
                    {
                        a = Advance(a, "aa", inflag.f == cInFlag.Pin, a.Point);
                    }
                }
                System.Diagnostics.Debug.WriteLine("After advances:a=(" + a.Point.X + ", " + a.Point.Y +
                                                   "), b=(" + b.Point.X + ", " + b.Point.Y + "); aa=" + aa +
                                                   ", ba=" + ba + "; inflag=" + inflag.f);

                /* Quit when both adv. indices have cycled, or one has cycled twice. */
            } while (((aa < n) || (ba < m)) && (aa < 2 * n) && (ba < 2 * m));

            if (!FirstPoint) /* If at least one point output, close up. */
            {
                InsertInters(p0.x, p0.y);
            }

            /* Deal with special cases: not implemented. */
            if (inflag.f == cInFlag.Unknown)
            {
                System.Diagnostics.Debug.WriteLine("The boundaries of P and Q do not cross.");
                intersection = false;
            }
        }