Skip to content

Commit 6ff8a93

Browse files
committed
write macros to implement colorscales for respective color types
- the macros count!, define_colors_from_list_of_values_or_directly!, implement_linear_interpolation_color_map! are just helper macros for define_linear_interpolation_color_map! - the macro define_linear_interpolation_color_map! takes the name of the new colormap, the type of color to be used and then either a list of actual values (eg ((u8, u8, u8), ..., (u8, u8, u8)) for RGB) or already defined colors (for example by name in the full_palette super-module) - the macro then generates a new struct with the given name and implements the previously defined trait onto this struct - in addition we also write associated functions get_color, get_color_normalized such that they can be used without needing to instantiate the struct
1 parent f781b8c commit 6ff8a93

File tree

1 file changed

+81
-0
lines changed

1 file changed

+81
-0
lines changed

plotters/src/style/colors/colormaps.rs

Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1+
use crate::style::{HSLColor,RGBAColor,RGBColor};
2+
3+
use num_traits::{Float,ToPrimitive,FromPrimitive};
4+
15
pub trait ColorScale<ColorType: crate::prelude::Color, FloatType=f32>
26
where
37
FloatType: Float,
@@ -8,3 +12,80 @@ where
812

913
fn get_color_normalized(&self, h: FloatType, min: FloatType, max: FloatType) -> ColorType;
1014
}
15+
16+
17+
macro_rules! count {
18+
() => (0usize);
19+
($x:tt $($xs:tt)* ) => (1usize + count!($($xs)*));
20+
}
21+
22+
23+
macro_rules! define_colors_from_list_of_values_or_directly{
24+
($color_type:tt, $(($($color_value:expr),+)),+) => {
25+
[$($color_type($($color_value),+)),+]
26+
};
27+
($($color_complete:tt),+) => {
28+
[$($color_complete),+]
29+
};
30+
}
31+
32+
33+
macro_rules! implement_linear_interpolation_color_map{
34+
($color_scale_name:ident, $color_type:tt) => {
35+
impl<FloatType: std::fmt::Debug + Float + FromPrimitive + ToPrimitive> ColorScale<$color_type, FloatType> for $color_scale_name {
36+
fn get_color_normalized(&self, h: FloatType, min: FloatType, max: FloatType) -> $color_type {
37+
// Ensure that we do have a value in bounds
38+
let h = h.max(min).min(max);
39+
// Make sure that we really have a minimal value which is smaller than the maximal value
40+
assert_eq!(min<max, true);
41+
// Next calculate a normalized value between 0.0 and 1.0
42+
let t = (h - min)/(max-min);
43+
let approximate_index = t * (FloatType::from_usize(Self::COLORS.len()).unwrap() - FloatType::one()).max(FloatType::zero());
44+
// Calculate which index are the two most nearest of the supplied value
45+
let index_lower = approximate_index.floor().to_usize().unwrap();
46+
let index_upper = approximate_index.ceil().to_usize().unwrap();
47+
// Calculate the relative difference, ie. is the actual value more towards the color of index_upper or index_lower?
48+
let relative_difference = approximate_index.ceil() - approximate_index;
49+
// Interpolate the final color linearly
50+
calculate_new_color_value!(relative_difference, Self::COLORS, index_upper, index_lower, $color_type)
51+
}
52+
}
53+
54+
impl $color_scale_name {
55+
pub fn get_color<FloatType: std::fmt::Debug + Float + FromPrimitive + ToPrimitive>(h: FloatType) -> $color_type {
56+
let color_scale = $color_scale_name {};
57+
color_scale.get_color(h)
58+
}
59+
60+
pub fn get_color_normalized<FloatType: std::fmt::Debug + Float + FromPrimitive + ToPrimitive>(h: FloatType, min: FloatType, max: FloatType) -> $color_type {
61+
let color_scale = $color_scale_name {};
62+
color_scale.get_color_normalized(h, min, max)
63+
}
64+
}
65+
}
66+
}
67+
68+
69+
#[macro_export]
70+
macro_rules! define_linear_interpolation_color_map{
71+
($color_scale_name:ident, $color_type:tt, $(($($color_value:expr),+)),*) => {
72+
pub struct $color_scale_name {}
73+
74+
impl $color_scale_name {
75+
// const COLORS: [$color_type; $number_colors] = [$($color_type($($color_value),+)),+];
76+
// const COLORS: [$color_type; count!($(($($color_value:expr),+))*)] = [$($color_type($($color_value),+)),+];
77+
const COLORS: [$color_type; count!($(($($color_value:expr),+))*)] = define_colors_from_list_of_values_or_directly!{$color_type, $(($($color_value),+)),*};
78+
}
79+
80+
implement_linear_interpolation_color_map!{$color_scale_name, $color_type}
81+
};
82+
($color_scale_name:ident, $color_type:tt, $($color_complete:tt),+) => {
83+
pub struct $color_scale_name {}
84+
85+
impl $color_scale_name {
86+
const COLORS: [$color_type; count!($($color_complete)*)] = define_colors_from_list_of_values_or_directly!{$($color_complete),+};
87+
}
88+
89+
implement_linear_interpolation_color_map!{$color_scale_name, $color_type}
90+
}
91+
}

0 commit comments

Comments
 (0)