// // Color.cpp // screensaver // // Created by Bob Polis at 2020-10-27 // Copyright (c) 2020 SwiftCoder. All rights reserved. // #include "Color.hpp" #include #include Color::Color(const RGB& rgb) : _rgb {rgb} {} Color::Color(const HSB& hsb) { if (hsb.s <= 0) { _rgb.r = _rgb.g = _rgb.b = hsb.b; } else { 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; _rgb.b = p; break; case 1: _rgb.r = q; _rgb.g = hsb.b; _rgb.b = p; break; case 2: _rgb.r = p; _rgb.g = hsb.b; _rgb.b = t; break; case 3: _rgb.r = p; _rgb.g = q; _rgb.b = hsb.b; break; case 4: _rgb.r = t; _rgb.g = p; _rgb.b = hsb.b; break; case 5: default: _rgb.r = hsb.b; _rgb.g = p; _rgb.b = q; break; } } } Color::operator HSB() const { HSB hsb; 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 (delta < 0.00001) { hsb.h = 0; hsb.s = 0; hsb.b = rgb_max; return hsb; } 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; }