equal
deleted
inserted
replaced
|
1 use std::cmp; |
|
2 |
|
3 pub struct LinePoints { |
|
4 e_x: i32, |
|
5 e_y: i32, |
|
6 d_x: i32, |
|
7 d_y: i32, |
|
8 s_x: i32, |
|
9 s_y: i32, |
|
10 x: i32, |
|
11 y: i32, |
|
12 d: i32, |
|
13 i: i32, |
|
14 } |
|
15 |
|
16 impl LinePoints { |
|
17 pub fn new(x1: i32, y1: i32, x2: i32, y2: i32) -> Self { |
|
18 let mut d_x: i32 = x2 - x1; |
|
19 let mut d_y: i32 = y2 - y1; |
|
20 let s_x: i32; |
|
21 let s_y: i32; |
|
22 |
|
23 if d_x > 0 { |
|
24 s_x = 1; |
|
25 } else if d_x < 0 { |
|
26 s_x = -1; |
|
27 d_x = -d_x; |
|
28 } else { |
|
29 s_x = d_x; |
|
30 } |
|
31 |
|
32 if d_y > 0 { |
|
33 s_y = 1; |
|
34 } else if d_y < 0 { |
|
35 s_y = -1; |
|
36 d_y = -d_y; |
|
37 } else { |
|
38 s_y = d_y; |
|
39 } |
|
40 |
|
41 Self { |
|
42 e_x: 0, |
|
43 e_y: 0, |
|
44 d_x, |
|
45 d_y, |
|
46 s_x, |
|
47 s_y, |
|
48 x: x1, |
|
49 y: y1, |
|
50 d: cmp::max(d_x, d_y), |
|
51 i: 0, |
|
52 } |
|
53 } |
|
54 } |
|
55 |
|
56 impl Iterator for LinePoints { |
|
57 type Item = (i32, i32); |
|
58 |
|
59 fn next(&mut self) -> Option<Self::Item> { |
|
60 if self.i <= self.d { |
|
61 self.e_x += self.d_x; |
|
62 self.e_y += self.d_y; |
|
63 |
|
64 if self.e_x > self.d { |
|
65 self.e_x -= self.d; |
|
66 self.x += self.s_x; |
|
67 } |
|
68 if self.e_y > self.d { |
|
69 self.e_y -= self.d; |
|
70 self.y += self.s_y; |
|
71 } |
|
72 |
|
73 self.i += 1; |
|
74 |
|
75 Some((self.x, self.y)) |
|
76 } else { |
|
77 None |
|
78 } |
|
79 } |
|
80 } |
|
81 |
|
82 #[cfg(test)] |
|
83 mod tests { |
|
84 use super::*; |
|
85 |
|
86 #[test] |
|
87 fn basic() { |
|
88 let v = vec![(0, 0), (1, 1), (2, 2), (3, 3)]; |
|
89 |
|
90 for (&a, b) in v.iter().zip(LinePoints::new(0, 0, 3, 3)) { |
|
91 assert_eq!(a, b); |
|
92 } |
|
93 } |
|
94 } |