complement property

Hct get complement

A color that complements the input color aesthetically.

In art, this is usually described as being across the color wheel. History of this shows intent as a color that is just as cool-warm as the input color is warm-cool.

Implementation

Hct get complement {
  if (_precomputedComplement case final precomputedComplement?) {
    return precomputedComplement;
  }
  final coldestHue = _coldest.hue;
  final coldestTemp = _tempsByHct[_coldest]!;
  final warmestHue = _warmest.hue;
  final warmestTemp = _tempsByHct[_warmest]!;
  final range = warmestTemp - coldestTemp;
  final startHueIsColdestToWarmest = _isBetween(
    input.hue,
    coldestHue,
    warmestHue,
  );
  final startHue = startHueIsColdestToWarmest ? warmestHue : coldestHue;
  final endHue = startHueIsColdestToWarmest ? coldestHue : warmestHue;
  const directionOfRotation = 1.0;

  var smallestError = 1000.0;
  var answer = _hctsByHue[input.hue.round()];

  final complementRelativeTemp = 1.0 - getRelativeTemperature(input);

  // Find the color in the other section, closest to the inverse percentile
  // of the input color. This is the complement.
  for (var hueAddend = 0.0; hueAddend <= 360.0; hueAddend += 1.0) {
    final hue = MathUtils.sanitizeDegreesDouble(
      startHue + directionOfRotation * hueAddend,
    );
    if (!_isBetween(hue, startHue, endHue)) {
      continue;
    }
    final possibleAnswer = _hctsByHue[hue.round()];
    final relativeTemp = (_tempsByHct[possibleAnswer]! - coldestTemp) / range;
    final error = (complementRelativeTemp - relativeTemp).abs();
    if (error < smallestError) {
      smallestError = error;
      answer = possibleAnswer;
    }
  }
  return _precomputedComplement = answer;
}