clayAnchorFor function

({int distance, int index, int? overlapLo, int? overlapSpan}) clayAnchorFor(
  1. List<Weighted<IntRange>> anchors,
  2. int lo,
  3. int span
)

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