Skip to content

Commit

Permalink
Improve color_wheel so it blends more between colors
Browse files Browse the repository at this point in the history
Fix: improved accuracy of generated rainbow colors for LEDs
  • Loading branch information
acheronfail committed Aug 16, 2024
1 parent 5e73abf commit fae127c
Showing 1 changed file with 15 additions and 11 deletions.
26 changes: 15 additions & 11 deletions src/leds.c
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@
#define W(c) ((uint8_t) ((c) >> 24))
#define RGB(r, g, b) ((r) << 16 | (g) << 8 | (b))
#define RGBW(r, g, b, w) ((w) << 24 | (r) << 16 | (g) << 8 | (b))
#define TAU (2.0 * M_PI)

static const uint32_t colors[] = {
0x00000000, // BLACK
Expand Down Expand Up @@ -99,18 +100,21 @@ static uint32_t color_blend(uint32_t color1, uint32_t color2, float blend) {
return RGBW(r, g, b, w);
}

// Borrowed from WLED
// This function is an approximation of `sqrtf(sinf(x) * 0.5 + 0.5)`
inline static float taylor_series(float zero_to_tau) {
float x = (-0.5 * zero_to_tau) + 2.4;
float x3 = x * x * x;
float x5 = x3 * x * x;
float r = fabs(x - (x3 / 6.0) + (x5 / 120.0));
return fminf(r, 1.0f);
}

static uint32_t color_wheel(uint8_t pos) {
pos = 255 - pos;
if (pos < 85) {
return ((uint32_t) (255 - pos * 3) << 16) | ((uint32_t) 0 << 8) | (pos * 3);
} else if (pos < 170) {
pos -= 85;
return ((uint32_t) 0 << 16) | ((uint32_t) (pos * 3) << 8) | (255 - pos * 3);
} else {
pos -= 170;
return ((uint32_t) (pos * 3) << 16) | ((uint32_t) (255 - pos * 3) << 8) | 0;
}
float norm = (float) pos / 255.0;
float r = taylor_series((norm + 0.0 / 3.0) * TAU);
float b = taylor_series((norm + 1.0 / 3.0) * TAU);
float g = taylor_series((norm + 2.0 / 3.0) * TAU);
return ((uint8_t) (r * 255) << 16) | ((uint8_t) (g * 255) << 8) | (uint8_t) (b * 255);
}

static void sattolo_shuffle(uint32_t seed, uint8_t *array, uint8_t length) {
Expand Down

0 comments on commit fae127c

Please sign in to comment.