/// <summary> /// Adds a triangle to the advancing front to fill a hole. /// </summary> /// <param name="tcx"></param> /// <param name="node">middle node, that is the bottom of the hole</param> private static void Fill(DTSweepContext tcx, AdvancingFrontNode node) { DelaunayTriangle triangle = new DelaunayTriangle(node.Prev.Point, node.Point, node.Next.Point); // TODO: should copy the cEdge value from neighbor triangles // for now cEdge values are copied during the legalize triangle.MarkNeighbor(node.Prev.Triangle); triangle.MarkNeighbor(node.Triangle); tcx.Triangles.Add(triangle); // Update the advancing front node.Prev.Next = node.Next; node.Next.Prev = node.Prev; // tcx.RemoveNode (node); // If it was legalized the triangle has already been mapped if (!Legalize(tcx, triangle)) { tcx.MapTriangleToNodes(triangle); } }
/// <summary> /// Creates a new front triangle and legalize it /// </summary> private static AdvancingFrontNode NewFrontTriangle(DTSweepContext tcx, TriangulationPoint point, AdvancingFrontNode node) { AdvancingFrontNode newNode; DelaunayTriangle triangle; triangle = new DelaunayTriangle(point, node.Point, node.Next.Point); triangle.MarkNeighbor(node.Triangle); tcx.Triangles.Add(triangle); newNode = new AdvancingFrontNode(point); newNode.Next = node.Next; newNode.Prev = node; node.Next.Prev = newNode; node.Next = newNode; // tcx.AddNode (newNode); // XXX: BST if (!Legalize(tcx, triangle)) { tcx.MapTriangleToNodes(triangle); } return(newNode); }
/// <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, TriangulationPoint p, DelaunayTriangle ot, TriangulationPoint 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); }