From 6262cd9aab04bce1c98fd5f6ab19cd5da814dfc7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juan=20Manuel=20Tom=C3=A1s?= Date: Mon, 11 Jan 2021 08:42:04 -0300 Subject: Implement add and sub for P --- src/lerp.rs | 3 ++- src/main.rs | 33 +++++++++++++++++------------ src/number.rs | 1 + src/poly.rs | 63 +++++++++++++++++++++++++++++++++++++++++++++++++++++++- src/poly/iter.rs | 25 ++++++++++++++++++++++ 5 files changed, 110 insertions(+), 15 deletions(-) create mode 100644 src/number.rs create mode 100644 src/poly/iter.rs (limited to 'src') diff --git a/src/lerp.rs b/src/lerp.rs index 7c4994c..8a33e8f 100644 --- a/src/lerp.rs +++ b/src/lerp.rs @@ -1,4 +1,5 @@ -use crate::poly::{self, Number, Poly}; +use crate::number::Number; +use crate::poly::{self, Poly}; pub enum Lerp { Node(Box, Box), diff --git a/src/main.rs b/src/main.rs index 8c23d3e..e5e4112 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,8 +1,9 @@ mod poly; +mod number; mod lerp; -use crate::poly::Number; -use crate::lerp::Lerp; +use number::Number; +use lerp::Lerp; use std::thread; use std::time::Duration; @@ -13,10 +14,12 @@ use sdl2::keyboard::Keycode; use sdl2::rect::Rect; fn main() { - let a = Lerp::new(vec![100.0, 200.0, 300.0, 500.0]); - let b = Lerp::new(vec![400.0, 140.0, 500.0, 300.0]); - let pa = lerp::lp(a); - let pb = lerp::lp(b); + //let a = Lerp::new(vec![2.0, -2.0, 2.0]); + //let b = Lerp::new(vec![-1.0, 1.0, 2.0]); + //let pa = lerp::lp(a); + //let pb = lerp::lp(b); + let pa = vec![1.0, 5.0, -2.0]; + let pb = vec![5.0, -4.0, 0.0]; let p = poly::gcd(&pa, &pb); let sdl_context = sdl2::init().unwrap(); @@ -43,16 +46,20 @@ fn main() { } } - for t in 0..800 { - let x = poly::eval_poly(&pa, t as Number / 800.0); - let y = poly::eval_poly(&pb, t as Number / 800.0); - let z = poly::eval_poly(&p, t as Number / 800.0); + let s = -600.0 / 10.0; + let k = 600.0 / 2.0; + for t in -800..800 { + let x = k + s * poly::eval_poly(&pa, t as Number / 100.0); + let y = k + s * poly::eval_poly(&pb, t as Number / 100.0); + let z = k + s * poly::eval_poly(&p, t as Number / 100.0); canvas.set_draw_color(Color::RGB(180, 20, 20)); - canvas.fill_rect(Rect::new(t, x as i32, 5, 5)).unwrap(); + canvas.fill_rect(Rect::new(400 + t, x as i32, 5, 5)).unwrap(); canvas.set_draw_color(Color::RGB(20, 180, 20)); - canvas.fill_rect(Rect::new(t, y as i32, 5, 5)).unwrap(); + canvas.fill_rect(Rect::new(400 + t, y as i32, 5, 5)).unwrap(); canvas.set_draw_color(Color::RGB(20, 20, 180)); - canvas.fill_rect(Rect::new(t, z as i32, 5, 5)).unwrap(); + canvas.fill_rect(Rect::new(400 + t, z as i32, 2, 2)).unwrap(); + canvas.set_draw_color(Color::RGB(255, 0, 0)); + canvas.fill_rect(Rect::new(400 + t, k as i32, 2, 2)).unwrap(); } canvas.present(); diff --git a/src/number.rs b/src/number.rs new file mode 100644 index 0000000..cd5d47f --- /dev/null +++ b/src/number.rs @@ -0,0 +1 @@ +pub type Number = f32; diff --git a/src/poly.rs b/src/poly.rs index 2128d38..34444b3 100644 --- a/src/poly.rs +++ b/src/poly.rs @@ -1,6 +1,53 @@ +mod iter; + +use crate::number::Number; +use iter::Iter; +use std::cmp; use std::cmp::Ordering; +use std::ops::{Add, Sub}; +use std::iter::{Zip, Take}; + +#[derive(PartialEq, Debug)] +pub struct P(Vec); + +impl P { + fn degree(&self) -> usize { + let mut i = self.0.len() - 1; + while self.0[i] == 0.0 && i > 0 { + i -= 1; + } + i + } + + fn iter(&self) -> Iter { + Iter::new(self.0.clone()) + } + + fn zip(&self, other: &Self) -> Zip, Take> { + let deg = cmp::max(self.degree(), other.degree()) + 1; + let a = self.iter().take(deg); + let b = other.iter().take(deg); + a.zip(b) + } +} + +impl Add for &P { + type Output = P; + + fn add(self, other: Self) -> P { + P(self.zip(other).map(|(x, y)| {x + y}).collect()) + } +} + +impl Sub for &P { + type Output = P; + + fn sub(self, other: Self) -> P { + P(self.zip(other).map(|(x, y)| {x - y}).collect()) + } +} -pub type Number = f32; +//****************************REFACTORING************************************ pub type Poly = Vec; @@ -87,6 +134,20 @@ pub fn gcd(a: &Poly, b: &Poly) -> Poly { mod tests { use super::*; + #[test] + fn add_test() { + let a = P(vec![1.0]); + let b = P(vec![0.0, 0.0, 0.0, 1.0]); + assert_eq!(&a + &b, P(vec![1.0, 0.0, 0.0, 1.0])); + } + + #[test] + fn sub_test() { + let a = P(vec![1.0, 2.0, 3.0]); + let b = P(vec![1.0]); + assert_eq!(&a - &b, P(vec![0.0, 2.0, 3.0])); + } + #[test] fn poly_is_zero() { let p = vec![0.0; 5]; diff --git a/src/poly/iter.rs b/src/poly/iter.rs new file mode 100644 index 0000000..26c5989 --- /dev/null +++ b/src/poly/iter.rs @@ -0,0 +1,25 @@ +use crate::number::Number; + +pub struct Iter { + index: usize, + data: Vec +} + +impl Iter { + pub fn new(data: Vec) -> Iter { + Iter { index: 0, data } + } +} + +impl Iterator for Iter { + type Item = Number; + + fn next(&mut self) -> Option { + self.index += 1; + if self.index <= self.data.len() { + Some(self.data[self.index - 1]) + } else { + Some(0.0) + } + } +} -- cgit v1.2.3