private void FinalizationPolygon(SweepContext tcx) { // Get an Internal triangle to start with Triangle t = tcx.Front._head.Next.Triangle; TriPoint p = tcx.Front._head.Next.Point; while (!t.GetConstrainedEdgeCW(p)) { t = t.NeighborCCW(p); } tcx.MeshClean(t); }
private void EdgeEvent(SweepContext tcx, TriPoint ep, TriPoint eq, Triangle triangle, TriPoint point) { if (IsEdgeSideOfTriangle(triangle, ep, eq)) { return; } TriPoint p1 = triangle.PointCCW(point); Winding o1 = TriUtil.Orient2d(eq, p1, ep); if (o1 == Winding.Collinear) { if (triangle.Contains(eq, p1)) { triangle.MarkConstrainedEdge(eq, p1); // We are modifying the constraint maybe it would be better to // not change the given constraint and just keep a variable for the new constraint tcx.EdgeEvent.ConstrainedEdge.Q = p1; triangle = triangle.NeighborAcross(point); EdgeEvent(tcx, ep, p1, triangle, p1); } else { throw new NotSupportedException("EdgeEvent - collinear points not supported"); } return; } TriPoint p2 = triangle.PointCW(point); Winding o2 = TriUtil.Orient2d(eq, p2, ep); if (o2 == Winding.Collinear) { if (triangle.Contains(eq, p2)) { triangle.MarkConstrainedEdge(eq, p2); // We are modifying the constraint maybe it would be better to // not change the given constraint and just keep a variable for the new constraint tcx.EdgeEvent.ConstrainedEdge.Q = p2; triangle = triangle.NeighborAcross(point); EdgeEvent(tcx, ep, p2, triangle, p2); } else { throw new NotSupportedException("EdgeEvent - collinear points not supported"); } return; } if (o1 == o2) { // Need to decide if we are rotating CW or CCW to get to a triangle // that will cross edge if (o1 == Winding.CW) { triangle = triangle.NeighborCCW(point); } else { triangle = triangle.NeighborCW(point); } EdgeEvent(tcx, ep, eq, triangle, point); } else { // This triangle crosses constraint so lets flippin start! FlipEdgeEvent(tcx, ep, eq, triangle, point); } }
/** * Rotates a triangle pair one vertex CW *<pre> * n2 n2 * P +-----+ P +-----+ * | t /| |\ t | * | / | | \ | * n1| / |n3 n1| \ |n3 * | / | after CW | \ | * |/ oT | | oT \| * +-----+ oP +-----+ * n4 n4 * </pre> */ private void RotateTrianglePair(Triangle t, TriPoint p, Triangle ot, TriPoint op) { Triangle n1, n2, n3, n4; n1 = t.NeighborCCW(p); n2 = t.NeighborCW(p); n3 = ot.NeighborCCW(op); n4 = ot.NeighborCW(op); bool ce1, ce2, ce3, ce4; ce1 = t.GetConstrainedEdgeCCW(p); ce2 = t.GetConstrainedEdgeCW(p); ce3 = ot.GetConstrainedEdgeCCW(op); ce4 = ot.GetConstrainedEdgeCW(op); bool de1, de2, de3, de4; de1 = t.GetDelaunayEdgeCCW(p); de2 = t.GetDelaunayEdgeCW(p); de3 = ot.GetDelaunayEdgeCCW(op); de4 = ot.GetDelaunayEdgeCW(op); t.Legalize(p, op); ot.Legalize(op, p); // Remap delaunay_edge ot.SetDelunayEdgeCCW(p, de1); t.SetDelunayEdgeCW(p, de2); t.SetDelunayEdgeCCW(op, de3); ot.SetDelunayEdgeCW(op, de4); // Remap constrained_edge ot.SetConstrainedEdgeCCW(p, ce1); t.SetConstrainedEdgeCW(p, ce2); t.SetConstrainedEdgeCCW(op, ce3); ot.SetConstrainedEdgeCW(op, ce4); // Remap neighbors // XXX: might optimize the markNeighbor by keeping track of // what side should be assigned to what neighbor after the // rotation. Now mark neighbor does lots of testing to find // the right side. t.ClearNeighbors(); ot.ClearNeighbors(); if (n1 != null) { ot.MarkNeighbor(n1); } if (n2 != null) { t.MarkNeighbor(n2); } if (n3 != null) { t.MarkNeighbor(n3); } if (n4 != null) { ot.MarkNeighbor(n4); } t.MarkNeighbor(ot); }