|
|
|
@ -1,12 +1,23 @@
@@ -1,12 +1,23 @@
|
|
|
|
|
#include <SDL2/SDL.h> |
|
|
|
|
#include <stdbool.h> |
|
|
|
|
#include <stdlib.h> |
|
|
|
|
#include <string.h> |
|
|
|
|
#include <math.h> |
|
|
|
|
#include <stdio.h> |
|
|
|
|
|
|
|
|
|
struct rgb_colour { |
|
|
|
|
int r; |
|
|
|
|
int g; |
|
|
|
|
int b; |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
typedef struct rgb_colour rgb_colour; |
|
|
|
|
|
|
|
|
|
SDL_Color get_random_color(unsigned int seed) { |
|
|
|
|
rgb_colour 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; |
|
|
|
|
rgb_colour col; |
|
|
|
|
col.r = red; |
|
|
|
|
col.g = green; |
|
|
|
|
col.b = blue; |
|
|
|
@ -55,7 +66,7 @@ struct colour {
@@ -55,7 +66,7 @@ struct colour {
|
|
|
|
|
// https://en.wikipedia.org/wiki/HSL_and_HSV#From_RGB
|
|
|
|
|
// 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 get_hs_l_v(rgb_colour c, enum colour_space sp) { |
|
|
|
|
struct colour ret; |
|
|
|
|
memset(&ret, 0, sizeof(struct colour)); |
|
|
|
|
double r = (double)c.r / 255; |
|
|
|
@ -108,11 +119,11 @@ struct colour get_hs_l_v(SDL_Color c, enum colour_space sp) {
@@ -108,11 +119,11 @@ struct colour get_hs_l_v(SDL_Color c, enum colour_space sp) {
|
|
|
|
|
return ret; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
struct colour get_hsl(SDL_Color c) { |
|
|
|
|
struct colour get_hsl(rgb_colour c) { |
|
|
|
|
return get_hs_l_v(c, CS_HSL);
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
struct colour get_hsv(SDL_Color c) { |
|
|
|
|
struct colour get_hsv(rgb_colour c) { |
|
|
|
|
return get_hs_l_v(c, CS_HSV);
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
@ -126,13 +137,13 @@ double magic_hsv_function(int n, struct colour c) {
@@ -126,13 +137,13 @@ double magic_hsv_function(int n, struct colour c) {
|
|
|
|
|
return res; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
SDL_Color get_rgb_from_hsv(struct colour c) { |
|
|
|
|
rgb_colour 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; |
|
|
|
|
rgb_colour res; |
|
|
|
|
res.r = round(r * 255); |
|
|
|
|
res.g = round(g * 255); |
|
|
|
|
res.b = round(b * 255); |
|
|
|
@ -150,19 +161,19 @@ double magic_hsl_function(int n, struct colour c) {
@@ -150,19 +161,19 @@ double magic_hsl_function(int n, struct colour c) {
|
|
|
|
|
return c.l - a * (d[0] > d[1] ? d[0] : d[1]); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
SDL_Color get_rgb_from_hsl(struct colour c) { |
|
|
|
|
rgb_colour 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; |
|
|
|
|
rgb_colour 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) { |
|
|
|
|
rgb_colour get_rgb(struct colour c) { |
|
|
|
|
if (c.sp == CS_HSL) { |
|
|
|
|
return get_rgb_from_hsl(c); |
|
|
|
|
} |
|
|
|
@ -170,12 +181,21 @@ SDL_Color get_rgb(struct colour c) {
@@ -170,12 +181,21 @@ SDL_Color get_rgb(struct colour c) {
|
|
|
|
|
return get_rgb_from_hsv(c); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
SDL_Color d; |
|
|
|
|
memset(&d, 0, sizeof(SDL_Color)); |
|
|
|
|
rgb_colour d; |
|
|
|
|
memset(&d, 0, sizeof(rgb_colour)); |
|
|
|
|
return d; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
SDL_Color *get_adjacent(SDL_Color base, int deg, int num) { |
|
|
|
|
int compare_perceived_lum(const void* c1, const void* c2) { |
|
|
|
|
rgb_colour rgb_c1 = *(rgb_colour*)c1; |
|
|
|
|
rgb_colour rgb_c2 = *(rgb_colour*)c2; |
|
|
|
|
|
|
|
|
|
double lum1 = 0.299*rgb_c1.r + 0.587*rgb_c1.g + 0.114*rgb_c1.b; |
|
|
|
|
double lum2 = 0.299*rgb_c2.r + 0.587*rgb_c2.g + 0.114*rgb_c2.b; |
|
|
|
|
return lum1 - lum2; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
rgb_colour *get_adjacent(rgb_colour base, int deg, int num) { |
|
|
|
|
struct colour col = get_hsl(base); |
|
|
|
|
num += 1; |
|
|
|
|
|
|
|
|
@ -189,20 +209,28 @@ SDL_Color *get_adjacent(SDL_Color base, int deg, int num) {
@@ -189,20 +209,28 @@ SDL_Color *get_adjacent(SDL_Color base, int deg, int num) {
|
|
|
|
|
colours[i].h += fmod(colours[i].h, 360); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
SDL_Color *ret_colours = calloc(num, sizeof(SDL_Color) * num); |
|
|
|
|
rgb_colour *ret_colours = calloc(num, sizeof(rgb_colour) * num); |
|
|
|
|
|
|
|
|
|
for (int i = 0; i < num; i++) { |
|
|
|
|
ret_colours[i] = get_rgb(colours[i]); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// sort from dark to bright
|
|
|
|
|
qsort(ret_colours, num, sizeof(rgb_colour), compare_perceived_lum); |
|
|
|
|
|
|
|
|
|
return ret_colours; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void print_colour(SDL_Color c) { |
|
|
|
|
printf("//\"#%02x%02x%02x\n", c.r, c.g, c.b); |
|
|
|
|
void print_colour(rgb_colour c) { |
|
|
|
|
char *colour = calloc(20, sizeof(char)); |
|
|
|
|
sprintf(colour, "#%02x%02x%02x", c.r, c.g, c.b); |
|
|
|
|
|
|
|
|
|
printf("\x1b[38;2;%d;%d;%dm%s\x1b[0m\n", c.r, c.g, c.b, colour); |
|
|
|
|
free(colour); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void test(int seed) { |
|
|
|
|
SDL_Color c = get_random_color(seed); |
|
|
|
|
rgb_colour c = get_random_color(seed); |
|
|
|
|
//print_colour(c);
|
|
|
|
|
struct colour hsl = get_hsl(c); |
|
|
|
|
struct colour hsv = get_hsv(c); |
|
|
|
@ -210,10 +238,12 @@ void test(int seed) {
@@ -210,10 +238,12 @@ void test(int seed) {
|
|
|
|
|
/*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); |
|
|
|
|
rgb_colour *adj = get_adjacent(c, 5, 4); |
|
|
|
|
for (int i = 0; i < 5; i++) { |
|
|
|
|
print_colour(adj[i]); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
free(adj); |
|
|
|
|
printf("\n"); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
@ -225,15 +255,30 @@ void wheel() {
@@ -225,15 +255,30 @@ void wheel() {
|
|
|
|
|
c.sp = CS_HSV; |
|
|
|
|
for(int i = 0; i < 360; i+=5) { |
|
|
|
|
c.h = (double)i; |
|
|
|
|
SDL_Color rgb = get_rgb(c); |
|
|
|
|
rgb_colour rgb = get_rgb(c); |
|
|
|
|
/*printf("HSL: %f %f %f\n",c.h, c.s, c.l);*/ |
|
|
|
|
/*printf("RGB: %d %d %d\n",rgb.r,rgb.g,rgb.b);*/ |
|
|
|
|
print_colour(rgb); |
|
|
|
|
|
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
int main() { |
|
|
|
|
wheel(); |
|
|
|
|
/*test(100);*/ |
|
|
|
|
/*test(400);*/ |
|
|
|
|
/*test(310);*/ |
|
|
|
|
/*test(2900);*/ |
|
|
|
|
/*test(2100);*/ |
|
|
|
|
/*test(260);*/ |
|
|
|
|
/*test(240);*/ |
|
|
|
|
|
|
|
|
|
rgb_colour c = get_random_color(128); |
|
|
|
|
rgb_colour *adj = get_adjacent(c, 2, 20); |
|
|
|
|
for (int i = 0; i < 20; i++) { |
|
|
|
|
print_colour(adj[i]); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
free(adj); |
|
|
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|