예제 #1
0
 /*---------------------------------------------------------------------
  * Returns TRUE iff (a,b) is a proper internal diagonal.
  */
 public bool Diagonal(cVertex a, cVertex b)
 {
     return(InCone(a, b) && InCone(b, a) && Diagonalie(a, b));
 }
예제 #2
0
        //**************************************

        public bool Solven(double x, double y)

        /*Is called when the user drags the last point of the link or releases it.
         * Corresponds to the Solven method in C*/
        {
            double  halfLength; //floor of half os total
            cPointi target;     //point for storing the target
            cPointd Jk;         // coords of kinked joint returned by Solve2



            //create target
            target = new cPointi(x, y);

            //Compute Length array and # of links
            v1 = list.head;

            for (i = 0; i < list.n - 1; i++)
            {
                linklen[i] = (Length(v1.Point, v1.NextVertex.Point) + .5);
                v1         = v1.NextVertex;
            }
            nlinks = list.n - 1;


            //Compute total&half Length

            totLength = 0;

            for (i = 0; i < nlinks; i++)
            {
                totLength += linklen[i];
            }
            halfLength = totLength / 2;

            //Find median link
            if (nlinks > 2)
            {
                L1 = 0;
                for (m = 0; m < nlinks; m++)
                {
                    if ((L1 + linklen[m]) > halfLength)
                    {
                        break;
                    }
                    L1 += linklen[m];
                }//end for

                L2         = linklen[m];
                L3         = totLength - L1 - L2;
                firstlinks = m;
                for (i = 0; i < nlinks; i++)
                {
                    linklenback[i] = linklen[i];
                }
                nlinksback = nlinks;
            }
            else if (nlinks == 2)
            {
                L1 = linklen[0];
                L2 = linklen[1];
                L3 = 0;
            }
            else
            {
                System.Diagnostics.Debug.WriteLine("Just one link!!!");
                L1 = L2 = L3 = 0;
            }

            if ((nlinks == 3) && (nlinksback == 0))
            {
                nlinksback = 3;
            }
            if (nlinks == 2)
            {
                Jk = new cPointd(0, 0);
                if (Solve2(L1, L2, target, Jk))
                {
                    System.Diagnostics.Debug.WriteLine("Solve2 for 2 links: link1= " + L1 + ", link2= " + L2 + ", joint=\n");
                    LineTo_d(Jk);
                    SetAChain(Jk, target);
                    return(true);
                }
                else
                {
                    return(false);
                }
            }//end if nlinks==2
            else
            {
                if (Solve3(L1, L2, L3, target))
                {
                    return(true);
                }
                else
                {
                    return(false);
                }
            }
        }//end Solve
예제 #3
0
 private void Push(cVertex p, cVertexList top)
 {
     //simulating a stack behavior for cVertexList list
     //Push procedure
     top.InsertBeforeHead(p);
 }
예제 #4
0
        /*See Chapter 7 for an explanation of this code
         * The only modification we make is that the polygon is *not* translated
         * to place q=(0,0)
         */
        public char InPoly1(cPointi q)
        {
            int i = 0;//, i1;
            //int d;
            double  x;
            int     Rcross = 0;
            int     Lcross = 0;
            bool    Rstrad, Lstrad;
            cVertex vtemp = list.head;
            cVertex vtemp1;

            vtemp1   = list.head;
            intCount = 0;

            //For each edge e = (i-1,i), see if crosses rays*/
            //This code deviates from that in Chapter 7:
            //the polygon is *not* translated to move q to the origin
            do
            {
                /*First check if q =(0,0) is a vertex.*/
                if (vtemp.Point.X == q.X && vtemp.Point.Y == q.Y)
                {
                    return('v');
                }

                vtemp1 = new cVertex();
                vtemp1 = vtemp.PrevVertex;

                /*Check if e straddles x-axis, with bias above/below.*/
                Rstrad = ((vtemp.Point.Y - q.Y) > 0) != ((vtemp1.Point.Y - q.Y) > 0);
                Lstrad = ((vtemp.Point.Y - q.Y) < 0) != ((vtemp1.Point.Y - q.Y) < 0);

                if (Rstrad || Lstrad)
                {
                    /*Compute intersection of e with x-axis.*/
                    x = ((vtemp.Point.X - q.X) * (vtemp1.Point.Y - q.Y) -
                         (vtemp1.Point.X - q.X) * (vtemp.Point.Y - q.Y))
                        / (double)((vtemp1.Point.Y - q.Y) - (vtemp.Point.Y - q.Y));
                    /* saving the x-coordinates for the intersections;*/
                    inters[intCount] = (double)x + q.X;
                    intCount        += 1;

                    if (Rstrad && x > 0)
                    {
                        Rcross++;
                    }
                    if (Lstrad && x < 0)
                    {
                        Lcross++;
                    }
                }
                vtemp = vtemp.NextVertex;
                i++;
            } while (vtemp != list.head);

            /*q on an edge if L/Rcross counts are not the same parity*/
            if ((Rcross % 2) != (Lcross % 2))
            {
                return('e');
            }
            /*q inside iff an odd number of crossings*/
            if ((Rcross % 2) == 1)
            {
                return('i');
            }
            else
            {
                return('o');
            }
        }
예제 #5
0
 public cVertexList()
 {
     head = null;
     n    = 0;
 }
예제 #6
0
        /* Function used for Sort2
         */
        private int Compare2(cVertex tpi, cVertex tpj)
        {
            int     a = 0;        /* TriangleSign result */
            double  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 */
            }
        }
예제 #7
0
        public void SetVertex3D(double x, double y, double z)
        {
            cVertex v = new cVertex(x, y, z);

            InsertBeforeHead(v);
        }
예제 #8
0
 public void ResetVertex(cVertex resV, double x, double y)
 {
     resV.Point.X = x;
     resV.Point.Y = y;
 }
예제 #9
0
        public void SetVertex(double x, double y)
        {
            cVertex v = new cVertex(x, y);

            InsertBeforeHead(v);
        }
예제 #10
0
        /*---------------------------------------------------------------------
        * Consult the book for explanations
        *--------------------------------------------------------------------*/
        private void ConvexIntersect(cVertexList P, cVertexList Q, int n, int m)
        /* P has n vertices, Q has m vertices. */
        {
            /* 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;
            }
        }
예제 #11
0
        private void InsertInters(double x, double y)
        {
            cVertex v = new cVertex((int)x, (int)y);

            inters.InsertBeforeHead(v);
        }
예제 #12
0
        private int ReadVertices()
        {
            cVertex v = P.head;
            int i = 0;
            do
            {
                v.IndexInModel = i++;
                v.IsProcessed = true;
                v = v.NextVertex;
            } while (v != P.head);

            v = B.head;
            do
            {
                cVertex temp = new cVertex(v.Point.X, v.Point.Y);
                P.InsertBeforeHead(temp);
                v = v.NextVertex;
            } while (v != B.head);

            v = P.GetElement(n); i = 0;
            do
            {
                /* Reflect secondary polygon */
                v.Point.X = -v.Point.X;
                v.Point.Y = -v.Point.Y;
                v.IndexInModel = i++;
                v.IsProcessed = false;
                v = v.NextVertex;
            } while (v != P.head);

            double xmin, ymin, xmax, ymax;     /* Primary min & max */
            double sxmin, symin, sxmax, symax; /* Secondary min & max */
            int mp, ms;   /* i index of max (u-r) primary and secondary points */
            xmin = ymin = xmax = ymax = 0;
            sxmin = symin = sxmax = symax = 0;
            mp = ms = 0; v = P.head;
            xmin = xmax = v.Point.X;
            ymin = ymax = v.Point.Y;
            mp = 0; i = 1;
            v = v.NextVertex;
            cVertex startB = P.GetElement(n);
            do
            {
                if (v.Point.X > xmax) xmax = v.Point.X;
                else if (v.Point.X < xmin) xmin = v.Point.X;
                if (v.Point.Y > ymax) { ymax = v.Point.Y; mp = i; }
                else if (v.Point.Y == ymax && (v.Point.X > P.GetElement(mp).Point.X)) mp = i;
                else if (v.Point.Y < ymin) ymin = v.Point.Y;
                v = v.NextVertex; i++;
            } while (v != startB);
            /*System.Diagnostics.Debug.WriteLine("Index of upper rightmost primary, i=mp = "+mp);*/
            v = startB;
            sxmin = sxmax = v.Point.X;
            symin = symax = v.Point.Y;
            ms = n; v = v.NextVertex; i = 1;
            do
            {
                if (v.Point.X > sxmax) sxmax = v.Point.X;
                else if (v.Point.X < sxmin) sxmin = v.Point.X;
                if (v.Point.Y > symax) { symax = v.Point.Y; ms = i; }
                else if (v.Point.Y == symax && (v.Point.X > P.GetElement(ms).Point.X)) ms = i;
                else if (v.Point.Y < symin) symin = v.Point.Y;
                v = v.NextVertex; i++;
            } while (v != P.head.NextVertex);
            /*System.Diagnostics.Debug.WriteLine("Index of upper rightmost secondary, i=ms = "+ms);*/

            /* Compute the start point: upper rightmost of both. */
            System.Diagnostics.Debug.WriteLine("p0:");
            p0.PrintPoint();
            System.Diagnostics.Debug.WriteLine("mp is: " + mp);
            System.Diagnostics.Debug.WriteLine("mp element:" + P.GetElement(mp).Point.X + "," + P.GetElement(mp).Point.Y);
            AddVec(p0, P.GetElement(mp).Point, p0);
            System.Diagnostics.Debug.WriteLine("p0 after addvec:");
            p0.PrintPoint();
            System.Diagnostics.Debug.WriteLine("ms is: " + ms);
            System.Diagnostics.Debug.WriteLine("ms element:" + P.GetElement(ms).Point.X + "," + P.GetElement(ms).Point.Y);
            //   AddVec( p0, P.GetElement(ms).v, p0 );
            System.Diagnostics.Debug.WriteLine("p0 after another addvec:");
            p0.PrintPoint();
            return mp;
        }
예제 #13
0
 private void PutInOutput(double x, double y)
 {
     cVertex v = new cVertex(x, y);
     output.InsertBeforeHead(v);
 }