edgeSnap function
Spec 08 D15's edge snap: the centre that puts one edge of an opening
centred at u, w wide, on a candidate, or null.
- The candidates are every stretch's ends (
stretches, as stretchesOf gives them: the straight span's ends and the obstacles' edges inside it) and every edge ofotherCuts(the host's other openings' drawn cuts, D8). - An edge
u − w/2oru + w/2withinapertureof a candidate (the distance at mostaperture) snaps: the centre becomes the one that puts that edge on it. - The nearest (edge, candidate) pair wins; ties go to the lower centre.
Everything is along the host's centreline, in its local units: the
caller gives aperture in them.
Implementation
double? edgeSnap(List<(double, double)> stretches,
List<(double, double)> otherCuts, double u, double w, double aperture) {
final lo = u - w / 2, hi = u + w / 2;
double? best;
var bestDistance = double.infinity;
void offer(double centre, double distance) {
if (distance > aperture) return;
if (distance < bestDistance ||
(distance == bestDistance && centre < best!)) {
best = centre;
bestDistance = distance;
}
}
void candidate(double q) {
offer(q + w / 2, (lo - q).abs());
offer(q - w / 2, (hi - q).abs());
}
for (final (a, b) in stretches) {
candidate(a);
candidate(b);
}
for (final (a, b) in otherCuts) {
candidate(a);
candidate(b);
}
return best;
}