Пример #1
0
    void IsCdt(Navmesh *lct, int constraint = -1, int vertex = -1)
    {
        var e = lct->GetEdgeEnumerator(true);

        while (e.MoveNext())
        {
            if (e.Current->Constrained)
            {
                continue;
            }

            var o = e.Current->Org->Point;
            var d = e.Current->Dest->Point;
            if (Math.Contains(o, -lct->Extent, lct->Extent) && Math.Contains(d, -lct->Extent, lct->Extent))
            {
                var on = e.Current->ONext->Dest->Point;
                var dn = e.Current->DNext->Org->Point;
                if (Math.CircumcircleContains(o, d, on, dn) && Math.Ccw(dn, d, on) && Math.Ccw(on, o, dn))
                {
                    Debug.Log($"delaunay fail, constraint: {constraint}, vertex:{vertex}, from: {o}, to: {d}");
                    throw new Exception();
                }
            }
        }
    }
Пример #2
0
 // https://www.researchgate.net/publication/2478154_Fully_Dynamic_Constrained_Delaunay_Triangulations
 void FlipEdges(float2 p)
 {
     while (_flipStack.Count > 0)
     {
         var e = _flipStack.Pop();
         Assert.IsTrue(Math.Ccw(e->Org->Point, e->Dest->Point, p));
         if (!e->Constrained && Math.CircumcircleContains(e->Org->Point, e->Dest->Point, p, e->DNext->Org->Point))
         {
             _flipStack.Push(e->OPrev);
             _flipStack.Push(e->DNext);
             Assert.IsTrue(Math.Ccw(e->OPrev->Org->Point, e->OPrev->Dest->Point, p));
             Assert.IsTrue(Math.Ccw(e->DNext->Org->Point, e->DNext->Dest->Point, p));
             Swap(e);
         }
     }
 }
Пример #3
0
        void FlipQuad()
        {
            while (_flipStack.Count > 0)
            {
                var edge = _flipStack.Pop();

                if (!edge->Constrained && Math.CircumcircleContains(edge->Org->Point, edge->Dest->Point, edge->ONext->Dest->Point, edge->DNext->Org->Point))
                {
                    _flipStack.Push(edge->OPrev);
                    _flipStack.Push(edge->DNext);
                    _flipStack.Push(edge->Sym->OPrev);
                    _flipStack.Push(edge->Sym->DNext);
                    Swap(edge);
                }
            }
        }
Пример #4
0
        // http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.61.3862&rep=rep1&type=pdf
        // TriangulatePseudopolygonDelaunay()
        void RetriangulateFace(Edge *edge)
        {
            Assert.IsTrue(edge != null);
            Assert.IsTrue(edge != edge->LNext->LNext);
            if (edge->LNext->LNext->LNext == edge)
            {
                NewTriangle(edge);
                return;
            }

            InfiniteLoopDetection.Reset();
            while (!Math.Ccw(edge->Org->Point, edge->Dest->Point, edge->LNext->Dest->Point))
            {
                InfiniteLoopDetection.Register(1000, "RetriangulateFace 0");
                edge = edge->LNext;
            }

            var c = edge->LNext;
            var e = c;

            InfiniteLoopDetection.Reset();
            while (true)
            {
                InfiniteLoopDetection.Register(1000, "RetriangulateFace 1");
                e = e->LNext;
                if (e->LNext == edge)
                {
                    break;
                }
                if (Math.CircumcircleContains(edge->Org->Point, edge->Dest->Point, c->Dest->Point, e->Dest->Point))
                {
                    c = e;
                }
            }

            Assert.IsTrue(c != edge);
            var connected = false;

            if (c->LNext->LNext != edge)
            {
                V.TryAdd((IntPtr)edge->LPrev->Dest);
                V.TryAdd((IntPtr)c->LNext->Org);

                var b = Connect(edge->LPrev, c->LNext);
                RetriangulateFace(b);
                connected = true;
            }

            if (c != edge->LNext)
            {
                V.TryAdd((IntPtr)c->Dest);
                V.TryAdd((IntPtr)edge->LNext->Org);

                var a = Connect(c, edge->LNext);
                RetriangulateFace(a);
                connected = true;
            }

            if (connected)
            {
                NewTriangle(edge);
            }
        }