From 760a1d45124903070a62944faf6f0f3e95e9bbaf Mon Sep 17 00:00:00 2001 From: TripleWhy Date: Sat, 13 Jan 2024 18:52:57 +0100 Subject: [PATCH] Make color_wheel rotate in HSV sapce instead of linearly interpolating R->G->B --- wled00/FX_fcn.cpp | 23 +++++++++++++---------- 1 file changed, 13 insertions(+), 10 deletions(-) diff --git a/wled00/FX_fcn.cpp b/wled00/FX_fcn.cpp index 96e397aba1..b28ce4c91f 100644 --- a/wled00/FX_fcn.cpp +++ b/wled00/FX_fcn.cpp @@ -1022,20 +1022,23 @@ void Segment::blur(uint8_t blur_amount) { /* * Put a value 0 to 255 in to get a color value. * The colours are a transition r -> g -> b -> back to r - * Inspired by the Adafruit examples. + * Rotates the color in HSV space, where pos is H. (0=0deg, 256=360deg) */ uint32_t Segment::color_wheel(uint8_t pos) { if (palette) return color_from_palette(pos, false, true, 0); uint8_t w = W(currentColor(0)); - pos = 255 - pos; - if (pos < 85) { - return RGBW32((255 - pos * 3), 0, (pos * 3), w); - } else if(pos < 170) { - pos -= 85; - return RGBW32(0, (pos * 3), (255 - pos * 3), w); - } else { - pos -= 170; - return RGBW32((pos * 3), (255 - pos * 3), 0, w); + // These h and f values are the same h and f you have in the regular HSV to RGB conversion. + // The whole funciton really is just a HSV conversion, but assuming H=pos, S=1 and V=1. + const uint32_t h = (pos * 3) / 128; + const uint32_t f = (pos * 6) % 256; + switch (h) { + case 0: return RGBW32(255 , f , 0 , w); + case 1: return RGBW32(255 - f, 255 , 0 , w); + case 2: return RGBW32(0 , 255 , f , w); + case 3: return RGBW32(0 , 255 - f, 255 , w); + case 4: return RGBW32(f , 0 , 255 , w); + case 5: return RGBW32(255 , 0 , 255 - f, w); + default: return 0; } }