Fix HSL->RGB conversion

This commit is contained in:
Kuba Birecki 2021-12-04 17:13:40 +01:00
parent 2326f36e50
commit f50037dcbb

View file

@ -5,8 +5,24 @@
*/ */
#include <stdlib.h> #include <stdlib.h>
#include <zmk/animation.h> #include <zmk/animation.h>
static float fmod(float a, float b) {
float mod = a < 0 ? -a : a;
float x = b < 0 ? -b : b;
while (mod >= x) {
mod = mod - x;
}
return a < 0 ? -mod : mod;
}
static float fabs(float a) {
return a < 0 ? -a : a;
}
/** /**
* HSL chosen over HSV/HSB as it shares the same parameters with LCh or HSLuv. * HSL chosen over HSV/HSB as it shares the same parameters with LCh or HSLuv.
* The latter color spaces could be interesting to experiment with because of their * The latter color spaces could be interesting to experiment with because of their
@ -16,39 +32,45 @@
* Algorithm source: https://www.tlbx.app/color-converter * Algorithm source: https://www.tlbx.app/color-converter
*/ */
void zmk_hsl_to_rgb(const struct zmk_color_hsl *hsl, struct zmk_color_rgb *rgb) { void zmk_hsl_to_rgb(const struct zmk_color_hsl *hsl, struct zmk_color_rgb *rgb) {
// float a = hsl->h / 60; float s = (float) hsl->s / 100;
uint8_t a = hsl->h / 60; float l = (float) hsl->l / 100;
float chroma = hsl->s * (1 - abs(2 * hsl->l - 1));
// I think 'a' actually needs to be a float here or this doesn't make sense.
// If uint, possible values are: (0,1), if float: (0...1)
float x = chroma * (1 - abs(a % 2 - 1));
float m = hsl->l - chroma / 2;
switch (a) { float a = (float) hsl->h / 60;
float chroma = s * (1 - fabs(2 * l - 1));
float x = chroma * (1 - fabs(fmod(a, 2) - 1));
float m = l - chroma / 2;
switch ((uint8_t) a % 6) {
case 0: case 0:
rgb->r = m + chroma; rgb->r = m + chroma;
rgb->g = m + x; rgb->g = m + x;
rgb->b = m; rgb->b = m;
break;
case 1: case 1:
rgb->r = m + x; rgb->r = m + x;
rgb->g = m + chroma; rgb->g = m + chroma;
rgb->b = m; rgb->b = m;
break;
case 2: case 2:
rgb->r = m; rgb->r = m;
rgb->g = m + chroma; rgb->g = m + chroma;
rgb->b = m + x; rgb->b = m + x;
break;
case 3: case 3:
rgb->r = m; rgb->r = m;
rgb->g = m + x; rgb->g = m + x;
rgb->b = m + chroma; rgb->b = m + chroma;
break;
case 4: case 4:
rgb->r = m + x; rgb->r = m + x;
rgb->g = m; rgb->g = m;
rgb->b = m + chroma; rgb->b = m + chroma;
break;
case 5: case 5:
rgb->r = m + chroma; rgb->r = m + chroma;
rgb->g = m; rgb->g = m;
rgb->b = m + x; rgb->b = m + x;
break;
} }
} }
@ -56,9 +78,9 @@ void zmk_hsl_to_rgb(const struct zmk_color_hsl *hsl, struct zmk_color_rgb *rgb)
* Converts ZMKs RGB (float) to Zephyr's led_rgb (uint8_t) format. * Converts ZMKs RGB (float) to Zephyr's led_rgb (uint8_t) format.
*/ */
void zmk_rgb_to_led_rgb(const struct zmk_color_rgb *rgb, struct led_rgb *led) { void zmk_rgb_to_led_rgb(const struct zmk_color_rgb *rgb, struct led_rgb *led) {
led->r = rgb->r * 255; led->r = (uint8_t) (rgb->r * 255);
led->g = rgb->g * 255; led->g = (uint8_t) (rgb->g * 255);
led->b = rgb->b * 255; led->b = (uint8_t) (rgb->b * 255);
} }
/** /**