63 lines
1.7 KiB
C
63 lines
1.7 KiB
C
#include "color_hsv.h"
|
|
|
|
void interpolate(hsv_t start, hsv_t end, size_t steps, hsv_t *colors) {
|
|
if( steps == 1 ) {
|
|
colors[0] = start;
|
|
return;
|
|
}
|
|
|
|
for( size_t i = 0; i < steps; i++ ) {
|
|
hsv_t tmp;
|
|
tmp.hue = (uint16_t)((int16_t)start.hue + ((int16_t)end.hue - (int16_t)start.hue) * (int16_t)i / ((int16_t)steps-1));
|
|
tmp.sat = (uint8_t)((int16_t)start.sat + ((int16_t)end.sat - (int16_t)start.sat) * (int16_t)i / ((int16_t)steps-1));
|
|
tmp.val = (uint8_t)((int16_t)start.val + ((int16_t)end.val - (int16_t)start.val) * (int16_t)i / ((int16_t)steps-1));
|
|
colors[i] = tmp;
|
|
}
|
|
}
|
|
|
|
void hsv2rgbList(hsv_t* hsvList, rgb_t* rgbList, size_t count) {
|
|
for(size_t i = 0; i < count; ++i) {
|
|
rgbList[i] = hsv2rgb(&hsvList[i]);
|
|
}
|
|
}
|
|
|
|
rgb_t hsv2rgb(hsv_t* hsv) {
|
|
rgb_t res;
|
|
|
|
if(hsv->sat == 0) {
|
|
res.r = res.g = res.b = hsv->val;
|
|
} else {
|
|
float hue = (float) (hsv->hue<360?hsv->hue:hsv->hue-360);
|
|
float val = ((float) hsv->val ) / 100.0;
|
|
float sat = ((float) hsv->sat ) / 100.0;
|
|
|
|
uint8_t h = hue / 60;
|
|
float f = ( hue / 60 ) - h;
|
|
|
|
uint8_t p = RGB_MAX * ( val * ( 1 - sat ));
|
|
uint8_t q = RGB_MAX * ( val * ( 1 - sat * f ));
|
|
uint8_t t = RGB_MAX * ( val * ( 1 - sat * ( 1 - f )));
|
|
|
|
switch(h) {
|
|
case 0:
|
|
case 6: res.r = hsv->val; res.g = t; res.b = p; break;
|
|
case 1: res.r = q; res.g = hsv->val; res.b = p; break;
|
|
case 2: res.r = p; res.g = hsv->val; res.b = t; break;
|
|
case 3: res.r = p; res.g = q; res.b = hsv->val; break;
|
|
case 4: res.r = t; res.g = p; res.b = hsv->val; break;
|
|
case 5: res.r = hsv->hue; res.g = p; res.b = q; break;
|
|
|
|
}
|
|
}
|
|
return res;
|
|
}
|
|
|
|
hsv_t init_hsv_t(uint16_t hue, uint8_t sat, uint8_t val) {
|
|
hsv_t tmp;
|
|
tmp.hue = hue;
|
|
tmp.sat = sat;
|
|
tmp.val = val;
|
|
|
|
return tmp;
|
|
}
|