/// <summary>
/// Rotates a triangle pair one vertex CW
/// n2 n2
/// P +-----+ P +-----+
/// | t /| |\ t |
/// | / | | \ |
/// n1| / |n3 n1| \ |n3
/// | / | after CW | \ |
/// |/ oT | | oT \|
/// +-----+ oP +-----+
/// n4 n4
/// </summary>
private static void RotateTrianglePair(DelaunayTriangle t, PolygonPoint p, DelaunayTriangle ot,
PolygonPoint op)
{
DelaunayTriangle n1, n2, n3, n4;
n1 = t.NeighborCCWFrom(p);
n2 = t.NeighborCWFrom(p);
n3 = ot.NeighborCCWFrom(op);
n4 = ot.NeighborCWFrom(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 dEdge
ot.SetDelaunayEdgeCCW(p, de1);
t.SetDelaunayEdgeCW(p, de2);
t.SetDelaunayEdgeCCW(op, de3);
ot.SetDelaunayEdgeCW(op, de4);
// Remap cEdge
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.Neighbors.Clear();
ot.Neighbors.Clear();
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);
}