Exemplo n.º 1
0
 private cPointi SubVec(cPointi a, cPointi b)
 {
     cPointi c = new cPointi();
     c.X = a.X - b.X;
     c.Y = a.Y - b.Y;
     return c;
 }
Exemplo n.º 2
0
 private cPointi AddVec(cPointi a, cPointi b)
 {
     cPointi c = new cPointi();
     c.X = a.X + b.X;
     c.Y = a.Y + b.Y;
     return c;
 }
Exemplo n.º 3
0
        /*Returns nearest edge to (x,y) by returning prior vertex
         */
        public cVertex GetEdge(double x, double y)
        {
            cVertex vnear = null, vtemp = head;
            double  mindist = 0, dist = -1.0f;
            //int k;
            cPointi p = new cPointi();

            // input query point
            p.X = x;
            p.Y = y;

            if (vtemp == null)
            {
                return(vnear);
            }

            do
            {
                dist = p.DistEdgePoint(vtemp.Point, vtemp.NextVertex.Point, p);
                vtemp.Point.PrintPoint();
                if (vnear == null || dist < mindist)
                {
                    mindist = dist;
                    vnear   = vtemp;
                }
                vtemp = vtemp.NextVertex;
            } while (vtemp != head);

            return(vnear);
        }
Exemplo n.º 4
0
        }//end TwoCircles00

        /*Method used for cretaing the "extra-points" that will be displayed
         * on the screen after the arm is straightened. Called from DrawPoints */

        public cVertexList MakePoints(int lo, int hi1, int hi2, cVertex first, cVertex last, cVertexList listcopy)
        {
            double xaux;                    //auxiliary variable for storin the info
            double lenaux = 0;              //auxiliary variable for storing the Length of the
            //current link
            cPointi v1 = new cPointi(0, 0); //aux variable for computing the values
            //of the new points
            double sum = 0;                 //the sum of the previous link Lengths

            for (i = lo; i < hi1; i++)
            {
                lenaux += linklenback[i];
            }
            sum = 0;

            for (i = lo; i < hi2; i++)
            {
                sum += linklenback[i];
                xaux = sum / (double)lenaux;
                v1.X = (int)(.5 + (1 - xaux) * first.Point.X + xaux * last.Point.X);
                v1.Y = (int)(.5 + (1 - xaux) * first.Point.Y + xaux * last.Point.Y);
                listcopy.SetVertex(v1.X, v1.Y);
            }//end for

            return(listcopy);
        }
Exemplo n.º 5
0
 public cVertex(double i, double j)
 {
     Point      = new cPointi();
     Point.X    = i;
     Point.Y    = j;
     Point.Z    = i * i + j * j;
     PrevVertex = NextVertex = null;
 }
Exemplo n.º 6
0
        /*---------------------------------------------------------------------
        *  Returns the dot product of the two input vectors.
        *  ---------------------------------------------------------------------*/
        private double Dot(cPointi a, cPointi b)
        {
            double sum = 0.0;

            sum = a.X * b.X + a.Y * b.Y;

            return(sum);
        }
Exemplo n.º 7
0
        }//end Solve3

        public bool Solve2(double L1, double L2, cPointi target, cPointd J)
        {
            cPointi c1 = new cPointi(list.head.Point.X, list.head.Point.Y); // center of circle 1
            int     nsoln;                                                  // # of solns: 0,1,2,3(infinite)

            nsoln = TwoCircles(c1, L1, target, L2, J);
            return(nsoln != 0);
        }// end Solve2
Exemplo n.º 8
0
        public double Length(cPointi point1, cPointi point2)

        /*Computes the Length of the link between two points
         * Used for the Solven (and the subsequent) methods.*/
        {
            return(Math.Sqrt((double)Math.Abs(((point1.X - point2.X) * (point1.X - point2.X)
                                               + (point1.Y - point2.Y) * (point1.Y - point2.Y)))));
        }
        /*Centroid of triangle is just an average of vertices
         */
        public cPointi Centroid3(cPointi p1, cPointi p2, cPointi p3)
        {
            cPointi c = new cPointi();

            c.X = p1.X + p2.X + p3.X;
            c.Y = p1.Y + p2.Y + p3.Y;
            return(c);
        }
Exemplo n.º 10
0
 public cVertex(double x, double y, double z)
 {
     Point      = new cPointi();
     Point.X    = x;
     Point.Y    = y;
     Point.Z    = z;
     PrevVertex = NextVertex = null;
 }
Exemplo n.º 11
0
        }//end Solve

        public bool Solve3(double L1, double L2, double L3, cPointi target0)
        {
            cPointi target;
            cPointd Jk;      // coords of kinked joint returned by Solve2
            cPointi J1;      // Joint1 on x-axis
            cPointi Ttarget; // translated target

            target = new cPointi(target0.X, target0.Y);


            System.Diagnostics.Debug.WriteLine("==>Solve3: links = " + L1 + ", " + L2 + ", " + L3);

            Jk = new cPointd(0, 0);

            if (Solve2(L1 + L2, L3, target, Jk))
            {
                firstlinks++;
                nlinks = 2;

                System.Diagnostics.Debug.WriteLine("Solve3: link1=" + (L1 + L2) + ", link2=" + L3 + ", joint=\n");
                LineTo_d(Jk);
                SetAChain(Jk, target);
                return(true);
            }
            else if (Solve2(L1, L2 + L3, target, Jk))
            {
                System.Diagnostics.Debug.WriteLine("Solve3: link1= " + L1 + ", link2= " + (L2 + L3) + ", joint=\n");
                nlinks = 2;
                LineTo_d(Jk);
                SetAChain(Jk, target);
                return(true);
            }
            else
            {   // pin J0 to 0.
                // Shift so J1 is origin.
                //J1.x = L1;   J1.y = 0;
                J1      = new cPointi(L1, 0);
                Ttarget = new cPointi(0, 0);
                SubVec(target, J1, Ttarget);
                if (Solve2(L2, L3, Ttarget, Jk))
                {
                    // Shift solution back to origin.
                    Jk.x += L1;
                    System.Diagnostics.Debug.WriteLine("Solve3: link1=" + L1 + ", link2= " + L2 + ", link3= " + L1 + ", joints=\n");
                    nlinks = 3;
                    LineTo_i(J1);
                    LineTo_d(Jk);
                    SetAChain(Jk, target);
                    cVertex VJ1 = new cVertex(list.head.Point.X + J1.X, list.head.Point.Y);
                    list.InsertBefore(VJ1, list.head.NextVertex);
                    return(true);
                }
                else
                {
                    return(false);
                }
            }
        }//end Solve3
Exemplo n.º 12
0
 public cVertex()
 {
     PrevVertex   = NextVertex = null;
     Point        = new cPointi();
     IndexInModel = 0;
     Edge         = null;
     IsOnHull     = false;
     IsProcessed  = false;
 }
Exemplo n.º 13
0
        //****************************************************

        public double Length2(cPointi v)
        /* Returns the squared distance in between two points*/
        {
            double ss;

            ss = 0;
            ss = (double)(v.X * v.X + v.Y * v.Y);
            return(ss);
        }
        /*---------------------------------------------------------------------
        *  SegSegInt: Finds the point of intersection p between two closed
        *  segments ab and cd.  Returns p and a char with the following meaning:
        *  'e': The segments collinearly overlap, sharing a point.
        *  'v': An endpoint (vertex) of one segment is on the other segment,
        *  but 'e' doesn't hold.
        *  '1': The segments intersect properly (i.e., they share a point and
        *  neither 'v' nor 'e' holds).
        *  '0': The segments do not intersect (i.e., they share no points).
        *  Note that two collinear segments that share just one point, an endpoint
        *  of each, returns 'e' rather than 'v' as one might expect.
        *  ---------------------------------------------------------------------*/
        public char SegSegInt(cPointi a, cPointi b, cPointi c, cPointi d, cPointd p, cPointd q)
        {
            double s, t;       /* The two parameters of the parametric eqns. */
            double num, denom; /* Numerator and denoninator of equations. */
            char   code = '?'; /* Return char characterizing intersection. */

            p.x = p.y = 100.0; /* For testing purposes only... */

            denom = a.X * (double)(d.Y - c.Y) +
                    b.X * (double)(c.Y - d.Y) +
                    d.X * (double)(b.Y - a.Y) +
                    c.X * (double)(a.Y - b.Y);

            /* If denom is zero, then segments are parallel: handle separately. */
            if (denom == 0.0)
            {
                return(ParallelInt(a, b, c, d, p, q));
            }

            num = a.X * (double)(d.Y - c.Y) +
                  c.X * (double)(a.Y - d.Y) +
                  d.X * (double)(c.Y - a.Y);
            if ((num == 0.0) || (num == denom))
            {
                code = 'v';
            }
            s = num / denom;
            System.Diagnostics.Debug.WriteLine("SegSegInt: num=" + num + ",denom=" + denom + ",s=" + s);

            num = -(a.X * (double)(c.Y - b.Y) +
                    b.X * (double)(a.Y - c.Y) +
                    c.X * (double)(b.Y - a.Y));
            if ((num == 0.0) || (num == denom))
            {
                code = 'v';
            }
            t = num / denom;
            System.Diagnostics.Debug.WriteLine("SegSegInt: num=" + num + ",denom=" + denom + ",t=" + t);

            if ((0.0 < s) && (s < 1.0) &&
                (0.0 < t) && (t < 1.0))
            {
                code = '1';
            }
            else if ((0.0 > s) || (s > 1.0) ||
                     (0.0 > t) || (t > 1.0))
            {
                code = '0';
            }

            p.x = a.X + s * (b.X - a.X);
            p.y = a.Y + s * (b.Y - a.Y);

            return(code);
        }
Exemplo n.º 15
0
        public void SetAChain(cPointd Jk, cPointi target)
        {
            cPointi vaux1;
            cPointi vaux2;

            vaux1 = new cPointi(list.head.Point.X, list.head.Point.Y);
            vaux2 = new cPointi(target.X, target.Y);
            list.ClearVertexList();
            list.SetVertex(vaux1.X, vaux1.Y);
            list.SetVertex((int)(Jk.x + .5), (int)(Jk.y + .5));
            list.SetVertex(vaux2.X, vaux2.Y);
        }
 /* Draws a line and the quiry point of the InPoly request
  */
 public void DrawInPoly(System.Drawing.Graphics g, cPointi queryP,
                        int CanW, int CanH, int w, int h)
 {
     //int k;
     //g.setColor(System.Drawing.Color.Black);
     //g.drawLine(0, queryP.y, CanW, queryP.y);
     //for(k = 0; k < intCount; k++)
     //{
     //  g.fillOval(GetInters(k)-(int)(w/2), queryP.y - (int)(h/2), w, h);
     //}
     //g.setColor(System.Drawing.Color.Red);
     //g.fillOval(queryP.x - (int)(w/2), queryP.y - (int)(h/2), w, h);
 }
Exemplo n.º 17
0
        private void Convolve()
        {
            int i = 0;      /* Index into sorted edge vectors P */
            int j = 0;      /* Primary polygon indices */
            cVertex v = P.head;

            System.Diagnostics.Debug.WriteLine("Convolve: Start array i = " + i + ", primary j0=" + j0);
            PutInOutput(p0.X, p0.Y);

            i = 0;  /* Start at angle -pi, rightward vector. */
            j = j0; /* Start searching for j0. */
            v = P.GetElement(i);
            System.Diagnostics.Debug.WriteLine("Convolve, getElement(0)..." + v.Point.X + ", " + v.Point.Y);
            do
            {

                /* Advance around secondary edges until next j reached. */
                while (!(v.IsProcessed && v.IndexInModel == j))
                {
                    if (!v.IsProcessed)
                    {
                        p0 = AddVec(p0, v.Point);
                        PutInOutput(p0.X, p0.Y);
                    }
                    v = v.NextVertex;
                    i = (i + 1) % m;
                    //	System.Diagnostics.Debug.WriteLine("X: i incremented to "+i);
                }

                /* Advance one primary edge. */
                System.Diagnostics.Debug.WriteLine("X: j=" + j + " found at i=" + i);
                p0 = AddVec(p0, v.Point);
                PutInOutput(p0.X, p0.Y);
                j = (j + 1) % n;
                System.Diagnostics.Debug.WriteLine("X: j incremented to " + j);

            } while (j != j0);

            /* Finally, complete circuit on secondary/robot polygon. */
            while (i != 0)
            {
                if (!v.IsProcessed)
                {
                    p0 = AddVec(p0, v.Point);
                    PutInOutput(p0.X, p0.Y);
                }
                i = (i + 1) % m;
            }
            System.Diagnostics.Debug.WriteLine("X: i incremented to " + i + " in  circuit");
        }
        public bool IntersectProp(cPointi a, cPointi b, cPointi c, cPointi d)
        {
            /* Eliminate improper cases. */
            if (
                Collinear(a, b, c) ||
                Collinear(a, b, d) ||
                Collinear(c, d, a) ||
                Collinear(c, d, b))
            {
                return(false);
            }

            return
                (Xor(Left(a, b, c), Left(a, b, d)) &&
                 Xor(Left(c, d, a), Left(c, d, b)));
        }
        /*---------------------------------------------------------------------
        *  Returns TRUE iff point c lies on the closed segement ab.
        *  Assumes it is already known that abc are collinear.
        *  (This is the only difference with Between().)
        *  ---------------------------------------------------------------------*/
        public bool Between1(cPointi a, cPointi b, cPointi c)
        {
            //cPointi ba, ca;

            /* If ab not vertical, check betweenness on x; else on y. */
            if (a.X != b.X)
            {
                return(((a.X <= c.X) && (c.X <= b.X)) ||
                       ((a.X >= c.X) && (c.X >= b.X)));
            }
            else
            {
                return(((a.Y <= c.Y) && (c.Y <= b.Y)) ||
                       ((a.Y >= c.Y) && (c.Y >= b.Y)));
            }
        }
Exemplo n.º 20
0
 /*---------------------------------------------------------------------
 *  Advances and prints out an inside vertex if appropriate.
 *  ---------------------------------------------------------------------*/
 private cVertex Advance(cVertex a, String counter, bool inside, cPointi v)
 {
     if (inside)
     {
         InsertInters(v.X, v.Y);
     }
     if (counter.Equals("aa"))
     {
         aa++;
     }
     else if (counter.Equals("ba"))
     {
         ba++;
     }
     return(a.NextVertex);
 }
Exemplo n.º 21
0
        }// end Solve2

        //---------------------------------------------------------------------
        //TwoCircles finds an intersection point between two circles.
        //General routine: no assumptions. Returns # of intersections; point in p.
        //---------------------------------------------------------------------

        public int TwoCircles(cPointi c1, double r1, cPointi c2, double r2, cPointd p)
        {
            cPointi c;
            cPointd q;
            int     nsoln = -1;

            // Translate so that c1={0,0}.
            c = new cPointi(0, 0);
            SubVec(c2, c1, c);
            q     = new cPointd(0, 0);
            nsoln = TwoCircles0a(r1, c, r2, p);//p instead of

            // Translate back.
            p.x = p.x + c1.X;
            p.y = p.y + c1.Y;
            return(nsoln);
        }
Exemplo n.º 22
0
        }//end TwoCircles0a

        //---------------------------------------------------------------------
        //TwoCircles0b also assumes that the 1st circle is origin-centered.
        //---------------------------------------------------------------------
        public int TwoCircles0b(double r1, cPointi c2, double r2, cPointd p)
        {
            double  a2;         // center of 2nd circle when rotated to x-axis
            cPointd q;          // one solution when c2 on x-axis
            double  cost, sint; // sine and cosine of angle of c2

            // Rotate c2 to a2 on x-axis.
            a2   = Math.Sqrt(Length2(c2));
            cost = c2.X / a2;
            sint = c2.Y / a2;
            q    = new cPointd(0, 0);
            TwoCircles00(r1, a2, r2, q);

            // Rotate back
            p.x = cost * q.x + -sint * q.y;
            p.y = sint * q.x + cost * q.y;

            return(2);
        }
Exemplo n.º 23
0
        /* -------------------------------------------------------------------------
         * The following set of routines compute the (real) intersection point between
         * two segments.  The two segments are taken to be the first four edges of
         * the input "polygon" list.  A character "code" is returned and printed out.
         */
        public char SegSegTopLevel()
        {
            // Set the segments ab and cd to be the first four points in the list.
            cVertex temp = list.head;
            cPointi a    = temp.Point;

            temp = temp.NextVertex;
            cPointi b = temp.Point;

            temp = temp.NextVertex;
            cPointi c = temp.Point;

            temp = temp.NextVertex;
            cPointi d = temp.Point;

            // Store the results in class data field p, and returns code.
            code = a.SegSegInt(a, b, c, d, this.p, q);
            return(code);
        }
Exemplo n.º 24
0
        //---------------------------------------------------------------------
        //TwoCircles0a assumes that the first circle is centered on the origin.
        //Returns # of intersections: 0, 1, 2, 3 (inf); point in p.
        //-----------------------------------------------------------------------
        public int TwoCircles0a(double r1, cPointi c2, double r2, cPointd p)
        {
            double dc2;              // dist to center 2 squared
            double rplus2, rminus2;  // (r1 +/- r2)^2
            double f;                // fraction along c2 for nsoln=1

            // Handle special cases.
            dc2     = Length2(c2);
            rplus2  = (r1 + r2) * (r1 + r2);
            rminus2 = (r1 - r2) * (r1 - r2);

            // No solution if c2 out of reach + or -.
            if ((dc2 > rplus2) || (dc2 < rminus2))
            {
                return(0);
            }

            // One solution if c2 just reached.
            // Then solution is r1-of-the-way (f) to c2.
            if (dc2 == rplus2)
            {
                f   = r1 / (double)(r1 + r2);
                p.x = f * c2.X; p.y = f * c2.Y;
                return(1);
            }
            if (dc2 == rminus2)
            {
                if (rminus2 == 0)
                {   // Circles coincide.
                    p.x = r1; p.y = 0;
                    return(3);
                }
                f   = r1 / (double)(r1 - r2);
                p.x = f * c2.X; p.x = f * c2.Y;
                return(1);
            }
            // Two intersections.

            int auxint = TwoCircles0b(r1, c2, r2, p);

            return(auxint);
        }//end TwoCircles0a
        /*---------------------------------------------------------------------
         * Returns TRUE iff segments ab & cd intersect, properly or improperly.
         */
        public bool Intersect(cPointi a, cPointi b, cPointi c, cPointi d)
        {
            if (IntersectProp(a, b, c, d))
            {
                return(true);
            }

            else if (Between(a, b, c) ||
                     Between(a, b, d) ||
                     Between(c, d, a) ||
                     Between(c, d, b))
            {
                return(true);
            }

            else
            {
                return(false);
            }
        }
        private void Vectorize()
        {
            int     i;
            cVertex v;

            v = P.head;
            System.Diagnostics.Debug.WriteLine("Vectorize: ");
            System.Diagnostics.Debug.WriteLine("list before victorization");
            P.PrintVertices();
            cVertex startB = P.GetElement(n);

            System.Diagnostics.Debug.WriteLine("startB !!!: ");
            startB.PrintVertex();

            SubVec(P.head.Point, startB.PrevVertex.Point, last);
            do
            {
                cPointi c = SubVec(v.NextVertex.Point, v.Point);
                System.Diagnostics.Debug.WriteLine("(" + v.NextVertex.Point.X + "," + v.NextVertex.Point.Y + ") - (" + v.Point.X + "," + v.Point.Y + ")");
                v.Point.X = c.X;
                v.Point.Y = c.Y;
                v         = v.NextVertex;
            } while (v != startB.PrevVertex);
            startB.PrevVertex.Point.X = last.X;
            startB.PrevVertex.Point.Y = last.Y;

            SubVec(startB.Point, P.head.PrevVertex.Point, last);
            v = startB;
            do
            {
                cPointi c = SubVec(v.NextVertex.Point, v.Point);
                System.Diagnostics.Debug.WriteLine("(" + v.NextVertex.Point.X + "," + v.NextVertex.Point.Y + ") - (" + v.Point.X + "," + v.Point.Y + ")");
                v.Point.X = c.X;
                v.Point.Y = c.Y;
                v         = v.NextVertex;
            } while (v != P.head.PrevVertex);
            P.head.PrevVertex.Point.X = last.X;
            P.head.PrevVertex.Point.Y = last.Y;
        }
        public int TriangleSign(cPointi a, cPointi b, cPointi c)
        {
            double area2;

            area2 = (b.X - a.X) * (double)(c.Y - a.Y) -
                    (c.X - a.X) * (double)(b.Y - a.Y);


            /* The area should be an integer. */
            if (area2 > 0.5)
            {
                return(1);
            }
            else if (area2 < -0.5)
            {
                return(-1);
            }
            else
            {
                return(0);
            }
        }
        ///*Returns the distance of the input point
        // *from its perp. proj. to the e1 edge.
        // *Uses method detailed in comp.graphics.algorithms FAQ
        // */
        public double DistEdgePoint(cPointi a, cPointi b, cPointi c)
        {
            double r, s;
            double Length;
            double dproj = 0.0;

            Length = Math.Sqrt(Math.Pow((b.X - a.X), 2) +
                               Math.Pow((b.Y - a.Y), 2));

            if (Length == 0.0)
            {
                System.Diagnostics.Debug.WriteLine("DistEdgePoint: Length = 0");
                a.PrintPoint();
                b.PrintPoint();
                c.PrintPoint();
            }
            r = (((a.Y - c.Y) * (a.Y - b.Y))
                 - ((a.X - c.X) * (b.X - a.X))) / (Length * Length);
            s = (((a.Y - c.Y) * (b.X - a.X))
                 - ((a.X - c.X) * (b.Y - a.Y))) / (Length * Length);

            dproj = Math.Abs(s * Length);

            //    System.Diagnostics.Debug.WriteLine("XI = " + (a.x + r *(b.x-a.x))+" YI = "+(a.y+r*(b.y-a.y)));
            if ((s != 0.0) && ((0.0 <= r) && (r <= 1.0)))
            {
                return(dproj);
            }
            if ((s == 0.0) && Between(a, b, c))
            {
                return(0.0);
            }
            else
            {
                double ca = Dist(a, c);
                double cb = Dist(b, c);
                return(Math.Min(ca, cb));
            }
        }
        /* Finds polygon's center of gravity */
        public void FindCG()
        {
            double  A2, areaSum2 = 0;   //partial area sum
            cPointi Cent3  = new cPointi();
            cVertex temp   = list.head;
            cPointi fixedv = list.head.Point;

            this.CG.x = 0;
            this.CG.y = 0;

            do
            {
                Cent3     = fixedv.Centroid3(fixedv, temp.Point, temp.NextVertex.Point);
                A2        = fixedv.Triangle2(fixedv, temp.Point, temp.NextVertex.Point);
                this.CG.x = CG.x + (A2 * Cent3.X);
                this.CG.y = CG.y + (A2 * Cent3.Y);
                areaSum2  = areaSum2 + A2;
                temp      = temp.NextVertex;
            } while (temp != list.head.PrevVertex);
            //Division by 3 is delayed to the last moment.
            this.CG.x = this.CG.x / (3 * areaSum2);
            this.CG.y = this.CG.y / (3 * areaSum2);
        }
        /*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');
            }
        }