Removed rounding error in int->float color conversions

main
noah metz 2024-11-17 16:18:54 -07:00
parent 8a30340202
commit d82269f640
2 changed files with 10 additions and 38 deletions

@ -104,10 +104,10 @@ typedef struct ColorUIDataStruct {
void set_rgb_from_hsv(UIContext* ui, RenderContext* gpu, ColorUIData* data, double hsv[3]) { void set_rgb_from_hsv(UIContext* ui, RenderContext* gpu, ColorUIData* data, double hsv[3]) {
hsv_to_rgb(hsv, data->current); hsv_to_rgb(hsv, data->current);
snprintf(data->string, 10, "#%02X%02X%02X%02X", snprintf(data->string, 10, "#%02X%02X%02X%02X",
(uint)(data->current[0]*255), (uint)rintf(data->current[0]*255),
(uint)(data->current[1]*255), (uint)rintf(data->current[1]*255),
(uint)(data->current[2]*255), (uint)rintf(data->current[2]*255),
(uint)(data->current[3]*255)); (uint)rintf(data->current[3]*255));
data->string_len = 8; data->string_len = 8;
update_ui_string(data->string, COLOR_PICK_CONTAINER_ID, 0, 0, ui, gpu); update_ui_string(data->string, COLOR_PICK_CONTAINER_ID, 0, 0, ui, gpu);
} }

@ -1,6 +1,5 @@
#include "hsv.h" #include "hsv.h"
#include <stdio.h> #include <stdio.h>
#include <stdlib.h>
#include <math.h> #include <math.h>
#define FAIL -1 #define FAIL -1
@ -13,17 +12,17 @@ int test_conv(int r, int g, int b, double tolerance) {
int test[3]; int test[3];
rgb_to_hsv(rgb, hsv); rgb_to_hsv(rgb, hsv);
hsv_to_rgb(hsv, out); hsv_to_rgb(hsv, out);
test[0] = out[0]*255.0; test[0] = rintf(out[0]*255.0);
test[1] = out[1]*255.0; test[1] = rintf(out[1]*255.0);
test[2] = out[2]*255.0; test[2] = rintf(out[2]*255.0);
if(fabs(rgb[0] - out[0]) > tolerance || fabs(rgb[1] - out[1]) > tolerance || fabs(rgb[2] - out[2]) > tolerance) { if(fabs(rgb[0] - out[0]) > tolerance || fabs(rgb[1] - out[1]) > tolerance || fabs(rgb[2] - out[2]) > tolerance || r != test[0] || g != test[1] || b != test[2]) {
fprintf(stderr, "FAIL:\t#%02X%02X%02X -> #%02X%02X%02X\nIN:\t(%.12f %.12f %.12f)\nOUT:\t(%.12f %.12f %.12f)\nDIF:\t(%.12f %.12f %.12f)\n", fprintf(stderr, "FAIL:\t#%02X%02X%02X -> #%02X%02X%02X\nIN:\t(%.12f %.12f %.12f)\nOUT:\t(%.12f %.12f %.12f)\nMULT:\t(%.12f %.12f %.12f)\n",
r, g, b, r, g, b,
test[0], test[1], test[2], test[0], test[1], test[2],
rgb[0], rgb[1], rgb[2], rgb[0], rgb[1], rgb[2],
out[0], out[1], out[2], out[0], out[1], out[2],
rgb[0]-out[0], rgb[1]-out[1], rgb[2]-out[2]); rintf(out[0]*255.0), rintf(out[1]*255.0), rintf(out[2]*255.0));
return FAIL; return FAIL;
} else { } else {
return OK; return OK;
@ -41,30 +40,3 @@ int main() {
} }
} }
} }
// To RGB steps:
// 1. C = V * S <- maps to 3 in inv
// 2. H' = H * 6 <- maps to 7 in inv
// 3. X = C * (1 - abs(H' - 2*floor(H'/2) - 1))
// 4. M = V - C <- maps to 4 in inv
// 5. R = V, G = X + M, B = M
// To HSV steps:
// 1. V = max(R, G, B) <- maps to 5,R in inv
// 2. M = min(R, G, B) <- maps to 5,B in inv
// 3. S = C / V <- maps to 1 in inv
// 4. C = V - M <- maps to 4 in inv
// 5. X = G - M
// 6. H' = X/C
// 7. H = H'/6 <- maps to 2 in inv
//
// So out of the two algos, the only step that doest match exactly so far is
// RGB: X = C * (1 - abs(H' - 2*floor(H'/2) - 1))
// HSV: X = G - M, H' = X/C
//
// After floor():
// RGB: X = C * (1 - abs(H' - 1))
//
// After abs() assuming H' = [0, 1]:
// RGB: X = C * (1 - (1 - H'))
// RGB: X = C * H'