/* 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 */ } }
//************************************** public bool Solven(float x, float y) /*Is called when the user drags the last point of the link or releases it. * Corresponds to the Solven method in C*/ { float halfLength; //floor of half os total cPointi target; //point for storing the target cPointd Jk; // coords of kinked joint returned by Solve2 // cPointi J1; // Joint1 on x-axis //create target target = new cPointi(x, y); //Compute Length array and # of links //cVertex v0; v1 = list.head; for (i = 0; i < list.n - 1; i++) { linklen[i] = (Length(v1.Point, v1.NextVertex.Point) + .5f); 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
public void ResetVertex(cVertex resV, float x, float y) { resV.Point.X = x; resV.Point.Y = y; }
public cVertexList() { head = null; n = 0; }
public void SetVertex(float x, float y) { cVertex v = new cVertex(x, y); InsertBeforeHead(v); }
public void SetVertex3D(float x, float y, float z) { cVertex v = new cVertex(x, y, z); InsertBeforeHead(v); }
public cDiagonal() { next = prev = null; v1 = v2 = new cVertex(); }
public cDiagonal(cVertex v1, cVertex v2) { this.v1 = v1; this.v2 = v2; }
/*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; float 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)) / (float)((vtemp1.Point.Y - q.Y) - (vtemp.Point.Y - q.Y)); /* saving the x-coordinates for the intersections;*/ inters[intCount] = (float)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'); } }
/*--------------------------------------------------------------------- * 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)); }
private int ReadVertices() { cVertex v = P.head; int i = 0; do { v.IndexInPointCloud = 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.IndexInPointCloud = i++; v.IsProcessed = false; v = v.NextVertex; } while (v != P.head); float xmin, ymin, xmax, ymax; /* Primary min & max */ float 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); }
private void PutInOutput(float x, float y) { cVertex v = new cVertex(x, y); output.InsertBeforeHead(v); }
private void Push(cVertex p, cVertexList top) { //simulating a stack behavior for cVertexList list //Push procedure top.InsertBeforeHead(p); }
/*--------------------------------------------------------------------- * 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; } }
private void InsertInters(float x, float y) { cVertex v = new cVertex((int)x, (int)y); inters.InsertBeforeHead(v); }