1
1
Fork 0
Browse Source

Add colour pallete generator, hsv-hsl-rgb converter

thread-physics
alistair 4 years ago
parent
commit
f0187b0243
  1. 250
      colours.c
  2. 7
      main.c

250
colours.c

@ -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

7
main.c

@ -65,6 +65,7 @@ int physics_loop(void *ptr) { @@ -65,6 +65,7 @@ int physics_loop(void *ptr) {
}
}
int game(void) {
LOGLEVEL = DEBUG;
STDOUTLEVEL = DEBUG;
@ -73,7 +74,8 @@ int game(void) { @@ -73,7 +74,8 @@ int game(void) {
logwrite(INFO, "Starting\n");
SDL_Window * win = make_window();
SDL_Renderer * ren = SDL_CreateRenderer(win, -1, SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC);
SDL_Renderer * ren = SDL_CreateRenderer(win, -1, SDL_RENDERER_ACCELERATED
| SDL_RENDERER_PRESENTVSYNC);
queue_for_cleanup(win, WINDOW);
queue_for_cleanup(ren, RENDERER);
@ -91,7 +93,7 @@ int game(void) { @@ -91,7 +93,7 @@ int game(void) {
SDL_Thread *physics_thread;
int ignore;
// physics_thread = SDL_CreateThread(physics_loop, "Physics", (void *)NULL);
physics_thread = SDL_CreateThread(physics_loop, "Physics", (void *)NULL);
bool once = true;
startgame(ren);
@ -112,7 +114,6 @@ int game(void) { @@ -112,7 +114,6 @@ int game(void) {
}
/* Redraw Screen */
redraw(ren);
step(10);
}
}

Loading…
Cancel
Save