create method

Hct create()

Creates a key color from a hue and a requestedChroma. The key color is the first tone, starting from T50, matching the given hue and chroma.

@return Key color Hct

Implementation

Hct create() {
  // Pivot around T50 because T50 has the most chroma available, on
  // average. Thus it is most likely to have a direct answer.
  const pivotTone = 50;
  const toneStepSize = 1;
  // Epsilon to accept values slightly higher than the requested chroma.
  const epsilon = 0.01;

  // Binary search to find the tone that can provide a chroma that is closest
  // to the requested chroma.
  var lowerTone = 0;
  var upperTone = 100;
  while (lowerTone < upperTone) {
    final midTone = (lowerTone + upperTone) ~/ 2;
    final isAscending =
        _maxChroma(midTone) < _maxChroma(midTone + toneStepSize);
    final sufficientChroma = _maxChroma(midTone) >= requestedChroma - epsilon;

    if (sufficientChroma) {
      // Either range [lowerTone, midTone] or [midTone, upperTone] has
      // the answer, so search in the range that is closer the pivot tone.
      if ((lowerTone - pivotTone).abs() < (upperTone - pivotTone).abs()) {
        upperTone = midTone;
      } else {
        if (lowerTone == midTone) {
          return Hct.from(hue, requestedChroma, lowerTone.toDouble());
        }
        lowerTone = midTone;
      }
    } else {
      // As there is no sufficient chroma in the midTone, follow the direction
      // to the chroma peak.
      if (isAscending) {
        lowerTone = midTone + toneStepSize;
      } else {
        // Keep midTone for potential chroma peak.
        upperTone = midTone;
      }
    }
  }

  return Hct.from(hue, requestedChroma, lowerTone.toDouble());
}