示例#1
0
        static void ResetClearance(double2 o, double2 d, Edge *t, float2 perp)
        {
            var rhs = t->LPrev;
            var lhs = t->LNext->Sym;
            var a   = rhs->Dest->Point;
            var b   = rhs->Org->Point;
            var c   = lhs->Dest->Point;
            var f   = Math.ProjectSeg2(o, d, b, out var bi);

            if (f >= 0 && f <= 1 &&
                !lhs->Constrained && !rhs->Constrained &&
                math.lengthsq(bi - b) < math.min(math.lengthsq(a - b), math.lengthsq(c - b)))
            {
                lhs->ClearanceLeft  = -1;
                rhs->ClearanceRight = -1;
            }

            if (f >= 0 && !rhs->Constrained)
            {
                var r = Math.IntersectLineSegClamped(o, o + perp, b, (a + b) / 2);
                Math.ProjectSeg2(o, d, r, out var ri);
                if (math.lengthsq(ri - r) < math.min(math.lengthsq(b - r), math.lengthsq(a - r)))
                {
                    ResetClearance(o, d, rhs->Sym, perp);
                }
            }

            if (f <= 1 && !lhs->Constrained)
            {
                var l = Math.IntersectLineSegClamped(d, d + perp, b, (c + b) / 2);
                Math.ProjectSeg2(o, d, l, out var li);
                if (math.lengthsq(li - l) < math.min(math.lengthsq(b - l), math.lengthsq(c - l)))
                {
                    ResetClearance(o, d, lhs, perp);
                }
            }
        }
示例#2
0
文件: CDT.cs 项目: dotsnav/dotsnav
        Point GetNextPoint(Vertex *a, Vertex *b, float2 start, float2 end)
        {
            InfiniteLoopDetection.Reset();
            var e = GetLeftEdge(a, b->Point);

            while (e->Dest != b)
            {
                InfiniteLoopDetection.Register(1000, "GetNextPoint");

                var d = Math.TriArea(a->Point, b->Point, e->Dest->Point);

                if (d < 0 && e->Constrained)
                {
                    var p           = (float2)Math.IntersectLineSegClamped(start, end, e->Org->Point, e->Dest->Point);
                    var pointExists = TryGetPoint(p, e, out var v);

                    if (v != null)
                    {
                        if (_insertedPoints.Length > 1)
                        {
                            var prev = _insertedPoints[_insertedPoints.Length - 1].Vertex;
                            if (prev == v || e->Org == prev || e->Dest == prev)
                            {
                                continue;
                            }
                        }

                        if (_insertedPoints.Length > 2)
                        {
                            var prev = _insertedPoints[_insertedPoints.Length - 2].Vertex;
                            if (prev == v || e->Org == prev || e->Dest == prev)
                            {
                                continue;
                            }
                        }

                        return(new Point
                        {
                            Vertex = v,
                            FoundExisting = true,
                            P = p
                        });
                    }

                    if (pointExists || !SplitIsRobust(p, e))
                    {
                        var pRef = CreatePRef(p, e);

                        if (_insertedPoints.Length > 1 && _insertedPoints[_insertedPoints.Length - 1].Vertex == pRef)
                        {
                            continue;
                        }

                        var point = new Point
                        {
                            Vertex   = pRef,
                            Modified = true,
                            P        = p
                        };

                        var proj  = (float2)Math.ProjectLine(a->Point, b->Point, point.Vertex->Point);
                        var pproj = proj - p;

                        if (math.dot(b - a, pproj) < 0)
                        {
                            point.Before = proj;
                            point.After  = p;
                        }
                        else
                        {
                            point.Before = p;
                            point.After  = proj;
                        }

                        return(point);
                    }

                    var vert = InsertPointInEdge(p, e);
                    return(new Point
                    {
                        Vertex = vert,
                        P = p
                    });
                }

                e = d > 0 ? e->RPrev : e->ONext;
            }

            return(new Point
            {
                Vertex = b,
                P = b->Point
            });
        }