24 Indirect { destination : Face, intermediate : Face }, |
24 Indirect { destination : Face, intermediate : Face }, |
25 } |
25 } |
26 |
26 |
27 /// An iterator over paths on a cube, from a source face to a destination face. |
27 /// An iterator over paths on a cube, from a source face to a destination face. |
28 #[derive(Clone, Debug)] |
28 #[derive(Clone, Debug)] |
29 pub struct PathIter { |
29 pub enum PathIter { |
30 destination : Face, |
30 Same { |
31 intermediate : AdjacentFaces, |
31 destination : Face, |
32 current : usize |
32 exhausted : bool |
|
33 }, |
|
34 Indirect { |
|
35 destination : Face, |
|
36 intermediate : AdjacentFaces, |
|
37 current : usize |
|
38 } |
33 } |
39 } |
34 |
40 |
35 impl std::iter::Iterator for PathIter { |
41 impl std::iter::Iterator for PathIter { |
36 type Item = Path; |
42 type Item = Path; |
37 |
43 |
38 fn next(&mut self) -> Option<Self::Item> { |
44 fn next(&mut self) -> Option<Self::Item> { |
39 let PathIter { destination, intermediate : ref i, ref mut current } = *self; |
45 match *self { |
40 while *current < i.len() { |
46 PathIter::Same { destination, ref mut exhausted } => { |
41 let intermediate = i[*current]; |
47 if !*exhausted { |
42 *current += 1; |
48 *exhausted = true; |
43 if intermediate == destination { |
49 return Some(Path::Direct { destination }) |
44 return Some(Path::Direct { destination }) |
50 } |
45 } else if intermediate != destination.opposing_face() { |
51 None |
46 return Some(Path::Indirect{ destination, intermediate }) |
52 }, |
47 } |
53 PathIter::Indirect { destination, intermediate : ref i, ref mut current } => { |
48 // Paths should never go through a face opposing the destination. |
54 while *current < i.len() { |
49 } |
55 let intermediate = i[*current]; |
50 None |
56 *current += 1; |
|
57 if intermediate == destination { |
|
58 return Some(Path::Direct { destination }) |
|
59 } else if intermediate != destination.opposing_face() { |
|
60 return Some(Path::Indirect{ destination, intermediate }) |
|
61 } |
|
62 // Paths should never go through a face opposing the destination. |
|
63 } |
|
64 None |
|
65 } |
|
66 } |
51 } |
67 } |
52 } |
68 } |
53 |
69 |
54 impl std::fmt::Display for Face { |
70 impl std::fmt::Display for Face { |
55 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { |
71 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { |
164 } |
180 } |
165 |
181 |
166 |
182 |
167 /// Returns an iterator over all the paths from `self` to `other`. |
183 /// Returns an iterator over all the paths from `self` to `other`. |
168 fn paths(&self, other : Face) -> PathIter { |
184 fn paths(&self, other : Face) -> PathIter { |
169 PathIter { |
185 if other == *self { |
170 intermediate : self.adjacent_faces(), |
186 PathIter::Same { |
171 destination : other, |
187 destination : other, |
172 current : 0 |
188 exhausted : false |
|
189 } |
|
190 } else { |
|
191 PathIter::Indirect { |
|
192 intermediate : self.adjacent_faces(), |
|
193 destination : other, |
|
194 current : 0 |
|
195 } |
173 } |
196 } |
174 } |
197 } |
175 |
198 |
176 /// Indicates whether an unfolded point `p` is on this face, i.e., |
199 /// Indicates whether an unfolded point `p` is on this face, i.e., |
177 /// has coordinates in [0,1]². |
200 /// has coordinates in [0,1]². |