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); } } }
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 }); }