hspToRgb static method

RgbColor hspToRgb(
  1. HspColor hspColor
)

Converts a HSP color to a RGB color.

Implementation

static RgbColor hspToRgb(HspColor hspColor) {
  final hsp = hspColor.toFactoredList();

  var hue = hsp[0];
  final saturation = hsp[1];
  final perceivedBrightness = hsp[2];

  final hueIndex = (hue * 6).floor() % 6;
  final hueSegment = (hueIndex.isEven) ? hueIndex : hueIndex + 1;
  final hueSegmentSign = (hueIndex.isEven) ? 1 : -1;
  hue =
      6 * ((hueSegmentSign * hue) + (-1 * hueSegmentSign * (hueSegment / 6)));

  late double red, green, blue;

  if (saturation < 1) {
    final invertSaturation = 1 - saturation;
    final part = 1 + (hue * ((1 / invertSaturation) - 1));

    double calculateFirstValue(double a, double b, double c) =>
        perceivedBrightness /
        math.sqrt((a / invertSaturation / invertSaturation) +
            (b * part * part) +
            c);
    double calculateSecondValue(double firstValue) =>
        firstValue / invertSaturation;
    double calculateThirdValue(double firstValue, double secondValue) =>
        firstValue + (hue * (secondValue - firstValue));

    switch (hueIndex) {
      case 0:
        blue = calculateFirstValue(_pr, _pg, _pb).clamp(0.0, 1.0);
        red = calculateSecondValue(blue).clamp(0.0, 1.0);
        green = calculateThirdValue(blue, red).clamp(0.0, 1.0);
        break;
      case 1:
        blue = calculateFirstValue(_pg, _pr, _pb).clamp(0.0, 1.0);
        green = calculateSecondValue(blue).clamp(0.0, 1.0);
        red = calculateThirdValue(blue, green).clamp(0.0, 1.0);
        break;
      case 2:
        red = calculateFirstValue(_pg, _pb, _pr).clamp(0.0, 1.0);
        green = calculateSecondValue(red).clamp(0.0, 1.0);
        blue = calculateThirdValue(red, green).clamp(0.0, 1.0);
        break;
      case 3:
        red = calculateFirstValue(_pb, _pg, _pr).clamp(0.0, 1.0);
        blue = calculateSecondValue(red).clamp(0.0, 1.0);
        green = calculateThirdValue(red, blue).clamp(0.0, 1.0);
        break;
      case 4:
        green = calculateFirstValue(_pb, _pr, _pg).clamp(0.0, 1.0);
        blue = calculateSecondValue(green).clamp(0.0, 1.0);
        red = calculateThirdValue(green, blue).clamp(0.0, 1.0);
        break;
      case 5:
        green = calculateFirstValue(_pr, _pb, _pg).clamp(0.0, 1.0);
        red = calculateSecondValue(green).clamp(0.0, 1.0);
        blue = calculateThirdValue(green, red).clamp(0.0, 1.0);
        break;
    }
  } else {
    double calculateFirstValue(double a, double b) => math.sqrt(
        (perceivedBrightness * perceivedBrightness) / (a + (b * hue * hue)));
    double calculateSecondValue(double firstValue) => firstValue * hue;

    switch (hueIndex) {
      case 0:
        red = calculateFirstValue(_pr, _pg).clamp(0.0, 1.0);
        green = calculateSecondValue(red).clamp(0.0, 1.0);
        blue = 0;
        break;
      case 1:
        green = calculateFirstValue(_pg, _pr).clamp(0.0, 1.0);
        red = calculateSecondValue(green).clamp(0.0, 1.0);
        blue = 0;
        break;
      case 2:
        green = calculateFirstValue(_pg, _pb).clamp(0.0, 1.0);
        blue = calculateSecondValue(green).clamp(0.0, 1.0);
        red = 0;
        break;
      case 3:
        blue = calculateFirstValue(_pb, _pg).clamp(0.0, 1.0);
        green = calculateSecondValue(blue).clamp(0.0, 1.0);
        red = 0;
        break;
      case 4:
        blue = calculateFirstValue(_pb, _pr).clamp(0.0, 1.0);
        red = calculateSecondValue(blue).clamp(0.0, 1.0);
        green = 0;
        break;
      case 5:
        red = calculateFirstValue(_pr, _pb).clamp(0.0, 1.0);
        blue = calculateSecondValue(red).clamp(0.0, 1.0);
        green = 0;
        break;
    }
  }

  final alpha = hspColor.alpha / 255;

  return RgbColor.extrapolate(<double>[red, green, blue, alpha]);
}