clayAnchorFor function
The body anchor nearest the clockwise hue range (lo, span) in tenths: its index, the overlap with it (null when none) and the gap (0 when they overlap). Ties go to the lower index.
Implementation
({int index, int? overlapLo, int? overlapSpan, int distance}) clayAnchorFor(
List<Weighted<IntRange>> anchors,
int lo,
int span,
) {
int d(int x, int y) {
final v = (x - y).abs() % 3600;
return v > 1800 ? 3600 - v : v;
}
bool inside(int h, int from, int width) => (h - from) % 3600 <= width;
var best = 0;
var bestDistance = 1 << 30;
int? bestLo;
int? bestSpan;
for (var i = 0; i < anchors.length; i++) {
final a = anchors[i].value;
final aLo = a.lo % 3600;
final aSpan = a.hi - a.lo;
int? oLo;
if (inside(lo, aLo, aSpan)) {
oLo = lo;
} else if (inside(aLo, lo, span)) {
oLo = aLo;
}
final int distance;
int? oSpan;
if (oLo != null) {
final endA = (aLo + aSpan - oLo) % 3600;
final endB = (lo + span - oLo) % 3600;
oSpan = endA < endB ? endA : endB;
distance = 0;
} else {
final x = d((lo + span) % 3600, aLo);
final y = d((aLo + aSpan) % 3600, lo);
distance = x < y ? x : y;
}
if (distance < bestDistance) {
best = i;
bestDistance = distance;
bestLo = oLo;
bestSpan = oSpan;
}
}
return (
index: best,
overlapLo: bestLo,
overlapSpan: bestSpan,
distance: bestDistance,
);
}