changeset 13962 | 3f69a70063a5 |
parent 13959 | 1fa905aa4cdb |
child 13963 | 7e7a03e85ac4 |
13961:1c30793b1cea | 13962:3f69a70063a5 |
---|---|
1 use std::cmp; |
1 use std::cmp; |
2 use std::ops::{Add, Sub, Mul, Div, AddAssign, SubAssign, MulAssign, DivAssign}; |
2 use std::ops::{Add, AddAssign, Div, DivAssign, Mul, MulAssign, Sub, SubAssign}; |
3 |
3 |
4 #[derive(PartialEq, Eq, Clone, Copy, Debug)] |
4 #[derive(PartialEq, Eq, Clone, Copy, Debug)] |
5 pub struct Point { |
5 pub struct Point { |
6 pub x: i32, |
6 pub x: i32, |
7 pub y: i32, |
7 pub y: i32, |
8 } |
8 } |
9 |
9 |
10 impl Point { |
10 impl Point { |
11 #[inline] |
11 #[inline] |
12 pub fn new(x: i32, y: i32) -> Self { |
12 pub fn new(x: i32, y: i32) -> Self { |
13 Self {x, y} |
13 Self { x, y } |
14 } |
14 } |
15 |
15 |
16 #[inline] |
16 #[inline] |
17 pub fn zero() -> Self { |
17 pub fn zero() -> Self { |
18 Self::new(0, 0) |
18 Self::new(0, 0) |
44 impl $op for Point { |
44 impl $op for Point { |
45 type Output = Self; |
45 type Output = Self; |
46 |
46 |
47 #[inline] |
47 #[inline] |
48 fn $name(self, rhs: Self) -> Self::Output { |
48 fn $name(self, rhs: Self) -> Self::Output { |
49 Self::new(self.x.$name(rhs.x), |
49 Self::new(self.x.$name(rhs.x), self.y.$name(rhs.y)) |
50 self.y.$name(rhs.y)) |
50 } |
51 } |
51 } |
52 } |
52 }; |
53 } |
|
54 } |
53 } |
55 |
54 |
56 macro_rules! bin_assign_op_impl { |
55 macro_rules! bin_assign_op_impl { |
57 ($op: ty, $name: tt) => { |
56 ($op: ty, $name: tt) => { |
58 impl $op for Point { |
57 impl $op for Point { |
59 #[inline] |
58 #[inline] |
60 fn $name(&mut self, rhs: Self){ |
59 fn $name(&mut self, rhs: Self) { |
61 self.x.$name(rhs.x); |
60 self.x.$name(rhs.x); |
62 self.y.$name(rhs.y); |
61 self.y.$name(rhs.y); |
63 } |
62 } |
64 } |
63 } |
65 } |
64 }; |
66 } |
65 } |
67 |
66 |
68 bin_op_impl!(Add, add); |
67 bin_op_impl!(Add, add); |
69 bin_op_impl!(Sub, sub); |
68 bin_op_impl!(Sub, sub); |
70 bin_op_impl!(Mul, mul); |
69 bin_op_impl!(Mul, mul); |
121 None |
120 None |
122 } |
121 } |
123 } |
122 } |
124 } |
123 } |
125 |
124 |
125 pub struct ArcPoints { |
|
126 point: Point, |
|
127 step: i32, |
|
128 } |
|
129 |
|
130 impl ArcPoints { |
|
131 pub fn new(radius: i32) -> Self { |
|
132 Self { |
|
133 point: Point::new(0, radius), |
|
134 step: 3 - 2 * radius, |
|
135 } |
|
136 } |
|
137 } |
|
138 |
|
139 impl Iterator for ArcPoints { |
|
140 type Item = Point; |
|
141 |
|
142 fn next(&mut self) -> Option<Self::Item> { |
|
143 if self.point.x < self.point.y { |
|
144 let result = self.point; |
|
145 |
|
146 if self.step < 0 { |
|
147 self.step += self.point.x * 4 + 6; |
|
148 } else { |
|
149 self.step += (self.point.x - self.point.y) * 4 + 10; |
|
150 self.point.y -= 1; |
|
151 } |
|
152 |
|
153 self.point.x += 1; |
|
154 |
|
155 Some(result) |
|
156 } else if self.point.x == self.point.y { |
|
157 Some(self.point) |
|
158 } else { |
|
159 None |
|
160 } |
|
161 } |
|
162 } |
|
163 |
|
126 #[cfg(test)] |
164 #[cfg(test)] |
127 mod tests { |
165 mod tests { |
128 use super::*; |
166 use super::*; |
129 |
167 |
130 fn get_points(coords: &[(i32, i32)]) -> Vec<Point> { |
168 fn get_points(coords: &[(i32, i32)]) -> Vec<Point> { |
142 } |
180 } |
143 |
181 |
144 #[test] |
182 #[test] |
145 fn skewed() { |
183 fn skewed() { |
146 let line = LinePoints::new(Point::new(0, 0), Point::new(5, -7)); |
184 let line = LinePoints::new(Point::new(0, 0), Point::new(5, -7)); |
147 let v = get_points(&[(0, 0), (1, -1), (2, -2), (2, -3), (3, -4), (4, -5), (4, -6), (5, -7)]); |
185 let v = get_points(&[ |
186 (0, 0), |
|
187 (1, -1), |
|
188 (2, -2), |
|
189 (2, -3), |
|
190 (3, -4), |
|
191 (4, -5), |
|
192 (4, -6), |
|
193 (5, -7), |
|
194 ]); |
|
148 |
195 |
149 for (&a, b) in v.iter().zip(line) { |
196 for (&a, b) in v.iter().zip(line) { |
150 assert_eq!(a, b); |
197 assert_eq!(a, b); |
151 } |
198 } |
152 } |
199 } |