aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/bitmap.rs50
-rw-r--r--src/symmetry.rs42
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
250fn abs_difference<T: Sub<Output = T> + Ord>(x: T, y: T) -> T { 235fn 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
243pub 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
250pub 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 @@
1use std::fmt;
2
3use crate::bitmap::{mirror_figure, reflect_figure, Axis, MapPoint};
4
5#[derive(Debug, Default, Copy, Clone)]
6pub struct Symmetry {
7 pub x: Option<u32>,
8 pub y: Option<u32>,
9}
10
11impl 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
32impl 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}