diff --git a/Color.cpp b/Color.cpp index 40cba4a..5a20ed0 100644 --- a/Color.cpp +++ b/Color.cpp @@ -13,15 +13,16 @@ Color::Color(const RGB& rgb) : _rgb {rgb} {} Color::Color(const HSB& hsb) { - if (hsb.s == 0) { + if (hsb.s <= 0) { _rgb.r = _rgb.g = _rgb.b = hsb.b; } else { - int hi = static_cast(round(fabs(hsb.h / 60))); - double f = hsb.h / 60 - hi; - double p = hsb.b * (1 - hsb.s); - double q = hsb.b * (1 - f * hsb.s); - double t = hsb.b * (1- (1 - f) * hsb.s); - switch (hi) { + double hi = hsb.h / 60; + int i = static_cast(hi); + double f = hi - i; + double p = hsb.b * (1.0 - hsb.s); + double q = hsb.b * (1.0 - (hsb.s * f)); + double t = hsb.b * (1.0 - (hsb.s * (1.0 -f))); + switch (i) { case 0: _rgb.r = hsb.b; _rgb.g = t; @@ -48,12 +49,11 @@ Color::Color(const HSB& hsb) { _rgb.b = hsb.b; break; case 5: + default: _rgb.r = hsb.b; _rgb.g = p; _rgb.b = q; break; - default: - break; } } } @@ -63,14 +63,21 @@ Color::operator HSB() const { double rgb_max = std::max({_rgb.r, _rgb.g, _rgb.b}); double rgb_min = std::min({_rgb.r, _rgb.g, _rgb.b}); double delta = rgb_max - rgb_min; - if (_rgb.r > _rgb.g && _rgb.r > _rgb.b) { // red is max - hsb.h = ((_rgb.g - _rgb.b) / delta) * 60; - } else if (_rgb.g > _rgb.r && _rgb.g > _rgb.b) { // green is max - hsb.h = ((_rgb.b - _rgb.r) / delta) * 60; - } else { // blue is max - hsb.h = ((_rgb.r - _rgb.g) / delta) * 60; + if (delta < 0.00001) { + hsb.h = 0; + hsb.s = 0; + hsb.b = rgb_max; + return hsb; } - hsb.s = delta / rgb_max; + if (_rgb.r >= rgb_max) { // between yellow and magenta + hsb.h = (_rgb.g - _rgb.b) / delta; + } else if (_rgb.g >= rgb_max) { // between cyan and yellow + hsb.h = 2.0 + (_rgb.b - _rgb.r) / delta; + } else { // between magenta and cyan + hsb.h = 4.0 + (_rgb.r - _rgb.g) / delta; + } + hsb.h *= 60; + hsb.s = rgb_max > 0.0 ? delta / rgb_max : 0; hsb.b = rgb_max; return hsb; }