diff options
author | Juan Manuel Tomás <jtomas1815@gmail.com> | 2021-01-19 09:06:32 -0300 |
---|---|---|
committer | Juan Manuel Tomás <jtomas1815@gmail.com> | 2021-01-19 09:15:02 -0300 |
commit | 4998f5936dc7da36aba0cd018de2a1a6127dda08 (patch) | |
tree | 1363045387c3730d33fbed10f682662e3a635860 /src/poly.rs | |
parent | be18a9a0503fa09318b5d99452a3407a92db4366 (diff) | |
download | bezier-4998f5936dc7da36aba0cd018de2a1a6127dda08.tar.gz bezier-4998f5936dc7da36aba0cd018de2a1a6127dda08.zip |
Make shader sample intervals uniform
Diffstat (limited to 'src/poly.rs')
-rw-r--r-- | src/poly.rs | 123 |
1 files changed, 123 insertions, 0 deletions
diff --git a/src/poly.rs b/src/poly.rs new file mode 100644 index 0000000..35e85d8 --- /dev/null +++ b/src/poly.rs @@ -0,0 +1,123 @@ +mod iter; + +use iter::Iter; +use std::fmt; +use std::ops::{Add, Sub}; + +#[derive(PartialEq, Debug, Clone)] +pub struct Poly { + data: Vec<f32>, + degree: usize, +} + +impl Poly { + pub fn new(data: Vec<f32>) -> Poly { + if data.len() > 1 { + let mut i = data.len() - 1; + while data[i] == 0.0 && i > 0 { + i -= 1; + } + Poly { data, degree: i } + } else { + Poly { data, degree: 0 } + } + } + + pub fn degree(&self) -> usize { + self.degree + } + + fn iter(&self) -> Iter { + Iter::new(self.data.clone(), self.degree()) + } + + pub fn shift(self) -> Poly { + let mut r = vec![0.0]; + r.append(&mut self.data.clone()); + Poly::new(r) + } + + pub fn deriv(&self) -> Poly { + let mut data = vec![0.0; self.degree()]; + if self.degree() > 0 { + for i in 0..self.degree() { + data[i] = self.data[i + 1] * (i + 1) as f32; + } + Poly::new(data) + } else { + Poly::new(vec![0.0]) + } + } +} + +impl Add for &Poly { + type Output = Poly; + + fn add(self, other: Self) -> Poly { + Poly::new(self.iter().zip(other.iter()).map(|(x, y)| x + y).collect()) + } +} + +impl Sub for &Poly { + type Output = Poly; + + fn sub(self, other: Self) -> Poly { + Poly::new(self.iter().zip(other.iter()).map(|(x, y)| x - y).collect()) + } +} + +impl fmt::Display for &Poly { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + let mut s = String::new(); + for i in 0..self.data.len() { + s.push_str(&self.data[i].clone().to_string()); + if i < self.data.len() - 1 { + s.push_str(", "); + } + } + write!(f, "{}", s) + } +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn shift_test() { + let a = Poly::new(vec![1.0, 2.0, 3.0]); + assert_eq!(a.shift(), Poly::new(vec![0.0, 1.0, 2.0, 3.0])); + } + + #[test] + fn add_test() { + let a = Poly::new(vec![1.0]); + let b = Poly::new(vec![0.0, 0.0, 0.0, 1.0]); + assert_eq!(&a + &b, Poly::new(vec![1.0, 0.0, 0.0, 1.0])); + } + + #[test] + fn sub_test() { + let a = Poly::new(vec![1.0, 2.0, 3.0]); + let b = Poly::new(vec![1.0, 1.0, 1.0]); + assert_eq!(&a - &b, Poly::new(vec![0.0, 1.0, 2.0])); + } + + #[test] + fn deriv_test() { + let p = Poly::new(vec![1.0, 2.0, 3.0, 4.0]); + assert_eq!(p.deriv(), Poly::new(vec![2.0, 6.0, 12.0])); + } + + #[test] + fn degree_is_five() { + let p = Poly::new(vec![0.0, 0.0, 0.0, 0.0, 0.0, 2.0]); + assert_eq!(p.degree(), 5); + } + + #[test] + fn degree_is_zero() { + let p = Poly::new(vec![0.0; 6]); + assert_eq!(p.degree(), 0); + } +} |