void CheckTraversal(float2 a, Edge *exit, bool lhs, Edge *s) { var b = exit->Org->Point; var c = exit->Dest->Point; if (!Math.ProjectSeg(a, c, b, out var bac)) { return; } var mirror = b + (c - 2 * bac + a); var lba = math.lengthsq(a - b); var lbc = math.lengthsq(c - b); var clearance = math.sqrt(math.min(lba, lbc)); var s1 = s->Org->Point; var s2 = s->Dest->Point; if (Math.IntersectSegCircle(s1, s2, b, clearance) < 2 && Math.IntersectSegCircle(s1, s2, mirror, clearance) < 2) { return; } if (Math.ProjectSeg(s1, s2, b, out var bi)) { var bib = b - bi; var lbib = math.length(bib); clearance = math.min(clearance, lbib); var r1 = bi + bib / lbib * clearance; var acp = Math.PerpCw(c - a); var s12 = s2 - s1; var s12p = Math.PerpCw(s12); var r2 = Math.Angle(acp, s12p) < 0 ? Math.IntersectLineLine(r1, r1 + s12, c, c + acp) : Math.IntersectLineLine(r1, r1 + s12, c, c + s12p); if (TryGetDisturbance(lhs ? exit->Sym : exit, r1, r2, c, out var e, out _, out var vert, lhs)) { var v = vert->Point; var vi = Math.ProjectLine(s1, s2, v); var lvs = math.length(vi - v); var lve = math.length(e - v); if (lvs < lve && lvs < clearance) { V.TryAdd((IntPtr)vert); return; } } } Propagate(s, lhs ? exit : exit->Sym); }
bool CheckTraversal(float2 a, float2 b, float2 c, Edge *exit, bool lhs, out Disturbance disturbance) { if (!Math.ProjectSeg(a, c, b, out var bac)) { disturbance = default; return(false); } var mirror = b + (c - 2 * bac + a); var lba = math.lengthsq(a - b); var lbc = math.lengthsq(c - b); var clearance = math.sqrt(math.min(lba, lbc)); var constraint = TryGetConstraint(exit, clearance, b, mirror, lhs); if (constraint == null || constraint->RefineFailed) { disturbance = default; return(false); } var s1 = constraint->Org->Point; var s2 = constraint->Dest->Point; if (!Math.ProjectSeg(s1, s2, b, out var bi)) { disturbance = default; return(false); } // The paper says R is delimited by a line parallel to s passing by b. // When cl(a, b, c) == dist(b, a) and dist(b, a) < dist(b, s) this allows // for vertices in R violating definition 3.4: dist(v, s) < cl(a, b, c). // R will be delimited by a line parallel to s at a distance of cl(a, b, c) // Technially r1 should be at the intersection point with bc, but as bc // is enclosed by the Delaunay circle of triangle abc this is irrelevant. // R is triangle r1, r2, c var bib = b - bi; var lbib = math.length(bib); clearance = math.min(clearance, lbib); var r1 = bi + bib / lbib * clearance; var acp = Math.PerpCw(c - a); var s12 = s2 - s1; var s12p = Math.PerpCw(s12); var r2 = Math.Angle(acp, s12p) < 0 ? Math.IntersectLineLine(r1, r1 + s12, c, c + acp) : Math.IntersectLineLine(r1, r1 + s12, c, c + s12p); if (TryGetDisturbance(lhs ? exit->Sym : exit, r1, r2, c, out var e, out var u, out var vert, lhs)) { var v = vert->Point; var vi = Math.ProjectLine(s1, s2, v); var lvs = math.length(vi - v); var lve = math.length(e - v); if (lvs < lve && lvs < clearance) { Math.CircleFromPoints(u, v, e, out var centre, out var radius); var t = Math.IntersectLineCircle(s1, s2, centre, radius, out var x1, out var x2); Assert.IsTrue(t == 2); var pRef = (x1 + x2) / 2; if (ValidateRefinement(ref pRef, constraint)) { disturbance = new Disturbance(vert, pRef, constraint); return(true); } constraint->RefineFailed = true; } } disturbance = default; return(false); }
bool TravsDisturbed(Edge *edge, out Vertex *vRef) { var v = edge->Org->Point; var check = edge->LNext->Sym; InfiniteLoopDetection.Reset(); while (true) { InfiniteLoopDetection.Register(1000, "TravsDisturbed 0"); if (check->Constrained) { break; } if (!Math.ProjectSeg(check->Org->Point, check->Dest->Point, v, out _)) { check = check->OPrev->Sym; if (check->Constrained || !Math.ProjectSeg(check->Org->Point, check->Dest->Point, v, out _)) { break; } } if (RhsDisturbed(check, out vRef)) { return(true); } check = check->DPrev; } check = edge->LNext; InfiniteLoopDetection.Reset(); while (true) { InfiniteLoopDetection.Register(1000, "TravsDisturbed 1"); if (check->Constrained) { break; } if (!Math.ProjectSeg(check->Org->Point, check->Dest->Point, v, out _)) { check = check->ONext->Sym; if (check->Constrained || !Math.ProjectSeg(check->Org->Point, check->Dest->Point, v, out _)) { break; } } if (LhsDisturbed(check, out vRef)) { return(true); } check = check->DNext; } vRef = default; return(false); }