#[derive(Debug)]
struct PColorValue{
value: f32,
r: u8,
g: u8,
b: u8,
a: u8,
}
impl PColorValue{
pub fn new(value: f32, r: u8, g: u8, b: u8, a: u8) -> Self{
PColorValue {
value: value,
r: r,
g: g,
b: b,
a: a
}
}
pub fn get_color(&self) -> (u8, u8, u8, u8){
return (self.r, self.g, self.b, self.a);
}
}
#[derive(Debug)]
pub struct PColorMap{
vec_value: Vec<PColorValue>,
}
impl PColorMap{
pub fn new() -> Self{
PColorMap {
vec_value: vec![]
}
}
pub fn gray_scott() -> Self{
let mut colormap: PColorMap = PColorMap::new();
colormap.add_color(0.0, 0, 0, 0, 255);
colormap.add_color(0.2, 0, 255, 0, 255);
colormap.add_color(0.21, 255, 255, 0, 255);
colormap.add_color(0.4, 255, 0, 0, 255);
colormap.add_color(0.6, 255, 255, 255, 255);
return colormap;
}
pub fn add_color(&mut self, value: f32, r: u8, g: u8, b: u8, a: u8){
self.vec_value.push(PColorValue::new(value, r, g, b, a));
}
pub fn interpolate(&self, value: f32) -> (u8, u8, u8, u8){
if self.vec_value.len() == 0 { return (0,0,0,0);
}else{
let mincolor = self.vec_value.first().unwrap();
if value <= mincolor.value {
return mincolor.get_color();
}
let maxcolor = self.vec_value.last().unwrap();
if value >= maxcolor.value {
return maxcolor.get_color();
}
for (min, max) in self.vec_value.iter().zip(self.vec_value.iter().skip(1)) {
if value >= min.value && value < max.value {
let interp: PColorValue = self.interpolate_color(value, min, max);
return interp.get_color();
}
}
return (0,0,0,0);
}
}
fn interpolate_color(&self, value: f32, min_color: &PColorValue, max_color: &PColorValue) -> PColorValue{
let ratio: f32 = (value - min_color.value)/(max_color.value - min_color.value);
let color: PColorValue = PColorValue::new(value,
((max_color.r as f32)*ratio + (min_color.r as f32)*(1.0 - ratio)) as u8,
((max_color.g as f32)*ratio + (min_color.g as f32)*(1.0 - ratio)) as u8,
((max_color.b as f32)*ratio + (min_color.b as f32)*(1.0 - ratio)) as u8,
((max_color.a as f32)*ratio + (min_color.a as f32)*(1.0 - ratio)) as u8
);
return color;
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_pcolormap() {
let colormap: PColorMap = PColorMap::gray_scott();
println!("test_pcolormap : colormap = {:?}", colormap);
assert_eq!(colormap.vec_value.get(0).unwrap().get_color(), (0, 0, 0, 255));
assert_eq!(colormap.vec_value.first().unwrap().get_color(), (0, 0, 0, 255));
assert_eq!(colormap.vec_value.get(1).unwrap().get_color(), (0, 255, 0, 255));
assert_eq!(colormap.vec_value.get(2).unwrap().get_color(), (255, 255, 0, 255));
assert_eq!(colormap.vec_value.get(3).unwrap().get_color(), (255, 0, 0, 255));
assert_eq!(colormap.vec_value.get(4).unwrap().get_color(), (255, 255, 255, 255));
assert_eq!(colormap.vec_value.last().unwrap().get_color(), (255, 255, 255, 255));
assert_eq!(colormap.interpolate(-1.0), (0, 0, 0, 255));
assert_eq!(colormap.interpolate(1.0), (255, 255, 255, 255));
assert_eq!(colormap.interpolate(0.5), (255, 127, 127, 255));
}
}