diff -r 3f69a70063a5 -r 7e7a03e85ac4 rust/integral-geometry/src/lib.rs --- a/rust/integral-geometry/src/lib.rs Thu Oct 18 21:44:09 2018 +0200 +++ b/rust/integral-geometry/src/lib.rs Thu Oct 18 22:23:25 2018 +0200 @@ -161,6 +161,43 @@ } } +pub struct EquidistantPoints { + vector: Point, + iteration: u8, +} + +impl EquidistantPoints { + pub fn new(vector: Point) -> Self { + Self { + vector, + iteration: 0, + } + } +} + +impl Iterator for EquidistantPoints { + type Item = Point; + + fn next(&mut self) -> Option { + if self.iteration < 8 { + self.vector.x = -self.vector.x; + if self.iteration & 1 == 0 { + self.vector.y = -self.vector.y; + } + + if self.iteration == 4 { + std::mem::swap(&mut self.vector.x, &mut self.vector.y); + } + + self.iteration += 1; + + Some(self.vector) + } else { + None + } + } +} + #[cfg(test)] mod tests { use super::*; @@ -170,7 +207,7 @@ } #[test] - fn basic() { + fn line_basic() { let line = LinePoints::new(Point::new(0, 0), Point::new(3, 3)); let v = get_points(&[(0, 0), (1, 1), (2, 2), (3, 3), (123, 456)]); @@ -180,7 +217,7 @@ } #[test] - fn skewed() { + fn line_skewed() { let line = LinePoints::new(Point::new(0, 0), Point::new(5, -7)); let v = get_points(&[ (0, 0), @@ -197,4 +234,24 @@ assert_eq!(a, b); } } + + #[test] + fn equidistant() { + let n = EquidistantPoints::new(Point::new(1, 3)); + let v = get_points(&[ + (-1, -3), + (1, -3), + (-1, 3), + (1, 3), + (-3, -1), + (3, -1), + (-3, 1), + (3, 1), + (123, 456), + ]); + + for (&a, b) in v.iter().zip(n) { + assert_eq!(a, b); + } + } }