diff options
-rw-r--r-- | src/bitmap.rs | 50 | ||||
-rw-r--r-- | src/symmetry.rs | 42 |
2 files changed, 65 insertions, 27 deletions
diff --git a/src/bitmap.rs b/src/bitmap.rs index 726e0a2..128a14e 100644 --- a/src/bitmap.rs +++ b/src/bitmap.rs | |||
@@ -145,7 +145,12 @@ where | |||
145 | old_val | 145 | old_val |
146 | } | 146 | } |
147 | 147 | ||
148 | pub fn get_circle<P: Into<MapPoint>>(&self, center: P, radius: u32) -> Vec<MapPoint> { | 148 | pub fn get_circle<P: Into<MapPoint>>( |
149 | &self, | ||
150 | center: P, | ||
151 | radius: u32, | ||
152 | filled: bool, | ||
153 | ) -> Vec<MapPoint> { | ||
149 | let mut circle: Vec<(i64, i64)> = vec![]; | 154 | let mut circle: Vec<(i64, i64)> = vec![]; |
150 | let MapPoint { x, y } = center.into(); | 155 | let MapPoint { x, y } = center.into(); |
151 | let x = x as i64; | 156 | let x = x as i64; |
@@ -160,6 +165,12 @@ where | |||
160 | circle.push((x - dy, y + dx)); | 165 | circle.push((x - dy, y + dx)); |
161 | circle.push((x + dy, y - dx)); | 166 | circle.push((x + dy, y - dx)); |
162 | circle.push((x - dy, y - dx)); | 167 | circle.push((x - dy, y - dx)); |
168 | if filled { | ||
169 | circle.extend((x - dx.abs() + 1..x + dx.abs()).map(|x| (x, y + dy))); | ||
170 | circle.extend((x - dx.abs() + 1..x + dx.abs()).map(|x| (x, y - dy))); | ||
171 | circle.extend((x - dy.abs() + 1..x + dy.abs()).map(|x| (x, y + dx))); | ||
172 | circle.extend((x - dy.abs() + 1..x + dy.abs()).map(|x| (x, y - dx))); | ||
173 | } | ||
163 | dy = dy + 1; | 174 | dy = dy + 1; |
164 | if err < 0 { | 175 | if err < 0 { |
165 | err = err + 2 * dy + 1; | 176 | err = err + 2 * dy + 1; |
@@ -168,16 +179,6 @@ where | |||
168 | err += 2 * (dy - dx) + 1; | 179 | err += 2 * (dy - dx) + 1; |
169 | } | 180 | } |
170 | } | 181 | } |
171 | for xi in 0..radius as i64 { | ||
172 | for yi in 0..radius as i64 { | ||
173 | if xi.pow(2) + yi.pow(2) < (radius as i64).pow(2) { | ||
174 | circle.push((x + xi, y + yi)); | ||
175 | circle.push((x - xi, y + yi)); | ||
176 | circle.push((x + xi, y - yi)); | ||
177 | circle.push((x - xi, y - yi)); | ||
178 | } | ||
179 | } | ||
180 | } | ||
181 | circle | 182 | circle |
182 | .into_iter() | 183 | .into_iter() |
183 | .flat_map(|pt| MapPoint::try_from(pt)) | 184 | .flat_map(|pt| MapPoint::try_from(pt)) |
@@ -229,22 +230,6 @@ where | |||
229 | .filter(|&pt| self.is_inside(pt)) | 230 | .filter(|&pt| self.is_inside(pt)) |
230 | .collect() | 231 | .collect() |
231 | } | 232 | } |
232 | |||
233 | pub fn mirror_figure(&self, figure: &[MapPoint], line: u32, axis: Axis) -> Vec<MapPoint> { | ||
234 | figure | ||
235 | .iter() | ||
236 | .map(|pt| pt.mirror_about(line, axis)) | ||
237 | .filter(|&pt| self.is_inside(pt)) | ||
238 | .collect() | ||
239 | } | ||
240 | |||
241 | pub fn reflect_figure(&self, figure: &[MapPoint], around: MapPoint) -> Vec<MapPoint> { | ||
242 | figure | ||
243 | .iter() | ||
244 | .map(|pt| pt.reflect(around)) | ||
245 | .filter(|&pt| self.is_inside(pt)) | ||
246 | .collect() | ||
247 | } | ||
248 | } | 233 | } |
249 | 234 | ||
250 | fn abs_difference<T: Sub<Output = T> + Ord>(x: T, y: T) -> T { | 235 | fn abs_difference<T: Sub<Output = T> + Ord>(x: T, y: T) -> T { |
@@ -254,3 +239,14 @@ fn abs_difference<T: Sub<Output = T> + Ord>(x: T, y: T) -> T { | |||
254 | x - y | 239 | x - y |
255 | } | 240 | } |
256 | } | 241 | } |
242 | |||
243 | pub fn mirror_figure(figure: &[MapPoint], line: u32, axis: Axis) -> Vec<MapPoint> { | ||
244 | figure | ||
245 | .iter() | ||
246 | .map(|pt| pt.mirror_about(line, axis)) | ||
247 | .collect() | ||
248 | } | ||
249 | |||
250 | pub fn reflect_figure(figure: &[MapPoint], around: MapPoint) -> Vec<MapPoint> { | ||
251 | figure.iter().map(|pt| pt.reflect(around)).collect() | ||
252 | } | ||
diff --git a/src/symmetry.rs b/src/symmetry.rs new file mode 100644 index 0000000..7517317 --- /dev/null +++ b/src/symmetry.rs | |||
@@ -0,0 +1,42 @@ | |||
1 | use std::fmt; | ||
2 | |||
3 | use crate::bitmap::{mirror_figure, reflect_figure, Axis, MapPoint}; | ||
4 | |||
5 | #[derive(Debug, Default, Copy, Clone)] | ||
6 | pub struct Symmetry { | ||
7 | pub x: Option<u32>, | ||
8 | pub y: Option<u32>, | ||
9 | } | ||
10 | |||
11 | impl Symmetry { | ||
12 | pub fn apply(self, figure: &[MapPoint]) -> Vec<MapPoint> { | ||
13 | let Symmetry { x, y } = self; | ||
14 | match (x, y) { | ||
15 | (None, None) => vec![], | ||
16 | (Some(line), None) => mirror_figure(figure, line, Axis::X), | ||
17 | (None, Some(line)) => mirror_figure(figure, line, Axis::Y), | ||
18 | (Some(x), Some(y)) => { | ||
19 | let along_x = mirror_figure(figure, x, Axis::X); | ||
20 | let along_y = mirror_figure(figure, y, Axis::Y); | ||
21 | let reflected = reflect_figure(figure, (x, y).into()); | ||
22 | along_x | ||
23 | .into_iter() | ||
24 | .chain(along_y) | ||
25 | .chain(reflected) | ||
26 | .collect() | ||
27 | } | ||
28 | } | ||
29 | } | ||
30 | } | ||
31 | |||
32 | impl fmt::Display for Symmetry { | ||
33 | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { | ||
34 | let Symmetry { x, y } = self; | ||
35 | match (x, y) { | ||
36 | (None, None) => write!(f, " "), | ||
37 | (Some(_), None) => write!(f, "-"), | ||
38 | (None, Some(_)) => write!(f, "|"), | ||
39 | (Some(_), Some(_)) => write!(f, "+"), | ||
40 | } | ||
41 | } | ||
42 | } | ||