use std::iter::repeat;
use crate::SplineCurve;
use super::Result;
pub struct SplineCurves<const K: usize, const N: usize, const NK: usize, const NT:usize, const NC: usize> {
keys: [(&'static str, [usize;2], [usize;2]); NK],
t: [i32; NT], c: [f64; NC], }
impl<const K: usize, const N: usize, const NK: usize, const NC: usize, const NT: usize> SplineCurves<K, N, NK, NT, NC> {
pub const fn new(keys: [(&'static str, [usize;2], [usize;2]); NK], t: [i32; NT], c: [f64; NC]) -> Self {
Self { keys, t, c }
}
pub fn spline_curve(&self, key: &str) -> Result<SplineCurve<K,N>> {
for &(s, [ts,te], [cs, ce]) in &self.keys {
if key == s {
let ti = &self.t[ts..te];
let t: Vec<f64> =
repeat(ti[0] as f64)
.take(K)
.chain(
ti.iter()
.cloned()
.map(|v| v as f64)
).chain(
repeat(ti[ti.len()-1] as f64)
.take(K)
).collect();
return Ok(SplineCurve::new(t, self.c[cs..ce].to_owned()))
}
}
Err("Key not found".into())
}
pub fn evaluate(&self, key: &str, u: &[f64]) -> Result<Vec<f64>> {
let sc = self.spline_curve(key)?;
sc.evaluate(u)
}
}
#[cfg(test)]
mod tests {
use crate::{SplineCurves, Result};
static MUNSELL_MATT: SplineCurves<3,1,11,131,153> = SplineCurves::new(
[("2.5R9/2", [0, 14], [0, 16]), ("2.5R8/2", [14, 28], [16, 32]), ("2.5R7/2", [28, 41], [32, 47]), ("2.5R6/2",
[41, 54], [47, 62]), ("2.5R5/2", [54, 63], [62, 73]), ("2.5R4/2", [63, 72], [73, 84]), ("2.5R3/2", [72, 78],
[84, 92]), ("2.5R2.5/2", [78, 84], [92, 100]), ("2.5R8/4", [84, 102], [100, 120]), ("2.5R7/4", [102, 118], [120,
138]), ("2.5R6/4", [118, 131], [138, 153])],
[380, 387, 394, 407, 420, 433, 485, 499, 512, 538, 564, 590, 695, 800, 380, 407, 420, 433, 485, 499, 512, 538,
551, 564, 590, 695, 748, 800, 380, 394, 407, 420, 433, 485, 499, 512, 538, 564, 590, 695, 800, 380, 394, 407,
433, 485, 512, 538, 564, 590, 695, 748, 774, 800, 380, 394, 407, 433, 485, 538, 564, 590, 800, 380, 394, 407,
433, 485, 538, 590, 695, 800, 380, 485, 538, 590, 695, 800, 380, 485, 590, 643, 695, 800, 380, 394, 407, 420,
433, 459, 485, 499, 512, 538, 564, 571, 577, 590, 643, 695, 748, 800, 380, 394, 407, 420, 433, 485, 499, 512,
538, 564, 590, 643, 695, 748, 774, 800, 380, 394, 407, 433, 485, 499, 512, 538, 564, 590, 643, 695, 800],
[0.13330, 0.13330, 0.17848, 0.30266, 0.64668, 0.70978, 0.68903, 0.70561, 0.66204, 0.68016, 0.61283, 0.77384,
0.76221, 0.75914, 0.75380, 0.75380, 0.14040, 0.14040, 0.52772, 0.54173, 0.49789, 0.52461, 0.48275, 0.49955,
0.43894, 0.52302, 0.58575, 0.57301, 0.56327, 0.55764, 0.54630, 0.54630, 0.13020, 0.13020, 0.27409, 0.40744,
0.38642, 0.36947, 0.37360, 0.34371, 0.35934, 0.30423, 0.44270, 0.42473, 0.42475, 0.40430, 0.40430, 0.12780,
0.12780, 0.24118, 0.28935, 0.24863, 0.25052, 0.23383, 0.20104, 0.31539, 0.30003, 0.29116, 0.28374, 0.28620,
0.27330, 0.27330, 0.10560, 0.10560, 0.17269, 0.19525, 0.15397, 0.17851, 0.11508, 0.20444, 0.20213, 0.19000,
0.19000, 0.09320, 0.09320, 0.10888, 0.11993, 0.10334, 0.10100, 0.08108, 0.16608, 0.12225, 0.13990, 0.13990,
0.06380, 0.06380, 0.06145, 0.05032, 0.09808, 0.08075, 0.09050, 0.09050, 0.04920, 0.04920, 0.03963, 0.03536,
0.08938, 0.12467, 0.14650, 0.14650, 0.13600, 0.13600, 0.28004, 0.52005, 0.50859, 0.48294, 0.47849, 0.47462,
0.42971, 0.46243, 0.35094, 0.55213, 0.60521, 0.64302, 0.68945, 0.66423, 0.66990, 0.65781, 0.66550, 0.66550,
0.12950, 0.12950, 0.27210, 0.39673, 0.37335, 0.33738, 0.35767, 0.30755, 0.32708, 0.24423, 0.46545, 0.51521,
0.49129, 0.48705, 0.47926, 0.47884, 0.47020, 0.47020, 0.13200, 0.13200, 0.24932, 0.28483, 0.22491, 0.25315,
0.20612, 0.22180, 0.16336, 0.30942, 0.40350, 0.36494, 0.36795, 0.34800, 0.34800],
);
#[test]
fn key_not_found_returns_error() {
assert!(MUNSELL_MATT.spline_curve("nonexistent").is_err());
}
#[test]
fn static_munsell_matt() -> Result<()>{
let sc1 = MUNSELL_MATT.spline_curve("2.5R9/2").unwrap();
println!("{:?}", sc1);
#[cfg(feature = "plot")]
sc1.plot("sc1.png", (2000,1000))?;
let sc2 = MUNSELL_MATT.spline_curve("2.5R6/4").unwrap();
println!("{:?}", sc2);
#[cfg(feature = "plot")]
sc2.plot("sc2.png", (2000,1000))?;
Ok(())
}
}