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