2020-10-27 22:32:37 +01:00
|
|
|
//
|
|
|
|
// Color.cpp
|
|
|
|
// screensaver
|
|
|
|
//
|
|
|
|
// Created by Bob Polis at 2020-10-27
|
|
|
|
// Copyright (c) 2020 SwiftCoder. All rights reserved.
|
|
|
|
//
|
|
|
|
|
|
|
|
#include "Color.hpp"
|
|
|
|
#include <algorithm>
|
|
|
|
#include <cmath>
|
|
|
|
|
|
|
|
Color::Color(const RGB& rgb) : _rgb {rgb} {}
|
|
|
|
|
|
|
|
Color::Color(const HSB& hsb) {
|
2020-10-28 15:46:17 +01:00
|
|
|
if (hsb.s <= 0) {
|
2020-10-27 22:32:37 +01:00
|
|
|
_rgb.r = _rgb.g = _rgb.b = hsb.b;
|
|
|
|
} else {
|
2020-10-28 15:46:17 +01:00
|
|
|
double hi = hsb.h / 60;
|
|
|
|
int i = static_cast<int>(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) {
|
2020-10-27 22:32:37 +01:00
|
|
|
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:
|
2020-10-28 15:46:17 +01:00
|
|
|
default:
|
2020-10-27 22:32:37 +01:00
|
|
|
_rgb.r = hsb.b;
|
|
|
|
_rgb.g = p;
|
|
|
|
_rgb.b = q;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
Color::operator HSB() const {
|
|
|
|
HSB hsb;
|
|
|
|
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 delta = rgb_max - rgb_min;
|
2020-10-28 15:46:17 +01:00
|
|
|
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;
|
2020-10-27 22:32:37 +01:00
|
|
|
}
|
2020-10-28 15:46:17 +01:00
|
|
|
hsb.h *= 60;
|
|
|
|
hsb.s = rgb_max > 0.0 ? delta / rgb_max : 0;
|
2020-10-27 22:32:37 +01:00
|
|
|
hsb.b = rgb_max;
|
|
|
|
return hsb;
|
|
|
|
}
|