fixed conversion calculations

This commit is contained in:
Bob Polis 2020-10-28 15:46:17 +01:00
parent 516b62e266
commit d0d8e28dd8

View File

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