|
|
|
@ -1,23 +1,11 @@
@@ -1,23 +1,11 @@
|
|
|
|
|
#include <stdbool.h> |
|
|
|
|
#include <stdlib.h> |
|
|
|
|
#include <string.h> |
|
|
|
|
#include <math.h> |
|
|
|
|
#include <stdio.h> |
|
|
|
|
#include "colours.h" |
|
|
|
|
|
|
|
|
|
struct rgb_colour { |
|
|
|
|
int r; |
|
|
|
|
int g; |
|
|
|
|
int b; |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
typedef struct rgb_colour rgb_colour; |
|
|
|
|
|
|
|
|
|
rgb_colour get_random_color(unsigned int seed) { |
|
|
|
|
struct 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; |
|
|
|
|
|
|
|
|
|
rgb_colour col; |
|
|
|
|
struct colour col; |
|
|
|
|
col.r = red; |
|
|
|
|
col.g = green; |
|
|
|
|
col.b = blue; |
|
|
|
@ -34,7 +22,6 @@ double m_min(double arr[], int len) {
@@ -34,7 +22,6 @@ double m_min(double arr[], int len) {
|
|
|
|
|
return largest; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
double m_max(double arr[], int len) { |
|
|
|
|
double largest = arr[0]; |
|
|
|
|
for (int i = 0; i < len; i ++) { |
|
|
|
@ -49,24 +36,10 @@ bool m_equal(double a, double b) {
@@ -49,24 +36,10 @@ 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; |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
// 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(rgb_colour c, enum colour_space sp) { |
|
|
|
|
struct colour get_hs_l_v(struct colour c, enum colour_space sp) { |
|
|
|
|
struct colour ret; |
|
|
|
|
memset(&ret, 0, sizeof(struct colour)); |
|
|
|
|
double r = (double)c.r / 255; |
|
|
|
@ -119,11 +92,11 @@ struct colour get_hs_l_v(rgb_colour c, enum colour_space sp) {
@@ -119,11 +92,11 @@ struct colour get_hs_l_v(rgb_colour c, enum colour_space sp) {
|
|
|
|
|
return ret; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
struct colour get_hsl(rgb_colour c) { |
|
|
|
|
struct colour get_hsl(struct colour c) { |
|
|
|
|
return get_hs_l_v(c, CS_HSL);
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
struct colour get_hsv(rgb_colour c) { |
|
|
|
|
struct colour get_hsv(struct colour c) { |
|
|
|
|
return get_hs_l_v(c, CS_HSV);
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
@ -137,13 +110,13 @@ double magic_hsv_function(int n, struct colour c) {
@@ -137,13 +110,13 @@ double magic_hsv_function(int n, struct colour c) {
|
|
|
|
|
return res; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
rgb_colour get_rgb_from_hsv(struct colour c) { |
|
|
|
|
struct 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); |
|
|
|
|
|
|
|
|
|
rgb_colour res; |
|
|
|
|
struct colour res; |
|
|
|
|
res.r = round(r * 255); |
|
|
|
|
res.g = round(g * 255); |
|
|
|
|
res.b = round(b * 255); |
|
|
|
@ -161,19 +134,19 @@ double magic_hsl_function(int n, struct colour c) {
@@ -161,19 +134,19 @@ double magic_hsl_function(int n, struct colour c) {
|
|
|
|
|
return c.l - a * (d[0] > d[1] ? d[0] : d[1]); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
rgb_colour get_rgb_from_hsl(struct colour c) { |
|
|
|
|
struct 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); |
|
|
|
|
|
|
|
|
|
rgb_colour res; |
|
|
|
|
struct colour res; |
|
|
|
|
res.r = round(r * 255); |
|
|
|
|
res.g = round(g * 255); |
|
|
|
|
res.b = round(b * 255); |
|
|
|
|
return res; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
rgb_colour get_rgb(struct colour c) { |
|
|
|
|
struct colour get_rgb(struct colour c) { |
|
|
|
|
if (c.sp == CS_HSL) { |
|
|
|
|
return get_rgb_from_hsl(c); |
|
|
|
|
} |
|
|
|
@ -181,21 +154,21 @@ rgb_colour get_rgb(struct colour c) {
@@ -181,21 +154,21 @@ rgb_colour get_rgb(struct colour c) {
|
|
|
|
|
return get_rgb_from_hsv(c); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
rgb_colour d; |
|
|
|
|
memset(&d, 0, sizeof(rgb_colour)); |
|
|
|
|
struct colour d; |
|
|
|
|
memset(&d, 0, sizeof(struct colour)); |
|
|
|
|
return d; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
int compare_perceived_lum(const void* c1, const void* c2) { |
|
|
|
|
rgb_colour rgb_c1 = *(rgb_colour*)c1; |
|
|
|
|
rgb_colour rgb_c2 = *(rgb_colour*)c2; |
|
|
|
|
struct colour rgb_c1 = *(struct colour*)c1; |
|
|
|
|
struct colour rgb_c2 = *(struct 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 *get_adjacent(struct colour base, int deg, int num) { |
|
|
|
|
struct colour col = get_hsl(base); |
|
|
|
|
num += 1; |
|
|
|
|
|
|
|
|
@ -209,19 +182,19 @@ rgb_colour *get_adjacent(rgb_colour base, int deg, int num) {
@@ -209,19 +182,19 @@ rgb_colour *get_adjacent(rgb_colour base, int deg, int num) {
|
|
|
|
|
colours[i].h += fmod(colours[i].h, 360); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
rgb_colour *ret_colours = calloc(num, sizeof(rgb_colour) * num); |
|
|
|
|
struct colour *ret_colours = calloc(num, sizeof(struct 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); |
|
|
|
|
qsort(ret_colours, num, sizeof(struct colour), compare_perceived_lum); |
|
|
|
|
|
|
|
|
|
return ret_colours; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void print_colour(rgb_colour c) { |
|
|
|
|
void print_colour(struct colour c) { |
|
|
|
|
char *colour = calloc(20, sizeof(char)); |
|
|
|
|
sprintf(colour, "#%02x%02x%02x", c.r, c.g, c.b); |
|
|
|
|
|
|
|
|
@ -230,7 +203,7 @@ void print_colour(rgb_colour c) {
@@ -230,7 +203,7 @@ void print_colour(rgb_colour c) {
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void test(int seed) { |
|
|
|
|
rgb_colour c = get_random_color(seed); |
|
|
|
|
struct colour c = get_random_color(seed); |
|
|
|
|
//print_colour(c);
|
|
|
|
|
struct colour hsl = get_hsl(c); |
|
|
|
|
struct colour hsv = get_hsv(c); |
|
|
|
@ -238,7 +211,7 @@ void test(int seed) {
@@ -238,7 +211,7 @@ 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);*/ |
|
|
|
|
|
|
|
|
|
rgb_colour *adj = get_adjacent(c, 5, 4); |
|
|
|
|
struct colour *adj = get_adjacent(c, 5, 4); |
|
|
|
|
for (int i = 0; i < 5; i++) { |
|
|
|
|
print_colour(adj[i]); |
|
|
|
|
} |
|
|
|
@ -247,7 +220,7 @@ void test(int seed) {
@@ -247,7 +220,7 @@ void test(int seed) {
|
|
|
|
|
printf("\n"); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void wheel() { |
|
|
|
|
void test_print_wheel() { |
|
|
|
|
struct colour c; |
|
|
|
|
c.s = 0.999; |
|
|
|
|
c.v = 0.99; |
|
|
|
@ -255,7 +228,7 @@ void wheel() {
@@ -255,7 +228,7 @@ void wheel() {
|
|
|
|
|
c.sp = CS_HSV; |
|
|
|
|
for(int i = 0; i < 360; i+=5) { |
|
|
|
|
c.h = (double)i; |
|
|
|
|
rgb_colour rgb = get_rgb(c); |
|
|
|
|
struct 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); |
|
|
|
@ -272,13 +245,12 @@ int main() {
@@ -272,13 +245,12 @@ int main() {
|
|
|
|
|
/*test(260);*/ |
|
|
|
|
/*test(240);*/ |
|
|
|
|
|
|
|
|
|
rgb_colour c = get_random_color(128); |
|
|
|
|
rgb_colour *adj = get_adjacent(c, 2, 20); |
|
|
|
|
struct colour c = get_random_color(128); |
|
|
|
|
struct colour *adj = get_adjacent(c, 2, 20); |
|
|
|
|
for (int i = 0; i < 20; i++) { |
|
|
|
|
print_colour(adj[i]); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
free(adj); |
|
|
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|