analogous function

List<Hct> analogous(
  1. Hct x, {
  2. int count = 5,
  3. double step = 30.0,
  4. HarmonyTonePolicy tonePolicy = HarmonyTonePolicy.preserveTone,
})

count colors: x flanked by neighbors step degrees apart in chromatic direction (u'v' angle around the white point). For odd count, x is the middle element.

Unlike harmony sets, analogous colors all lean the same way from gray and cannot mix to neutral; this is a nearness operation, not a balance operation. step is a design knob, not physics: 30 degrees of u'v' direction per step is the default.

Implementation

List<Hct> analogous(
  Hct x, {
  int count = 5,
  double step = 30.0,
  HarmonyTonePolicy tonePolicy = HarmonyTonePolicy.preserveTone,
}) {
  assert(count >= 1, 'analogous needs at least 1 color');
  final p = uvOfArgb(x.toInt());
  if (p == null || x.chroma < 1e-4) return List.filled(count, x);
  final (wu, wv) = whiteUvPoint;
  final offset = (p.$1 - wu, p.$2 - wv);
  return [
    for (var i = 0; i < count; i++)
      if (i * 2 == count - 1)
        x // the seed itself, untouched
      else
        _rotated(x, offset, (i - (count - 1) / 2.0) * step, 1.0, tonePolicy),
  ];
}