use super::colormap::Colormap;
pub struct Viridis;
impl Colormap for Viridis {
fn map_normalized(&self, value: f32) -> [u8; 4] {
let colors = [
[68, 1, 84], [72, 33, 115],
[64, 67, 135],
[52, 94, 141],
[41, 120, 142],
[32, 144, 140],
[34, 167, 132],
[68, 190, 112],
[121, 209, 81],
[189, 222, 38],
[253, 231, 36], ];
let position = value * (colors.len() - 1) as f32;
let index = position.floor() as usize;
if index >= colors.len() - 1 {
return [
colors[colors.len() - 1][0],
colors[colors.len() - 1][1],
colors[colors.len() - 1][2],
255,
];
}
let t = position - index as f32; let c1 = colors[index];
let c2 = colors[index + 1];
let rgb = super::colormap::lerp_color(c1, c2, t);
[rgb[0], rgb[1], rgb[2], 255]
}
fn name(&self) -> &str {
"viridis"
}
}
pub struct Plasma;
impl Colormap for Plasma {
fn map_normalized(&self, value: f32) -> [u8; 4] {
let colors = [
[13, 8, 135], [75, 3, 161],
[125, 3, 168],
[168, 13, 155],
[203, 30, 129],
[228, 55, 97],
[246, 82, 66],
[251, 118, 35],
[246, 157, 8],
[232, 197, 0],
[240, 249, 33], ];
let position = value * (colors.len() - 1) as f32;
let index = position.floor() as usize;
if index >= colors.len() - 1 {
return [
colors[colors.len() - 1][0],
colors[colors.len() - 1][1],
colors[colors.len() - 1][2],
255,
];
}
let t = position - index as f32; let c1 = colors[index];
let c2 = colors[index + 1];
let rgb = super::colormap::lerp_color(c1, c2, t);
[rgb[0], rgb[1], rgb[2], 255]
}
fn name(&self) -> &str {
"plasma"
}
}
pub struct Inferno;
impl Colormap for Inferno {
fn map_normalized(&self, value: f32) -> [u8; 4] {
let colors = [
[0, 0, 4], [22, 11, 57],
[66, 10, 104],
[106, 23, 110],
[147, 38, 103],
[186, 54, 85],
[221, 73, 64],
[243, 106, 39],
[251, 150, 24],
[246, 196, 40],
[252, 255, 164], ];
let position = value * (colors.len() - 1) as f32;
let index = position.floor() as usize;
if index >= colors.len() - 1 {
return [
colors[colors.len() - 1][0],
colors[colors.len() - 1][1],
colors[colors.len() - 1][2],
255,
];
}
let t = position - index as f32; let c1 = colors[index];
let c2 = colors[index + 1];
let rgb = super::colormap::lerp_color(c1, c2, t);
[rgb[0], rgb[1], rgb[2], 255]
}
fn name(&self) -> &str {
"inferno"
}
}
pub struct Magma;
impl Colormap for Magma {
fn map_normalized(&self, value: f32) -> [u8; 4] {
let colors = [
[0, 0, 4], [28, 16, 68],
[79, 18, 123],
[129, 37, 129],
[181, 54, 122],
[229, 80, 100],
[251, 135, 97],
[254, 194, 135],
[252, 253, 191], ];
let position = value * (colors.len() - 1) as f32;
let index = position.floor() as usize;
if index >= colors.len() - 1 {
return [
colors[colors.len() - 1][0],
colors[colors.len() - 1][1],
colors[colors.len() - 1][2],
255,
];
}
let t = position - index as f32; let c1 = colors[index];
let c2 = colors[index + 1];
let rgb = super::colormap::lerp_color(c1, c2, t);
[rgb[0], rgb[1], rgb[2], 255]
}
fn name(&self) -> &str {
"magma"
}
}
pub struct Cividis;
impl Colormap for Cividis {
fn map_normalized(&self, value: f32) -> [u8; 4] {
let colors = [
[0, 32, 76], [0, 42, 102],
[0, 52, 110],
[25, 63, 115],
[46, 73, 114],
[67, 84, 107],
[90, 96, 98],
[115, 106, 85],
[143, 117, 70],
[172, 129, 54],
[206, 142, 36],
[237, 158, 16],
[255, 172, 0], ];
let position = value * (colors.len() - 1) as f32;
let index = position.floor() as usize;
if index >= colors.len() - 1 {
return [
colors[colors.len() - 1][0],
colors[colors.len() - 1][1],
colors[colors.len() - 1][2],
255,
];
}
let t = position - index as f32; let c1 = colors[index];
let c2 = colors[index + 1];
let rgb = super::colormap::lerp_color(c1, c2, t);
[rgb[0], rgb[1], rgb[2], 255]
}
fn name(&self) -> &str {
"cividis"
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_colormap_names() {
assert_eq!(Viridis.name(), "viridis");
assert_eq!(Plasma.name(), "plasma");
assert_eq!(Inferno.name(), "inferno");
assert_eq!(Magma.name(), "magma");
assert_eq!(Cividis.name(), "cividis");
}
#[test]
fn test_viridis_bounds() {
let colormap = Viridis;
let black = colormap.map_normalized(0.0);
let yellow = colormap.map_normalized(1.0);
assert_eq!(black, [68, 1, 84, 255]);
assert_eq!(yellow, [253, 231, 36, 255]);
let middle = colormap.map_normalized(0.5);
assert!(middle[1] > middle[0]); assert!(middle[1] > middle[2]);
}
}