Introduce integral-geometry crate, implement LinePoints iterator
authorunc0rr
Wed, 17 Oct 2018 22:45:33 +0200
changeset 13935 75eaf7c71789
parent 13934 9c112f2ae02d
child 13936 78c798d655ad
Introduce integral-geometry crate, implement LinePoints iterator
rust/integral-geometry/Cargo.toml
rust/integral-geometry/src/lib.rs
rust/lfprng/src/lib.rs
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/rust/integral-geometry/Cargo.toml	Wed Oct 17 22:45:33 2018 +0200
@@ -0,0 +1,6 @@
+[package]
+name = "integral-geometry"
+version = "0.1.0"
+authors = ["Andrey Korotaev <a.korotaev@hedgewars.org>"]
+
+[dependencies]
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/rust/integral-geometry/src/lib.rs	Wed Oct 17 22:45:33 2018 +0200
@@ -0,0 +1,94 @@
+use std::cmp;
+
+pub struct LinePoints {
+    e_x: i32,
+    e_y: i32,
+    d_x: i32,
+    d_y: i32,
+    s_x: i32,
+    s_y: i32,
+    x: i32,
+    y: i32,
+    d: i32,
+    i: i32,
+}
+
+impl LinePoints {
+    pub fn new(x1: i32, y1: i32, x2: i32, y2: i32) -> Self {
+        let mut d_x: i32 = x2 - x1;
+        let mut d_y: i32 = y2 - y1;
+        let s_x: i32;
+        let s_y: i32;
+
+        if d_x > 0 {
+            s_x = 1;
+        } else if d_x < 0 {
+            s_x = -1;
+            d_x = -d_x;
+        } else {
+            s_x = d_x;
+        }
+
+        if d_y > 0 {
+            s_y = 1;
+        } else if d_y < 0 {
+            s_y = -1;
+            d_y = -d_y;
+        } else {
+            s_y = d_y;
+        }
+
+        Self {
+            e_x: 0,
+            e_y: 0,
+            d_x,
+            d_y,
+            s_x,
+            s_y,
+            x: x1,
+            y: y1,
+            d: cmp::max(d_x, d_y),
+            i: 0,
+        }
+    }
+}
+
+impl Iterator for LinePoints {
+    type Item = (i32, i32);
+
+    fn next(&mut self) -> Option<Self::Item> {
+        if self.i <= self.d {
+            self.e_x += self.d_x;
+            self.e_y += self.d_y;
+
+            if self.e_x > self.d {
+                self.e_x -= self.d;
+                self.x += self.s_x;
+            }
+            if self.e_y > self.d {
+                self.e_y -= self.d;
+                self.y += self.s_y;
+            }
+
+            self.i += 1;
+
+            Some((self.x, self.y))
+        } else {
+            None
+        }
+    }
+}
+
+#[cfg(test)]
+mod tests {
+    use super::*;
+
+    #[test]
+    fn basic() {
+        let v = vec![(0, 0), (1, 1), (2, 2), (3, 3)];
+
+        for (&a, b) in v.iter().zip(LinePoints::new(0, 0, 3, 3)) {
+            assert_eq!(a, b);
+        }
+    }
+}
--- a/rust/lfprng/src/lib.rs	Wed Oct 17 22:00:58 2018 +0200
+++ b/rust/lfprng/src/lib.rs	Wed Oct 17 22:45:33 2018 +0200
@@ -49,7 +49,7 @@
 impl Iterator for LaggedFibonacciPRNG {
     type Item = u32;
 
-    fn next(&mut self) -> Option<u32> {
+    fn next(&mut self) -> Option<Self::Item> {
         self.get_next();
         Some(self.get_next())
     }