From 501031d18148c7e2cb37f634734d4fc6a300d9c5 Mon Sep 17 00:00:00 2001 From: profezzorn Date: Sat, 3 Feb 2024 15:15:49 -0600 Subject: [PATCH] fix HSL --- common/color.h | 18 +++++++++++++----- common/tests.cpp | 17 +++++++++++++++++ 2 files changed, 30 insertions(+), 5 deletions(-) diff --git a/common/color.h b/common/color.h index e985131ee..0ba20589a 100644 --- a/common/color.h +++ b/common/color.h @@ -172,6 +172,14 @@ class HSL { HSL rotate(float angle) { return HSL(fract(H + angle), S, L); } + void printTo(Print& p) { + p.print("HSL:"); + p.print(H); + p.write(','); + p.print(S); + p.write(','); + p.print(L); + } float H; // 0 - 1.0 float S; // 0 - 1.0 float L; // 0 - 1.0 @@ -305,23 +313,23 @@ class Color16 { int MAX = std::max(r, std::max(g, b)); int MIN = std::min(r, std::min(g, b)); int C = MAX - MIN; - int H; + float H; // Note 16384 = 60 degrees. if (C == 0) { H = 0; } else if (r == MAX) { // r is biggest - H = 16384 * (g - b) / C; + H = (g - b) / (float)C; } else if (g == MAX) { // g is biggest - H = 16384 * (b - r) / C + 16384 * 2; + H = (b - r) / (float)C + 2.0f; } else { // b is biggest - H = 16384 * (r - g) / C + 16384 * 4; + H = (r - g) / (float)C + 4.0f; } int L = MIN + MAX; float S = (MAX*2 - L) / (float)std::min(L, 131072 - L); - return HSL(H / 98304.0, S, L / 131070.0); + return HSL(fract(H / 6.0f), S, L / 131070.0); } explicit Color16(HSL hsl) { diff --git a/common/tests.cpp b/common/tests.cpp index f978985d3..c7ccf1ccd 100644 --- a/common/tests.cpp +++ b/common/tests.cpp @@ -127,6 +127,12 @@ BladeConfig* current_config; if (fabs(x_ - y_) > D) { std::cerr << #X << " (" << x_ << ") ~!= " << #Y << " (" << y_ << ") line " << __LINE__ << std::endl; exit(1); } \ } while(0) +#define CHECK_NEAR_MSG(X, Y, D, MSG) do { \ + auto x_ = (X); \ + auto y_ = (Y); \ + if (fabs(x_ - y_) > D) { STDOUT << #X << " (" << x_ << ") ~!= " << #Y << " (" << y_ << ") " << MSG << " line " << __LINE__ << "\n"; exit(1); } \ +} while(0) + #define CHECK_LT(X, Y) do { \ auto x_ = (X); \ auto y_ = (Y); \ @@ -326,6 +332,17 @@ void test_rotate(Color16 c, int angle) { // Test HSL HSL hsl = c.toHSL(); + CHECK_LE(0.0, hsl.H); + CHECK_LE(0.0, hsl.S); + CHECK_LE(0.0, hsl.L); + CHECK_LE(hsl.H, 1.0); + CHECK_LE(hsl.S, 1.0); + CHECK_LE(hsl.L, 1.0); + Color16 result3(hsl); + CHECK_NEAR_MSG(result3.r, c.r, 1, " in:" << c << " out:" << result3 << " hsl:" << hsl); + CHECK_NEAR_MSG(result3.g, c.g, 1, " in:" << c << " out:" << result3 << " hsl:" << hsl); + CHECK_NEAR_MSG(result3.b, c.b, 1, " in:" << c << " out:" << result3 << " hsl:" << hsl); + hsl = hsl.rotate(angle / (float)(32768 * 3)); // fprintf(stderr, "Angle = %d HSL={%f,%f,%f} RGB=%d,%d,%d\n", angle, hsl.H, hsl.S, hsl.L, c.r, c.g, c.b); CHECK_LE(0.0, hsl.H);