hsl_colour hsl_colour::from_rgb(const colour& aColour) { double hue, saturation, lightness; double r = aColour.red() / 255.0, g = aColour.green() / 255.0, b = aColour.blue() / 255.0; double M = std::max(std::max(r, g), b); double m = std::min(std::min(r, g), b); double c = M - m; double h2; if (c == 0.0) h2 = undefined_hue(); else if (M == r) h2 = std::fmod((g - b) / c, 6.0); else if (M == g) h2 = (b - r) / c + 2.0; else if (M == b) h2 = (r - g) / c + 4.0; else h2 = undefined_hue(); if (h2 != undefined_hue()) { hue = 60.0 * h2; if (hue < 0.0) hue += 360.0; } else hue = undefined_hue(); lightness = 0.5f * (M + m); lightness = std::max(std::min(lightness, 1.0), 0.0); if (c == 0.0) saturation = 0.0; else saturation = c / (1.0 - std::abs(2.0 * lightness - 1.0)); saturation = std::max(std::min(saturation, 1.0), 0.0); return hsl_colour(hue, saturation, lightness); }
hsv_colour hsv_colour::from_rgb(const colour& aColour) { double hue, saturation, value; double r = aColour.red() / 255.0, g = aColour.green() / 255.0, b = aColour.blue() / 255.0; double M = std::max(std::max(r, g), b); double m = std::min(std::min(r, g), b); double c = M - m; double h2; if (c == 0.0) h2 = undefined_hue(); else if (M == r) h2 = std::fmod((g - b) / c, 6.0); else if (M == g) h2 = (b - r) / c + 2.0; else if (M == b) h2 = (r - g) / c + 4.0; else h2 = undefined_hue(); if (h2 != undefined_hue()) { hue = 60.0 * h2; if (hue < 0.0) hue += 360.0; } else hue = undefined_hue(); value = M; value = std::max(std::min(value, 1.0), 0.0); if (c == 0.0) saturation = 0.0; else saturation = c / value; saturation = std::max(std::min(saturation, 1.0), 0.0); return hsv_colour(hue, saturation, value, aColour.alpha() / 255.0); }
colour hsl_colour::to_rgb(double aAlpha) const { double c = (1.0 - std::abs(2.0 * lightness() - 1.0)) * saturation(); double h2 = hue() / 60.0; double x = c * (1.0 - std::abs(std::fmod(h2, 2.0) - 1.0)); double r, g, b; if (hue() == undefined_hue()) r = g = b = 0.0; else if (h2 >= 0.0 && h2 < 1.0) r = c, g = x, b = 0.0; else if (h2 >= 1.0 && h2 < 2.0) r = x, g = c, b = 0.0; else if (h2 >= 2.0 && h2 < 3.0) r = 0.0, g = c, b = x; else if (h2 >= 3.0 && h2 < 4.0) r = 0.0, g = x, b = c; else if (h2 >= 4.0 && h2 < 5.0) r = x, g = 0.0, b = c; else if (h2 >= 5.0 && h2 < 6.0) r = c, g = 0.0, b = x; else r = g = b = 0.0; double m = lightness() - 0.5f * c; colour result( static_cast<colour::component>(std::floor((r + m) * 255.0)), static_cast<colour::component>(std::floor((g + m) * 255.0)), static_cast<colour::component>(std::floor((b + m) * 255.0)), static_cast<colour::component>(std::floor(aAlpha * 255.0))); return result; }
bool hsv_colour::hue_undefined() const { return iHue == undefined_hue(); }
double hsv_colour::hue() const { if (iHue != undefined_hue()) return iHue; return 0.0; }
hsv_colour::hsv_colour(double aHue, double aSaturation, double aValue, double aAlpha) : iHue{aHue}, iSaturation{ aSaturation }, iValue{ aValue }, iAlpha{ aAlpha } { if (iHue != undefined_hue()) iHue = std::fmod(iHue, 360.0); }