/*--------------------------------------------------------------------- * Prints out the float point of intersection, and toggles in/out flag. * ---------------------------------------------------------------------*/ public cInFlag InOut(cPointd p, cInFlag inflag, int aHB, int bHA) { InsertInters(p.x, p.y); /* Update inflag. */ if (aHB > 0) { inflag.f = cInFlag.Pin; return(inflag); } else if (bHA > 0) { inflag.f = cInFlag.Qin; return(inflag); } else /* Keep status quo. */ { return(inflag); } }
/*--------------------------------------------------------------------- * 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; } }