5 Mirror, |
5 Mirror, |
6 FlipMirror, |
6 FlipMirror, |
7 } |
7 } |
8 |
8 |
9 #[derive(Debug, PartialEq, Clone, Copy)] |
9 #[derive(Debug, PartialEq, Clone, Copy)] |
10 pub enum RotationTransform { |
10 pub enum Transform { |
11 Rotate0(SymmetryTransform), |
11 Rotate0(SymmetryTransform), |
12 Rotate90(SymmetryTransform), |
12 Rotate90(SymmetryTransform), |
13 Rotate180(SymmetryTransform), |
13 } |
14 Rotate270(SymmetryTransform), |
14 |
15 } |
15 impl Default for Transform { |
16 |
|
17 impl Default for RotationTransform { |
|
18 fn default() -> Self { |
16 fn default() -> Self { |
19 RotationTransform::Rotate0(SymmetryTransform::Id) |
17 Transform::Rotate0(SymmetryTransform::Id) |
20 } |
18 } |
21 } |
19 } |
22 |
20 |
23 impl SymmetryTransform { |
21 impl SymmetryTransform { |
24 pub fn mirror(&self) -> Self { |
22 pub fn mirror(&self) -> Self { |
38 Flip => Id, |
36 Flip => Id, |
39 Mirror => FlipMirror, |
37 Mirror => FlipMirror, |
40 FlipMirror => Mirror, |
38 FlipMirror => Mirror, |
41 } |
39 } |
42 } |
40 } |
43 } |
41 |
44 |
42 pub fn is_mirrored(&self) -> bool { |
45 impl RotationTransform { |
43 match self { |
|
44 Id => false, |
|
45 Flip => false, |
|
46 Mirror => true, |
|
47 FlipMirror => true, |
|
48 } |
|
49 } |
|
50 |
|
51 pub fn is_flipped(&self) -> bool { |
|
52 match self { |
|
53 Id => false, |
|
54 Flip => true, |
|
55 Mirror => false, |
|
56 FlipMirror => true, |
|
57 } |
|
58 } |
|
59 } |
|
60 |
|
61 impl Transform { |
46 pub fn new() -> Self { |
62 pub fn new() -> Self { |
47 Self::default() |
63 Self::default() |
48 } |
64 } |
49 |
65 |
50 pub fn mirror(self) -> RotationTransform { |
66 pub fn mirror(self) -> Transform { |
51 match self { |
67 match self { |
52 RotationTransform::Rotate0(s) => RotationTransform::Rotate0(s.mirror()), |
68 Transform::Rotate0(s) => Transform::Rotate0(s.mirror()), |
53 RotationTransform::Rotate90(s) => RotationTransform::Rotate270(s.mirror()).simplified(), |
69 Transform::Rotate90(s) => Transform::Rotate90(s.flip()), |
54 RotationTransform::Rotate180(s) => { |
70 } |
55 RotationTransform::Rotate180(s.mirror()).simplified() |
71 } |
56 } |
72 |
57 RotationTransform::Rotate270(s) => RotationTransform::Rotate90(s.mirror()), |
73 pub fn flip(self) -> Transform { |
58 } |
74 match self { |
59 } |
75 Transform::Rotate0(s) => Transform::Rotate0(s.flip()), |
60 |
76 Transform::Rotate90(s) => Transform::Rotate90(s.mirror()), |
61 pub fn flip(self) -> RotationTransform { |
77 } |
62 match self { |
78 } |
63 RotationTransform::Rotate0(s) => RotationTransform::Rotate0(s.flip()), |
79 |
64 RotationTransform::Rotate90(s) => RotationTransform::Rotate90(s.flip()), |
80 pub fn rotate90(self) -> Transform { |
65 RotationTransform::Rotate180(s) => RotationTransform::Rotate180(s.flip()).simplified(), |
81 match self { |
66 RotationTransform::Rotate270(s) => RotationTransform::Rotate270(s.flip()).simplified(), |
82 Transform::Rotate0(s) => Transform::Rotate90(s), |
67 } |
83 Transform::Rotate90(s) => Transform::Rotate0(s.flip().mirror()), |
68 } |
84 } |
69 |
85 } |
70 pub fn rotate90(self) -> RotationTransform { |
86 |
71 match self { |
87 pub fn rotate180(self) -> Transform { |
72 RotationTransform::Rotate0(s) => RotationTransform::Rotate90(s), |
88 match self { |
73 RotationTransform::Rotate90(s) => RotationTransform::Rotate180(s).simplified(), |
89 Transform::Rotate0(s) => Transform::Rotate0(s.flip().mirror()), |
74 RotationTransform::Rotate180(s) => RotationTransform::Rotate270(s).simplified(), |
90 Transform::Rotate90(s) => Transform::Rotate90(s.flip().mirror()), |
75 RotationTransform::Rotate270(s) => RotationTransform::Rotate0(s), |
91 } |
76 } |
92 } |
77 } |
93 |
78 |
94 pub fn rotate270(self) -> Transform { |
79 pub fn rotate180(self) -> RotationTransform { |
95 match self { |
80 match self { |
96 Transform::Rotate0(s) => Transform::Rotate90(s.flip().mirror()), |
81 RotationTransform::Rotate0(s) => RotationTransform::Rotate180(s).simplified(), |
97 Transform::Rotate90(s) => Transform::Rotate0(s), |
82 RotationTransform::Rotate90(s) => RotationTransform::Rotate270(s).simplified(), |
98 } |
83 RotationTransform::Rotate180(s) => RotationTransform::Rotate0(s), |
99 } |
84 RotationTransform::Rotate270(s) => RotationTransform::Rotate90(s), |
100 |
85 } |
101 pub fn is_mirrored(&self) -> bool { |
86 } |
102 match self { |
87 |
103 Transform::Rotate0(s) => s.is_mirrored(), |
88 pub fn rotate270(self) -> RotationTransform { |
104 Transform::Rotate90(s) => s.is_mirrored(), |
89 match self { |
105 } |
90 RotationTransform::Rotate0(s) => RotationTransform::Rotate270(s).simplified(), |
106 } |
91 RotationTransform::Rotate90(s) => RotationTransform::Rotate0(s), |
107 |
92 RotationTransform::Rotate180(s) => RotationTransform::Rotate90(s), |
108 pub fn is_flipped(&self) -> bool { |
93 RotationTransform::Rotate270(s) => RotationTransform::Rotate180(s).simplified(), |
109 match self { |
94 } |
110 Transform::Rotate0(s) => s.is_flipped(), |
95 } |
111 Transform::Rotate90(s) => s.is_flipped(), |
96 |
|
97 fn simplified(self) -> Self { |
|
98 match self { |
|
99 RotationTransform::Rotate0(s) => RotationTransform::Rotate0(s), |
|
100 RotationTransform::Rotate90(s) => RotationTransform::Rotate90(s), |
|
101 RotationTransform::Rotate180(s) => RotationTransform::Rotate0(s.flip().mirror()), |
|
102 RotationTransform::Rotate270(s) => RotationTransform::Rotate90(s.flip().mirror()), |
|
103 } |
112 } |
104 } |
113 } |
105 } |
114 } |
106 |
115 |
107 #[cfg(test)] |
116 #[cfg(test)] |
108 mod tests { |
117 mod tests { |
109 use super::{RotationTransform::*, SymmetryTransform::*, *}; |
118 use super::{SymmetryTransform::*, Transform::*, *}; |
110 |
119 |
111 // I totally wrote all of this myself and didn't use ChatGPT |
120 // I totally wrote all of this myself and didn't use ChatGPT |
112 #[test] |
121 #[test] |
113 fn test_default() { |
122 fn test_default() { |
114 let rt = RotationTransform::new(); |
123 let rt = Transform::new(); |
115 assert_eq!(rt, Rotate0(Id)); |
124 assert_eq!(rt, Rotate0(Id)); |
116 } |
125 } |
117 |
126 |
118 #[test] |
127 #[test] |
119 fn test_mirror() { |
128 fn test_mirror() { |
143 assert_eq!(rotated, Rotate90(Flip)); |
152 assert_eq!(rotated, Rotate90(Flip)); |
144 } |
153 } |
145 |
154 |
146 #[test] |
155 #[test] |
147 fn test_rotate270() { |
156 fn test_rotate270() { |
148 let rt = Rotate180(Flip); |
157 let rt = Transform::new().rotate180().flip(); |
149 let rotated = rt.rotate270(); |
158 let rotated = rt.rotate270(); |
150 assert_eq!(rotated, Rotate90(Flip)); |
159 assert_eq!(rotated, Rotate90(Flip)); |
151 } |
160 } |
152 |
161 |
153 #[test] |
162 #[test] |
154 fn test_simplified() { |
163 fn test_rotate180_2() { |
155 let rt = Rotate180(Id); |
164 let rt = Transform::new().rotate180(); |
156 let simplified = rt.simplified(); |
165 assert_eq!(rt, Rotate0(FlipMirror)); |
157 assert_eq!(simplified, Rotate0(FlipMirror)); |
|
158 } |
166 } |
159 |
167 |
160 #[test] |
168 #[test] |
161 fn test_rotation_chain() { |
169 fn test_rotation_chain() { |
162 assert_eq!( |
170 assert_eq!( |
163 RotationTransform::default(), |
171 Transform::default(), |
164 RotationTransform::default() |
172 Transform::default() |
165 .rotate90() |
173 .rotate90() |
166 .rotate90() |
174 .rotate90() |
167 .rotate90() |
175 .rotate90() |
168 .rotate90() |
176 .rotate90() |
169 ); |
177 ); |
170 assert_eq!( |
178 assert_eq!( |
171 RotationTransform::default().rotate90(), |
179 Transform::default().rotate90(), |
172 RotationTransform::default() |
180 Transform::default().rotate180().rotate90().rotate180() |
173 .rotate180() |
181 ); |
174 .rotate90() |
182 assert_eq!( |
175 .rotate180() |
183 Transform::default().rotate180(), |
176 ); |
184 Transform::default().rotate180().rotate270().rotate90() |
177 assert_eq!( |
|
178 RotationTransform::default().rotate180(), |
|
179 RotationTransform::default() |
|
180 .rotate180() |
|
181 .rotate270() |
|
182 .rotate90() |
|
183 ); |
185 ); |
184 } |
186 } |
185 |
187 |
186 #[test] |
188 #[test] |
187 fn test_combinations_chain() { |
189 fn test_combinations_chain() { |
188 assert_eq!( |
190 assert_eq!( |
189 RotationTransform::default(), |
191 Transform::default(), |
190 RotationTransform::default() |
192 Transform::default().flip().rotate180().flip().rotate180() |
191 .flip() |
193 ); |
192 .rotate180() |
194 assert_eq!( |
193 .flip() |
195 Transform::default(), |
194 .rotate180() |
196 Transform::default() |
195 ); |
|
196 assert_eq!( |
|
197 RotationTransform::default(), |
|
198 RotationTransform::default() |
|
199 .mirror() |
197 .mirror() |
200 .rotate180() |
198 .rotate180() |
201 .mirror() |
199 .mirror() |
202 .rotate180() |
200 .rotate180() |
203 ); |
201 ); |
204 assert_eq!( |
202 assert_eq!( |
205 RotationTransform::default(), |
203 Transform::default(), |
206 RotationTransform::default() |
204 Transform::default().rotate90().flip().rotate90().mirror().rotate180() |
207 .rotate90() |
205 ); |
208 .flip() |
206 } |
209 .rotate90() |
207 } |
210 .mirror() |
|
211 ); |
|
212 } |
|
213 } |
|