1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
use super::{point::Point, vector::Vector};

/// The Bresenham's Line aglorithm as an iterator of points
///
/// See [https://en.wikipedia.org/wiki/Bresenham%27s_line_algorithm]
pub struct LineAlgorithm {
    current: Point,
    dest: Point,
    delta: Point,
    increment: Point,
    error: i64,
}

impl LineAlgorithm {
    pub fn new(start: Point, end: Point) -> LineAlgorithm {
        let delta: Point = ((end.x - start.x).abs(), -(end.y - start.y).abs()).into();
        let error = delta.x + delta.y;
        LineAlgorithm {
            current: start,
            dest: end,
            delta,
            increment: (
                if start.x < end.x { 1 } else { -1 },
                if start.y < end.y { 1 } else { -1 },
            )
                .into(),
            error,
        }
    }
}

impl Iterator for LineAlgorithm {
    type Item = Point;

    fn next(&mut self) -> Option<Self::Item> {
        if self.current == self.dest {
            return None;
        }
        let item = self.current.clone();
        let e2 = 2 * self.error;
        if e2 >= self.delta.y {
            if self.current.x == self.dest.x {
                return None;
            }
            self.error += self.delta.y;
            self.current.x += self.increment.x;
        }
        if e2 <= self.delta.x {
            if self.current.y == self.dest.y {
                return None;
            }
            self.error += self.delta.x;
            self.current.y += self.increment.y;
        }
        Some(item)
    }
}

pub struct VectorIter {
    line_iter: LineAlgorithm,
}

impl VectorIter {
    pub fn new(v: Vector) -> VectorIter {
        let mut line_iter = LineAlgorithm::new(
            (0, 0).into(),
            Point {
                x: v.x as i64,
                y: v.y as i64,
            },
        );
        line_iter.next();
        VectorIter { line_iter }
    }
}

impl Iterator for VectorIter {
    type Item = Vector;

    fn next(&mut self) -> Option<Self::Item> {
        let prev = self.line_iter.next();
        let cur = self.line_iter.current;
        prev.map(|p| cur - p)
    }
}

pub struct SimpleLineIter {
    current: Option<Point>,
    dest: Point,
}

impl SimpleLineIter {
    pub fn new(start: Point, end: Point) -> SimpleLineIter {
        SimpleLineIter {
            current: Some(start),
            dest: end,
        }
    }
}

impl Iterator for SimpleLineIter {
    type Item = Point;

    fn next(&mut self) -> Option<Self::Item> {
        if let Some(current) = self.current.as_mut() {
            let next = *current;
            let diff = self.dest - *current;
            let increment = diff / diff;
            println!("\t\t{:?}", diff);
            if increment.x.abs() > 0.0 {
                current.x += (increment.x / increment.x) as i64;
            }
            if increment.y.abs() > 0.0 {
                current.y += (increment.y / increment.y) as i64;
            }
            if diff.magnitude() == 0.0 {
                self.current = None;
            }
            Some(next)
        } else {
            None
        }
    }
}