diff --git a/Color.cpp b/Color.cpp new file mode 100644 index 0000000..40cba4a --- /dev/null +++ b/Color.cpp @@ -0,0 +1,76 @@ +// +// 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 { + 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) { + 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: + _rgb.r = hsb.b; + _rgb.g = p; + _rgb.b = q; + break; + default: + 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 (_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; + } + hsb.s = delta / rgb_max; + hsb.b = rgb_max; + return hsb; +} diff --git a/Color.hpp b/Color.hpp new file mode 100644 index 0000000..fd6d5e4 --- /dev/null +++ b/Color.hpp @@ -0,0 +1,36 @@ +// +// Color.hpp +// screensaver +// +// Created by Bob Polis at 2020-10-27 +// Copyright (c) 2020 SwiftCoder. All rights reserved. +// + +#ifndef _Color_H_ +#define _Color_H_ + +struct RGB { + double r; + double g; + double b; +}; + +struct HSB { + double h; + double s; + double b; +}; + +class Color { + public: + Color(const RGB& rgb); + Color(const HSB& hsb); + + operator RGB() const { return _rgb; } + operator HSB() const; + + private: + RGB _rgb; +}; + +#endif // _Color_H_