alistair
4 years ago
2 changed files with 254 additions and 3 deletions
@ -0,0 +1,250 @@
@@ -0,0 +1,250 @@
|
||||
#include <SDL2/SDL.h> |
||||
#include <stdbool.h> |
||||
#include <time.h> |
||||
|
||||
SDL_Color get_random_color(unsigned int seed) { |
||||
int red = rand_r(&seed) % 255; |
||||
int blue = rand_r(&seed) % 255; |
||||
int green = rand_r(&seed) % 255; |
||||
|
||||
SDL_Color col; |
||||
col.r = red; |
||||
col.g = green; |
||||
col.b = blue; |
||||
return col; |
||||
} |
||||
|
||||
double m_min(double arr[], int len) { |
||||
double largest = arr[0]; |
||||
for (int i = 0; i < len; i ++) { |
||||
if (arr[i] < largest) { |
||||
largest = arr[i]; |
||||
} |
||||
} |
||||
return largest; |
||||
} |
||||
|
||||
|
||||
double m_max(double arr[], int len) { |
||||
double largest = arr[0]; |
||||
for (int i = 0; i < len; i ++) { |
||||
if (arr[i] > largest) { |
||||
largest = arr[i]; |
||||
} |
||||
} |
||||
return largest; |
||||
} |
||||
|
||||
bool m_equal(double a, double b) { |
||||
return (a - b) * (a - b) < 0.00001; |
||||
} |
||||
|
||||
|
||||
enum colour_space { |
||||
CS_HSV, |
||||
CS_HSL, |
||||
CS_RGB |
||||
}; |
||||
|
||||
struct colour { |
||||
double h; |
||||
double s; |
||||
double v; |
||||
double l; |
||||
enum colour_space sp; |
||||
}; |
||||
|
||||
// h = [0,360], s = [0,1], v = [0,1] // if s == 0, then h = -1 (undefined)
|
||||
struct colour get_hs_l_v(SDL_Color c, enum colour_space sp) { |
||||
struct colour ret; |
||||
memset(&ret, 0, sizeof(struct colour)); |
||||
double r = (double)c.r / 255; |
||||
double g = (double)c.g / 255; |
||||
double b = (double)c.b / 255; |
||||
|
||||
double arr[] = {r, g, b}; |
||||
double max = m_max(arr, 3); |
||||
double min = m_min(arr, 3); |
||||
|
||||
ret.v = max; |
||||
|
||||
double chroma = max - min; |
||||
|
||||
double lum = (max + min) / 2; |
||||
ret.l = lum; |
||||
|
||||
if (m_equal(chroma, 0)) { |
||||
ret.h = 0; |
||||
} else if (m_equal(ret.v,r)) { |
||||
ret.h = (g - b) / chroma; |
||||
} else if (m_equal(max,g)) { |
||||
ret.h = 2 + (b - r) / chroma; |
||||
} else if (m_equal(max,b)) { |
||||
ret.h = 4 + (r - g) / chroma; |
||||
} else { |
||||
printf("NOPE BAD ERROR\n"); |
||||
}
|
||||
|
||||
ret.h *= 60; |
||||
ret.h = fmod(ret.h, 360); |
||||
if (ret.h < 0) { |
||||
ret.h += 360; |
||||
} |
||||
|
||||
if (sp == CS_HSV) { |
||||
if (m_equal(max,0)) { |
||||
ret.s = 0; |
||||
} else { |
||||
ret.s = chroma / max; |
||||
} |
||||
} else { |
||||
double arr[] = {ret.l, 1 - ret.l}; |
||||
if (m_equal(0, lum) || m_equal(1, lum)) { |
||||
ret.s = 0; |
||||
} else { |
||||
ret.s = (ret.v - ret.l) / m_min(arr, 2);
|
||||
} |
||||
} |
||||
return ret; |
||||
} |
||||
|
||||
struct colour get_hsl(SDL_Color c) { |
||||
return get_hs_l_v(c, CS_HSL);
|
||||
} |
||||
|
||||
struct colour get_hsv(SDL_Color c) { |
||||
return get_hs_l_v(c, CS_HSV);
|
||||
} |
||||
|
||||
// https://en.wikipedia.org/wiki/HSI_color_space
|
||||
double magic_hsv_function(int n, struct colour c) { |
||||
double res = c.v - c.v * c.s; |
||||
double k = fmod(n + (c.h / 60), 6); |
||||
double arr[] = {k, 4 - k, 1}; |
||||
res = res * m_max(arr, 3);
|
||||
return res; |
||||
} |
||||
|
||||
SDL_Color get_rgb_from_hsv(struct colour c) { |
||||
|
||||
double r = magic_hsv_function(5, c); |
||||
double g = magic_hsv_function(3, c); |
||||
double b = magic_hsv_function(1, c); |
||||
|
||||
SDL_Color res; |
||||
res.r = round(r * 255); |
||||
res.g = round(g * 255); |
||||
res.b = round(b * 255); |
||||
return res; |
||||
|
||||
} |
||||
|
||||
double magic_hsl_function(int n, struct colour c) { |
||||
double arr[] = {c.l, 1-c.l}; |
||||
double a = c.s * ( c.l < (1-c.l) ? c.l : 1 - c.l ); |
||||
double k = fmod(n + c.h / 30, 12); |
||||
|
||||
double b[] = {k - 3, 9 -k, 1}; |
||||
double d[] = {-1, m_min(b, 3)}; |
||||
return c.l - a * (d[0] > d[1] ? d[0] : d[1]); |
||||
} |
||||
|
||||
SDL_Color get_rgb_from_hsl(struct colour c) { |
||||
double r = magic_hsl_function(0, c); |
||||
double g = magic_hsl_function(8, c); |
||||
double b = magic_hsl_function(4, c); |
||||
|
||||
SDL_Color res; |
||||
res.r = round(r * 255); |
||||
res.g = round(g * 255); |
||||
res.b = round(b * 255); |
||||
return res; |
||||
} |
||||
|
||||
SDL_Color get_rgb(struct colour c) { |
||||
if (c.sp == CS_HSL) { |
||||
return get_rgb_from_hsl(c); |
||||
} |
||||
if (c.sp == CS_HSV) { |
||||
return get_rgb_from_hsv(c); |
||||
} |
||||
|
||||
SDL_Color d; |
||||
memset(&d, 0, sizeof(SDL_Color)); |
||||
return d; |
||||
} |
||||
|
||||
SDL_Color *get_adjacent(SDL_Color base, int deg, int num) { |
||||
struct colour col = get_hsl(base); |
||||
num += 1; |
||||
|
||||
struct colour* colours = alloca(sizeof(struct colour) * num);
|
||||
|
||||
for (int i = 0; i < num; i++) { |
||||
int m = (i % 2 == 0) ? -i : i; |
||||
|
||||
colours[i] = col; |
||||
colours[i].h += m * deg; |
||||
colours[i].h += fmod(colours[i].h, 360); |
||||
} |
||||
|
||||
SDL_Color *ret_colours = calloc(num, sizeof(SDL_Color) * num); |
||||
|
||||
for (int i = 0; i < num; i++) { |
||||
ret_colours[i] = get_rgb(colours[i]); |
||||
} |
||||
return ret_colours; |
||||
} |
||||
|
||||
void print_colour(SDL_Color c) { |
||||
printf("//\"#%02x%02x%02x\n", c.r, c.g, c.b); |
||||
} |
||||
|
||||
void test(int seed) { |
||||
SDL_Color c = get_random_color(seed); |
||||
//print_colour(c);
|
||||
struct colour hsl = get_hsl(c); |
||||
struct colour hsv = get_hsv(c); |
||||
/*printf("RGB: %d %d %d\n",c.r,c.g,c.b);*/ |
||||
/*printf("HSL: %f %f %f\n",hsl.h, hsl.s, hsl.l);*/ |
||||
/*printf("HSV: %f %f %f\n",hsv.h, hsv.s, hsv.v);*/ |
||||
|
||||
SDL_Color *adj = get_adjacent(c, 5, 4); |
||||
for (int i = 0; i < 5; i++) { |
||||
print_colour(adj[i]); |
||||
} |
||||
printf("\n"); |
||||
} |
||||
|
||||
int main() { |
||||
test(1231); |
||||
test(2131); |
||||
test(123); |
||||
test(121); |
||||
test(1802); |
||||
} |
||||
|
||||
//"#d48d47
|
||||
//"#88934c
|
||||
//"#c88153
|
||||
//"#7c9f58
|
||||
//"#bc755f
|
||||
|
||||
//"#c67c64
|
||||
//"#cc825e
|
||||
//"#ba6f70
|
||||
//"#d98e51
|
||||
//"#ad637d
|
||||
|
||||
//"#221534
|
||||
//"#241336
|
||||
//"#1f1831
|
||||
//"#271423
|
||||
//"#1c1b2e
|
||||
|
||||
//"#77f0a6
|
||||
//"#83fb9a
|
||||
//"#61dabc
|
||||
//"#0b128b
|
||||
//"#4ac3d3
|
||||
|
Loading…
Reference in new issue