diff --git a/heat.c b/heat.c index 4408d69..9cf37a6 100644 --- a/heat.c +++ b/heat.c @@ -132,6 +132,8 @@ /* Color schemes, see list in global_pdes.c */ +#define COLOR_PALETTE 0 /* Color palette, see list in global_pdes.c */ + #define BLACK 1 /* black background */ #define COLOR_SCHEME 1 /* choice of color scheme */ @@ -151,6 +153,8 @@ // #define HUEAMP -130.0 /* amplitude of variation of hue for color scheme C_HUE */ +#include "hsluv.c" + #include "global_pdes.c" #include "sub_wave.c" diff --git a/hsluv.c b/hsluv.c new file mode 100644 index 0000000..f17dd36 --- /dev/null +++ b/hsluv.c @@ -0,0 +1,453 @@ +/* + * HSLuv-C: Human-friendly HSL + * + * + * + * Copyright (c) 2015 Alexei Boronine (original idea, JavaScript implementation) + * Copyright (c) 2015 Roger Tallada (Obj-C implementation) + * Copyright (c) 2017 Martin Mitas (C implementation, based on Obj-C implementation) + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#include "hsluv.h" + +#include +#include + + +typedef struct Triplet_tag Triplet; +struct Triplet_tag { + double a; + double b; + double c; +}; + +/* for RGB */ +static const Triplet m[3] = { + { 3.24096994190452134377, -1.53738317757009345794, -0.49861076029300328366 }, + { -0.96924363628087982613, 1.87596750150772066772, 0.04155505740717561247 }, + { 0.05563007969699360846, -0.20397695888897656435, 1.05697151424287856072 } +}; + +/* for XYZ */ +static const Triplet m_inv[3] = { + { 0.41239079926595948129, 0.35758433938387796373, 0.18048078840183428751 }, + { 0.21263900587151035754, 0.71516867876775592746, 0.07219231536073371500 }, + { 0.01933081871559185069, 0.11919477979462598791, 0.95053215224966058086 } +}; + +static const double ref_u = 0.19783000664283680764; +static const double ref_v = 0.46831999493879100370; + +static const double kappa = 903.29629629629629629630; +static const double epsilon = 0.00885645167903563082; + + +typedef struct Bounds_tag Bounds; +struct Bounds_tag { + double a; + double b; +}; + + +static void +get_bounds(double l, Bounds bounds[6]) +{ + double tl = l + 16.0; + double sub1 = (tl * tl * tl) / 1560896.0; + double sub2 = (sub1 > epsilon ? sub1 : (l / kappa)); + int channel; + int t; + + for(channel = 0; channel < 3; channel++) { + double m1 = m[channel].a; + double m2 = m[channel].b; + double m3 = m[channel].c; + + for (t = 0; t < 2; t++) { + double top1 = (284517.0 * m1 - 94839.0 * m3) * sub2; + double top2 = (838422.0 * m3 + 769860.0 * m2 + 731718.0 * m1) * l * sub2 - 769860.0 * t * l; + double bottom = (632260.0 * m3 - 126452.0 * m2) * sub2 + 126452.0 * t; + + bounds[channel * 2 + t].a = top1 / bottom; + bounds[channel * 2 + t].b = top2 / bottom; + } + } +} + +static double +intersect_line_line(const Bounds* line1, const Bounds* line2) +{ + return (line1->b - line2->b) / (line2->a - line1->a); +} + +static double +dist_from_pole_squared(double x, double y) +{ + return x * x + y * y; +} + +static double +ray_length_until_intersect(double theta, const Bounds* line) +{ + return line->b / (sin(theta) - line->a * cos(theta)); +} + +static double +max_safe_chroma_for_l(double l) +{ + double min_len_squared = DBL_MAX; + Bounds bounds[6]; + int i; + + get_bounds(l, bounds); + for(i = 0; i < 6; i++) { + double m1 = bounds[i].a; + double b1 = bounds[i].b; + /* x where line intersects with perpendicular running though (0, 0) */ + Bounds line2 = { -1.0 / m1, 0.0 }; + double x = intersect_line_line(&bounds[i], &line2); + double distance = dist_from_pole_squared(x, b1 + x * m1); + + if(distance < min_len_squared) + min_len_squared = distance; + } + + return sqrt(min_len_squared); +} + +static double +max_chroma_for_lh(double l, double h) +{ + double min_len = DBL_MAX; + double hrad = h * 0.01745329251994329577; /* (2 * pi / 360) */ + Bounds bounds[6]; + int i; + + get_bounds(l, bounds); + for(i = 0; i < 6; i++) { + double len = ray_length_until_intersect(hrad, &bounds[i]); + + if(len >= 0 && len < min_len) + min_len = len; + } + return min_len; +} + +static double +dot_product(const Triplet* t1, const Triplet* t2) +{ + return (t1->a * t2->a + t1->b * t2->b + t1->c * t2->c); +} + +/* Used for rgb conversions */ +static double +from_linear(double c) +{ + if(c <= 0.0031308) + return 12.92 * c; + else + return 1.055 * pow(c, 1.0 / 2.4) - 0.055; +} + +static double +to_linear(double c) +{ + if (c > 0.04045) + return pow((c + 0.055) / 1.055, 2.4); + else + return c / 12.92; +} + +static void +xyz2rgb(Triplet* in_out) +{ + double r = from_linear(dot_product(&m[0], in_out)); + double g = from_linear(dot_product(&m[1], in_out)); + double b = from_linear(dot_product(&m[2], in_out)); + in_out->a = r; + in_out->b = g; + in_out->c = b; +} + +static void +rgb2xyz(Triplet* in_out) +{ + Triplet rgbl = { to_linear(in_out->a), to_linear(in_out->b), to_linear(in_out->c) }; + double x = dot_product(&m_inv[0], &rgbl); + double y = dot_product(&m_inv[1], &rgbl); + double z = dot_product(&m_inv[2], &rgbl); + in_out->a = x; + in_out->b = y; + in_out->c = z; +} + +/* https://en.wikipedia.org/wiki/CIELUV + * In these formulas, Yn refers to the reference white point. We are using + * illuminant D65, so Yn (see refY in Maxima file) equals 1. The formula is + * simplified accordingly. + */ +static double +y2l(double y) +{ + if(y <= epsilon) + return y * kappa; + else + return 116.0 * cbrt(y) - 16.0; +} + +static double +l2y(double l) +{ + if(l <= 8.0) { + return l / kappa; + } else { + double x = (l + 16.0) / 116.0; + return (x * x * x); + } +} + +static void +xyz2luv(Triplet* in_out) +{ + double var_u = (4.0 * in_out->a) / (in_out->a + (15.0 * in_out->b) + (3.0 * in_out->c)); + double var_v = (9.0 * in_out->b) / (in_out->a + (15.0 * in_out->b) + (3.0 * in_out->c)); + double l = y2l(in_out->b); + double u = 13.0 * l * (var_u - ref_u); + double v = 13.0 * l * (var_v - ref_v); + + in_out->a = l; + if(l < 0.00000001) { + in_out->b = 0.0; + in_out->c = 0.0; + } else { + in_out->b = u; + in_out->c = v; + } +} + +static void +luv2xyz(Triplet* in_out) +{ + if(in_out->a <= 0.00000001) { + /* Black will create a divide-by-zero error. */ + in_out->a = 0.0; + in_out->b = 0.0; + in_out->c = 0.0; + return; + } + + double var_u = in_out->b / (13.0 * in_out->a) + ref_u; + double var_v = in_out->c / (13.0 * in_out->a) + ref_v; + double y = l2y(in_out->a); + double x = -(9.0 * y * var_u) / ((var_u - 4.0) * var_v - var_u * var_v); + double z = (9.0 * y - (15.0 * var_v * y) - (var_v * x)) / (3.0 * var_v); + in_out->a = x; + in_out->b = y; + in_out->c = z; +} + +static void +luv2lch(Triplet* in_out) +{ + double l = in_out->a; + double u = in_out->b; + double v = in_out->c; + double h; + double c = sqrt(u * u + v * v); + + /* Grays: disambiguate hue */ + if(c < 0.00000001) { + h = 0; + } else { + h = atan2(v, u) * 57.29577951308232087680; /* (180 / pi) */ + if(h < 0.0) + h += 360.0; + } + + in_out->a = l; + in_out->b = c; + in_out->c = h; +} + +static void +lch2luv(Triplet* in_out) +{ + double hrad = in_out->c * 0.01745329251994329577; /* (pi / 180.0) */ + double u = cos(hrad) * in_out->b; + double v = sin(hrad) * in_out->b; + + in_out->b = u; + in_out->c = v; +} + +static void +hsluv2lch(Triplet* in_out) +{ + double h = in_out->a; + double s = in_out->b; + double l = in_out->c; + double c; + + /* White and black: disambiguate chroma */ + if(l > 99.9999999 || l < 0.00000001) + c = 0.0; + else + c = max_chroma_for_lh(l, h) / 100.0 * s; + + /* Grays: disambiguate hue */ + if (s < 0.00000001) + h = 0.0; + + in_out->a = l; + in_out->b = c; + in_out->c = h; +} + +static void +lch2hsluv(Triplet* in_out) +{ + double l = in_out->a; + double c = in_out->b; + double h = in_out->c; + double s; + + /* White and black: disambiguate saturation */ + if(l > 99.9999999 || l < 0.00000001) + s = 0.0; + else + s = c / max_chroma_for_lh(l, h) * 100.0; + + /* Grays: disambiguate hue */ + if (c < 0.00000001) + h = 0.0; + + in_out->a = h; + in_out->b = s; + in_out->c = l; +} + +static void +hpluv2lch(Triplet* in_out) +{ + double h = in_out->a; + double s = in_out->b; + double l = in_out->c; + double c; + + /* White and black: disambiguate chroma */ + if(l > 99.9999999 || l < 0.00000001) + c = 0.0; + else + c = max_safe_chroma_for_l(l) / 100.0 * s; + + /* Grays: disambiguate hue */ + if (s < 0.00000001) + h = 0.0; + + in_out->a = l; + in_out->b = c; + in_out->c = h; +} + +static void +lch2hpluv(Triplet* in_out) +{ + double l = in_out->a; + double c = in_out->b; + double h = in_out->c; + double s; + + /* White and black: disambiguate saturation */ + if (l > 99.9999999 || l < 0.00000001) + s = 0.0; + else + s = c / max_safe_chroma_for_l(l) * 100.0; + + /* Grays: disambiguate hue */ + if (c < 0.00000001) + h = 0.0; + + in_out->a = h; + in_out->b = s; + in_out->c = l; +} + + + +void +hsluv2rgb(double h, double s, double l, double* pr, double* pg, double* pb) +{ + Triplet tmp = { h, s, l }; + + hsluv2lch(&tmp); + lch2luv(&tmp); + luv2xyz(&tmp); + xyz2rgb(&tmp); + + *pr = tmp.a; + *pg = tmp.b; + *pb = tmp.c; +} + +void +hpluv2rgb(double h, double s, double l, double* pr, double* pg, double* pb) +{ + Triplet tmp = { h, s, l }; + + hpluv2lch(&tmp); + lch2luv(&tmp); + luv2xyz(&tmp); + xyz2rgb(&tmp); + + *pr = tmp.a; + *pg = tmp.b; + *pb = tmp.c; +} + +void +rgb2hsluv(double r, double g, double b, double* ph, double* ps, double* pl) +{ + Triplet tmp = { r, g, b }; + + rgb2xyz(&tmp); + xyz2luv(&tmp); + luv2lch(&tmp); + lch2hsluv(&tmp); + + *ph = tmp.a; + *ps = tmp.b; + *pl = tmp.c; +} + +void +rgb2hpluv(double r, double g, double b, double* ph, double* ps, double* pl) +{ + Triplet tmp = { r, g, b }; + + rgb2xyz(&tmp); + xyz2luv(&tmp); + luv2lch(&tmp); + lch2hpluv(&tmp); + + *ph = tmp.a; + *ps = tmp.b; + *pl = tmp.c; +} diff --git a/hsluv.h b/hsluv.h new file mode 100644 index 0000000..2d43d9f --- /dev/null +++ b/hsluv.h @@ -0,0 +1,93 @@ +/* + * HSLuv-C: Human-friendly HSL + * + * + * + * Copyright (c) 2015 Alexei Boronine (original idea, JavaScript implementation) + * Copyright (c) 2015 Roger Tallada (Obj-C implementation) + * Copyright (c) 2017 Martin Mitas (C implementation, based on Obj-C implementation) + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#ifndef HSLUV_H +#define HSLUV_H + +#ifdef __cplusplus +extern "C" { +#endif + + +/** + * Convert HSLuv to RGB. + * + * @param h Hue. Between 0.0 and 360.0. + * @param s Saturation. Between 0.0 and 100.0. + * @param l Lightness. Between 0.0 and 100.0. + * @param[out] pr Red component. Between 0.0 and 1.0. + * @param[out] pg Green component. Between 0.0 and 1.0. + * @param[out] pb Blue component. Between 0.0 and 1.0. + */ +void hsluv2rgb(double h, double s, double l, double* pr, double* pg, double* pb); + +/** + * Convert RGB to HSLuv. + * + * @param r Red component. Between 0.0 and 1.0. + * @param g Green component. Between 0.0 and 1.0. + * @param b Blue component. Between 0.0 and 1.0. + * @param[out] ph Hue. Between 0.0 and 360.0. + * @param[out] ps Saturation. Between 0.0 and 100.0. + * @param[out] pl Lightness. Between 0.0 and 100.0. + */ +void rgb2hsluv(double r, double g, double b, double* ph, double* ps, double* pl); + +/** + * Convert HPLuv to RGB. + * + * @param h Hue. Between 0.0 and 360.0. + * @param s Saturation. Between 0.0 and 100.0. + * @param l Lightness. Between 0.0 and 100.0. + * @param[out] pr Red component. Between 0.0 and 1.0. + * @param[out] pg Green component. Between 0.0 and 1.0. + * @param[out] pb Blue component. Between 0.0 and 1.0. + */ +void hpluv2rgb(double h, double s, double l, double* pr, double* pg, double* pb); + +/** + * Convert RGB to HPLuv. + * + * @param r Red component. Between 0.0 and 1.0. + * @param g Green component. Between 0.0 and 1.0. + * @param b Blue component. Between 0.0 and 1.0. + * @param[out] ph Hue. Between 0.0 and 360.0. + * @param[out] ps Saturation. Between 0.0 and 100.0. + * @param[out] pl Lightness. Between 0.0 and 100.0. + * + * Note that HPLuv does not contain all the colors of RGB, so converting + * arbitrary RGB to it may generate invalid HPLuv colors. + */ +void rgb2hpluv(double r, double g, double b, double* ph, double* ps, double* pl); + + +#ifdef __cplusplus +} +#endif + +#endif /* HSLUV_H */ diff --git a/mangrove.c b/mangrove.c index e5dd33d..f3bc8d1 100644 --- a/mangrove.c +++ b/mangrove.c @@ -144,6 +144,8 @@ /* Color schemes */ +#define COLOR_PALETTE 0 /* Color palette, see list in global_pdes.c */ + #define BLACK 1 /* background */ #define COLOR_SCHEME 1 /* choice of color scheme, see list in global_pdes.c */ @@ -185,6 +187,8 @@ #define VMAX 10.0 /* max value of wave amplitude */ +#include "hsluv.c" + #include "global_pdes.c" #include "sub_wave.c" #include "wave_common.c" diff --git a/schrodinger.c b/schrodinger.c index fbf49b1..6cb47b5 100644 --- a/schrodinger.c +++ b/schrodinger.c @@ -116,6 +116,8 @@ /* Color schemes, see list in global_pdes.c */ +#define COLOR_PALETTE 0 /* Color palette, see list in global_pdes.c */ + #define BLACK 1 /* black background */ #define COLOR_SCHEME 1 /* choice of color scheme */ @@ -131,6 +133,8 @@ #define HUEMEAN 150.0 /* mean value of hue for color scheme C_HUE */ #define HUEAMP -150.0 /* amplitude of variation of hue for color scheme C_HUE */ +#include "hsluv.c" + #include "global_pdes.c" #include "sub_wave.c" diff --git a/sub_wave.c b/sub_wave.c index ad60d4d..622dd8a 100644 --- a/sub_wave.c +++ b/sub_wave.c @@ -67,7 +67,7 @@ void init() /* initialisation of window */ -void hsl_to_rgb(double h, double s, double l, double rgb[3]) /* color conversion from HSL to RGB */ +void hsl_to_rgb_jet(double h, double s, double l, double rgb[3]) /* color conversion from HSL to RGB */ /* h = hue, s = saturation, l = luminosity */ { double c = 0.0, m = 0.0, x = 0.0; @@ -106,7 +106,34 @@ void hsl_to_rgb(double h, double s, double l, double rgb[3]) /* color conv } } - +void hsl_to_rgb(double h, double s, double l, double rgb[3]) /* color conversion from HSL to RGB */ +{ + double r, g, b; + + switch (COLOR_PALETTE) { + case (COL_JET): + { + hsl_to_rgb_jet(h, s, l, rgb); + break; + } + case (COL_HSLUV): + { + hsluv2rgb(h, 100.0*s, l, &r, &g, &b); + rgb[0] = r*100.0; + rgb[1] = g*100.0; + rgb[2] = b*100.0; + break; + } + } +// if (HSLUV_COLORS) +// { +// hsluv2rgb(h, 100.0*s, l, &r, &g, &b); +// rgb[0] = r*100.0; +// rgb[1] = g*100.0; +// rgb[2] = b*100.0; +// } +// else hsl_to_rgb_jet(h, s, l, rgb); +} double color_amplitude(double value, double scale, int time) /* transforms the wave amplitude into a double in [-1,1] to feed into color scheme */ @@ -967,6 +994,60 @@ int xy_in_billiard(double x, double y) else if (y < 0.98*b) return (1); else return(0); } + case (D_TOKARSKY): + { + x1 = 4.0 + x/(XMAX - XMIN)*8.4; + y1 = 2.0 + y/(XMAX - XMIN)*8.4; + if ((x1 <= 0.0)||(x1 >= 8.0)) return(0); + else if (x1 < 1.0) + { + if (y1 <= 2.0) return(0); + else if (y1 >= x1 + 2.0) return(0); + else return(1); + } + else if (x1 < 2.0) + { + if (y1 <= 1.0) return(0); + else if (y1 >= 4.0) return(0); + else return(1); + } + else if (x1 < 3.0) + { + if (y1 <= x1 - 2.0) return(0); + else if (y1 >= 3.0) return(0); + else return(1); + } + else if (x1 < 4.0) + { + if (y1 <= 1.0) return(0); + else if (y1 >= 2.0) return(0); + else return(1); + } + else if (x1 < 5.0) + { + if (y1 <= x1 - 4.0) return(0); + else if (y1 >= 2.0) return(0); + else return(1); + } + else if (x1 < 6.0) + { + if (y1 <= 1.0) return(0); + else if (y1 >= 3.0) return(0); + else return(1); + } + else if (x1 < 7.0) + { + if (y1 <= x1 - 6.0) return(0); + else if (y1 >= 10.0 - x1) return(0); + else return(1); + } + else + { + if (y1 <= 2.0) return(0); + else if (y1 >= 3.0) return(0); + else return(1); + } + } case (D_CIRCLES): { for (i = 0; i < ncircles; i++) @@ -1132,8 +1213,17 @@ int ij_in_billiard(int i, int j) return(xy_in_billiard(xy[0], xy[1])); } - - +void toka_lineto(double x1, double y1) +/* draws boundary segments of Tokarsky billiard */ +{ + double ratio, x, y, pos[2]; + + ratio = (XMAX - XMIN)/8.4; + x = ratio*(x1 - 4.0); + y = ratio*(y1 - 2.0); + xy_to_pos(x, y, pos); + glVertex2d(pos[0], pos[1]); +} void draw_billiard() /* draws the billiard boundary */ { @@ -1666,6 +1756,45 @@ void draw_billiard() /* draws the billiard boundary */ } break; } + case (D_TOKARSKY): + { + glBegin(GL_LINE_LOOP); + toka_lineto(0.0, 2.0); + toka_lineto(1.0, 3.0); + toka_lineto(1.0, 4.0); + toka_lineto(2.0, 4.0); + toka_lineto(2.0, 3.0); + toka_lineto(3.0, 3.0); + toka_lineto(3.0, 2.0); + toka_lineto(5.0, 2.0); + toka_lineto(5.0, 3.0); + toka_lineto(6.0, 3.0); + toka_lineto(6.0, 4.0); + toka_lineto(7.0, 3.0); + toka_lineto(8.0, 3.0); + toka_lineto(8.0, 2.0); + toka_lineto(7.0, 2.0); + toka_lineto(7.0, 1.0); + toka_lineto(6.0, 0.0); + toka_lineto(6.0, 1.0); + toka_lineto(5.0, 1.0); + toka_lineto(4.0, 0.0); + toka_lineto(4.0, 1.0); + toka_lineto(3.0, 1.0); + toka_lineto(2.0, 0.0); + toka_lineto(2.0, 1.0); + toka_lineto(1.0, 1.0); + toka_lineto(1.0, 2.0); + glEnd(); + if (FOCI) + { + x = (XMAX - XMIN)/4.2; + glColor3f(0.3, 0.3, 0.3); + draw_circle(x, 0.0, r, NSEG); + draw_circle(-x, 0.0, r, NSEG); + } + break; + } case (D_CIRCLES): { glLineWidth(BOUNDARY_WIDTH); diff --git a/wave_billiard.c b/wave_billiard.c index c08e6d2..dd9ed39 100644 --- a/wave_billiard.c +++ b/wave_billiard.c @@ -145,6 +145,8 @@ /* Color schemes */ +#define COLOR_PALETTE 0 /* Color palette, see list in global_pdes.c */ + #define BLACK 1 /* background */ #define COLOR_SCHEME 1 /* choice of color scheme, see list in global_pdes.c */ @@ -167,6 +169,7 @@ #define FLOOR 0 /* set to 1 to limit wave amplitude to VMAX */ #define VMAX 10.0 /* max value of wave amplitude */ +#include "hsluv.c" #include "global_pdes.c" /* constants and global variables */ #include "sub_wave.c" /* common functions for wave_billiard, heat and schrodinger */ diff --git a/wave_comparison.c b/wave_comparison.c index 6e3c623..5df0673 100644 --- a/wave_comparison.c +++ b/wave_comparison.c @@ -143,6 +143,8 @@ /* Color schemes */ +#define COLOR_PALETTE 0 /* Color palette, see list in global_pdes.c */ + #define BLACK 1 /* background */ #define COLOR_SCHEME 1 /* choice of color scheme, see list in global_pdes.c */ @@ -164,6 +166,8 @@ #define VMAX 5.0 /* max value of wave amplitude */ +#include "hsluv.c" + #include "global_pdes.c" /* constants and global variables */ #include "sub_wave.c" /* common functions for wave_billiard, heat and schrodinger */ #include "wave_common.c" /* common functions for wave_billiard, wave_comparison, etc */ diff --git a/wave_energy.c b/wave_energy.c index 0c2279c..572d0f6 100644 --- a/wave_energy.c +++ b/wave_energy.c @@ -147,6 +147,8 @@ /* Color schemes */ +#define COLOR_PALETTE 0 /* Color palette, see list in global_pdes.c */ + #define BLACK 1 /* background */ #define COLOR_SCHEME 1 /* choice of color scheme, see list in global_pdes.c */ @@ -168,6 +170,8 @@ #define VMAX 5.0 /* max value of wave amplitude */ +#include "hsluv.c" + #include "global_pdes.c" /* constants and global variables */ #include "sub_wave.c" /* common functions for wave_billiard, heat and schrodinger */ #include "wave_common.c" /* common functions for wave_billiard, wave_comparison, etc */