Пример #1
0
        Vertex *InsertPointInEdge(float2 point, Edge *edge)
        {
            _flipStack.Push(edge->ONext->Sym);
            _flipStack.Push(edge->DPrev->Sym);
            _flipStack.Push(edge->OPrev);
            _flipStack.Push(edge->DNext);

            for (var i = 0; i < _flipStack.Count; i++)
            {
                Assert.IsTrue(Math.Ccw(_flipStack[i]->Org->Point, _flipStack[i]->Dest->Point, point));
            }

            DestroyedTriangle(edge->TriangleId);
            DestroyedTriangle(edge->Sym->TriangleId);

            var crep = edge->QuadEdge->Crep;
            var e    = edge->OPrev;

            C.Remove((IntPtr)edge);
            RemoveEdge(edge, false);
            var result = CreateVertex(point);

            V.TryAdd((IntPtr)result);
            V.TryAdd((IntPtr)e->Org);
            var newEdge = CreateEdge(e->Org, result);

            newEdge->QuadEdge->Crep = GetCrep(crep);
            Splice(newEdge, e);

            V.TryAdd((IntPtr)e->Dest);
            V.TryAdd((IntPtr)newEdge->Sym->Org);

            newEdge = Connect(e, newEdge->Sym);
            e       = newEdge->OPrev;

            V.TryAdd((IntPtr)e->Dest);
            V.TryAdd((IntPtr)newEdge->Sym->Org);

            newEdge = Connect(e, newEdge->Sym);
            newEdge->QuadEdge->Crep = crep;
            e = newEdge->OPrev;

            V.TryAdd((IntPtr)e->Dest);
            V.TryAdd((IntPtr)newEdge->Sym->Org);

            Connect(e, newEdge->Sym);

            var te = result->Edge;

            NewTriangle(te);
            te = te->ONext;
            NewTriangle(te);
            te = te->ONext;
            NewTriangle(te);
            te = te->ONext;
            NewTriangle(te);

            FlipEdges(point);
            return(result);
        }
Пример #2
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();
                }
            }
        }
    }
Пример #3
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);
         }
     }
 }
Пример #4
0
        static Edge *GetLeftEdge(Vertex *a, float2 p)
        {
            var result = a->Edge;
            var o      = result->Org->Point;

            InfiniteLoopDetection.Reset();
            while (!Math.Ccw(o, p, result->Dest->Point))
            {
                InfiniteLoopDetection.Register(1000, "GetLeftEdge 0");
                result = result->ONext;
            }

            InfiniteLoopDetection.Reset();
            while (Math.Ccw(o, p, result->OPrev->Dest->Point))
            {
                InfiniteLoopDetection.Register(1000, "GetLeftEdge 1");
                result = result->OPrev;
            }

            return(result);
        }
Пример #5
0
        Vertex *InsertPointInFace(float2 p, Edge *edge)
        {
            _flipStack.Push(edge->ONext->Sym);
            _flipStack.Push(edge);
            _flipStack.Push(edge->DPrev->Sym);

            for (var i = 0; i < _flipStack.Count; i++)
            {
                Assert.IsTrue(Math.Ccw(_flipStack[i]->Org->Point, _flipStack[i]->Dest->Point, p));
            }

            DestroyedTriangle(edge->TriangleId);

            var result = CreateVertex(p);

            V.TryAdd((IntPtr)result);
            V.TryAdd((IntPtr)edge->Org);
            V.TryAdd((IntPtr)edge->Dest);
            V.TryAdd((IntPtr)edge->LNext->Dest);

            var newEdge = CreateEdge(edge->Org, result);

            Splice(newEdge, edge);
            newEdge = Connect(edge, newEdge->Sym);
            Connect(newEdge->OPrev, newEdge->Sym);

            var te = result->Edge;

            NewTriangle(te);
            te = te->ONext;
            NewTriangle(te);
            te = te->ONext;
            NewTriangle(te);

            FlipEdges(p);
            return(result);
        }
Пример #6
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);
            }
        }