Beispiel #1
0
        private static bool Legalize(DTSweepContext tcx, DelaunayTriangle t)
        {
            for (int i = 0; i < 3; i++)
            {
                if (t.EdgeIsDelaunay[i])
                {
                    continue;
                }

                DelaunayTriangle ot = t.Neighbors[i];
                if (ot == null)
                {
                    continue;
                }

                TriangulationPoint p  = t.Points[i];
                TriangulationPoint op = ot.OppositePoint(t, p);
                int oi = ot.IndexOf(op);

                if (ot.EdgeIsConstrained[oi] || ot.EdgeIsDelaunay[oi])
                {
                    t.SetConstrainedEdgeAcross(p, ot.EdgeIsConstrained[oi]);
                    continue;
                }

                if (!TriangulationUtil.SmartIncircle(p, t.PointCCWFrom(p), t.PointCWFrom(p), op))
                {
                    continue;
                }


                t.EdgeIsDelaunay[i]   = true;
                ot.EdgeIsDelaunay[oi] = true;

                RotateTrianglePair(t, p, ot, op);

                if (!Legalize(tcx, t))
                {
                    tcx.MapTriangleToNodes(t);
                }
                if (!Legalize(tcx, ot))
                {
                    tcx.MapTriangleToNodes(ot);
                }

                t.EdgeIsDelaunay[i]   = false;
                ot.EdgeIsDelaunay[oi] = false;

                return(true);
            }
            return(false);
        }
Beispiel #2
0
        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);

            if (tcx.IsDebugEnabled)
            {
                tcx.DTDebugContext.ActiveNode = newNode;
            }

            if (!Legalize(tcx, triangle))
            {
                tcx.MapTriangleToNodes(triangle);
            }

            return(newNode);
        }
Beispiel #3
0
        private static void Fill(DTSweepContext tcx, AdvancingFrontNode node)
        {
            DelaunayTriangle triangle = new DelaunayTriangle(node.Prev.Point, node.Point, node.Next.Point);

            triangle.MarkNeighbor(node.Prev.Triangle);
            triangle.MarkNeighbor(node.Triangle);
            tcx.Triangles.Add(triangle);

            node.Prev.Next = node.Next;
            node.Next.Prev = node.Prev;
            tcx.RemoveNode(node);

            if (!Legalize(tcx, triangle))
            {
                tcx.MapTriangleToNodes(triangle);
            }
        }
Beispiel #4
0
        private static void FinalizationConvexHull(DTSweepContext tcx)
        {
            AdvancingFrontNode n1, n2;
            DelaunayTriangle   t1, t2;
            TriangulationPoint first, p1;

            n1    = tcx.Front.Head.Next;
            n2    = n1.Next;
            first = n1.Point;

            TurnAdvancingFrontConvex(tcx, n1, n2);

            n1 = tcx.Front.Tail.Prev;
            if (n1.Triangle.Contains(n1.Next.Point) && n1.Triangle.Contains(n1.Prev.Point))
            {
                t1 = n1.Triangle.NeighborAcrossFrom(n1.Point);
                RotateTrianglePair(n1.Triangle, n1.Point, t1, t1.OppositePoint(n1.Triangle, n1.Point));
                tcx.MapTriangleToNodes(n1.Triangle);
                tcx.MapTriangleToNodes(t1);
            }
            n1 = tcx.Front.Head.Next;
            if (n1.Triangle.Contains(n1.Prev.Point) && n1.Triangle.Contains(n1.Next.Point))
            {
                t1 = n1.Triangle.NeighborAcrossFrom(n1.Point);
                RotateTrianglePair(n1.Triangle, n1.Point, t1, t1.OppositePoint(n1.Triangle, n1.Point));
                tcx.MapTriangleToNodes(n1.Triangle);
                tcx.MapTriangleToNodes(t1);
            }

            first       = tcx.Front.Head.Point;
            n2          = tcx.Front.Tail.Prev;
            t1          = n2.Triangle;
            p1          = n2.Point;
            n2.Triangle = null;
            do
            {
                tcx.RemoveFromList(t1);
                p1 = t1.PointCCWFrom(p1);
                if (p1 == first)
                {
                    break;
                }
                t2 = t1.NeighborCCWFrom(p1);
                t1.Clear();
                t1 = t2;
            } while (true);

            first = tcx.Front.Head.Next.Point;
            p1    = t1.PointCWFrom(tcx.Front.Head.Point);
            t2    = t1.NeighborCWFrom(tcx.Front.Head.Point);
            t1.Clear();
            t1 = t2;
            while (p1 != first)
            {
                tcx.RemoveFromList(t1);
                p1 = t1.PointCCWFrom(p1);
                t2 = t1.NeighborCCWFrom(p1);
                t1.Clear();
                t1 = t2;
            }

            tcx.Front.Head      = tcx.Front.Head.Next;
            tcx.Front.Head.Prev = null;
            tcx.Front.Tail      = tcx.Front.Tail.Prev;
            tcx.Front.Tail.Next = null;
        }
Beispiel #5
0
        private static void FlipEdgeEvent(DTSweepContext tcx, TriangulationPoint ep, TriangulationPoint eq, DelaunayTriangle t, TriangulationPoint p)
        {
            DelaunayTriangle   ot = t.NeighborAcrossFrom(p);
            TriangulationPoint op = ot.OppositePoint(t, p);

            if (ot == null)
            {
                throw new InvalidOperationException("[BUG:FIXME] FLIP failed due to missing triangle");
            }

            if (tcx.IsDebugEnabled)
            {
                tcx.DTDebugContext.PrimaryTriangle   = t;
                tcx.DTDebugContext.SecondaryTriangle = ot;
            }

            bool inScanArea = TriangulationUtil.InScanArea(p, t.PointCCWFrom(p), t.PointCWFrom(p), op);

            if (inScanArea)
            {
                RotateTrianglePair(t, p, ot, op);
                tcx.MapTriangleToNodes(t);
                tcx.MapTriangleToNodes(ot);

                if (p == eq && op == ep)
                {
                    if (eq == tcx.EdgeEvent.ConstrainedEdge.Q && ep == tcx.EdgeEvent.ConstrainedEdge.P)
                    {
                        if (tcx.IsDebugEnabled)
                        {
                            Console.WriteLine("[FLIP] - constrained edge done");
                        }
                        t.MarkConstrainedEdge(ep, eq);
                        ot.MarkConstrainedEdge(ep, eq);
                        Legalize(tcx, t);
                        Legalize(tcx, ot);
                    }
                    else
                    {
                        if (tcx.IsDebugEnabled)
                        {
                            Console.WriteLine("[FLIP] - subedge done");
                        }
                    }
                }
                else
                {
                    Orientation o = TriangulationUtil.Orient2d(eq, op, ep);
                    t = NextFlipTriangle(tcx, o, t, ot, p, op);
                    FlipEdgeEvent(tcx, ep, eq, t, p);
                }
            }
            else
            {
                TriangulationPoint newP = null;
                if (NextFlipPoint(ep, eq, ot, op, out newP))
                {
                    FlipScanEdgeEvent(tcx, ep, eq, t, ot, newP);
                    EdgeEvent(tcx, ep, eq, t, p);
                }
            }
        }