| 11 |
11 |
| 12 pub type Point = Loc<f64, 2>; |
12 pub type Point = Loc<f64, 2>; |
| 13 |
13 |
| 14 pub type AdjacentFaces = [Face; 4]; |
14 pub type AdjacentFaces = [Face; 4]; |
| 15 |
15 |
| |
16 #[derive(Clone, Debug)] |
| 16 pub enum Path { |
17 pub enum Path { |
| 17 Direct { destination : Face }, |
18 Direct { destination : Face }, |
| 18 Indirect { destination : Face, intermediate : Face }, |
19 Indirect { destination : Face, intermediate : Face }, |
| 19 } |
20 } |
| 20 |
21 |
| 51 } |
52 } |
| 52 } |
53 } |
| 53 |
54 |
| 54 |
55 |
| 55 impl Face { |
56 impl Face { |
| 56 /// Returns an array of the four faces adjacent to `self`. |
57 /// Returns an array of the four faces adjacent to `self` in the |
| |
58 /// order [left, right, down, up] in the `self`-relative unfolding. |
| 57 pub fn adjacent_faces(&self) -> AdjacentFaces { |
59 pub fn adjacent_faces(&self) -> AdjacentFaces { |
| 58 match *self { |
60 match *self { |
| 59 F1 => [F2, F3, F4, F5], |
61 F1 => [F3, F2, F4, F5], |
| 60 F2 => [F1, F4, F5, F6], |
62 F2 => [F4, F5, F1, F6], |
| 61 F3 => [F1, F4, F5, F6], |
63 F3 => [F5, F4, F1, F6], |
| 62 F4 => [F1, F2, F3, F6], |
64 F4 => [F3, F2, F1, F6], |
| 63 F5 => [F1, F2, F3, F6], |
65 F5 => [F2, F3, F1, F6], |
| 64 F6 => [F2, F3, F4, F5], |
66 F6 => [F3, F2, F4, F5], |
| 65 } |
67 } |
| 66 } |
68 } |
| 67 |
69 |
| 68 /// Returns the face opposing `self`. |
70 /// Returns the face opposing `self`. |
| 69 pub fn opposing_face(&self) -> Face { |
71 pub fn opposing_face(&self) -> Face { |
| 70 match *self { |
72 match *self { |
| 71 F1 => F6, |
73 F1 => F6, |
| 72 F2 => F3, |
74 F2 => F3, |
| 73 F3 => F2, |
75 F3 => F2, |
| 74 F4 => F6, |
76 F4 => F5, |
| 75 F5 => F4, |
77 F5 => F4, |
| 76 F6 => F1, |
78 F6 => F1, |
| 77 } |
79 } |
| 78 } |
80 } |
| 79 |
81 |
| 134 } |
136 } |
| 135 |
137 |
| 136 /// Converts a point behind a path to the coordinate system of `self`. |
138 /// Converts a point behind a path to the coordinate system of `self`. |
| 137 pub fn convert(&self, path : &Path, p: &Point) -> Point { |
139 pub fn convert(&self, path : &Path, p: &Point) -> Point { |
| 138 use Path::*; |
140 use Path::*; |
| |
141 //dbg!(*self, path); |
| 139 match path { |
142 match path { |
| 140 &Direct{ destination : d} => self.convert_adjacent(d, p), |
143 &Direct{ destination : d} => self.convert_adjacent(d, p), |
| 141 &Indirect{ destination : d, intermediate : i } |
144 &Indirect{ destination : d, intermediate : i } |
| 142 => {dbg!((d,i)); dbg!(self.convert_adjacent(i, dbg!(&i.convert_adjacent(d, p).unwrap())))} |
145 => {self.convert_adjacent(i, &i.convert_adjacent(d, p).unwrap())} |
| 143 }.unwrap() |
146 }.unwrap() |
| 144 } |
147 } |
| 145 |
148 |
| 146 |
149 |
| 147 /// Returns an iterator over all the paths from `self` to `other`. |
150 /// Returns an iterator over all the paths from `self` to `other`. |
| 148 fn paths(&self, other : Face) -> PathIter { |
151 fn paths(&self, other : Face) -> PathIter { |
| |
152 //dbg!(self, other); |
| 149 if self.opposing_face() == other { |
153 if self.opposing_face() == other { |
| 150 PathIter::Indirect { |
154 PathIter::Indirect { |
| 151 intermediate : self.adjacent_faces(), |
155 intermediate : self.adjacent_faces(), |
| 152 destination : other, |
156 destination : other, |
| 153 current : 0 |
157 current : 0 |
| 154 } |
158 } |
| 155 } else { |
159 } else { |
| 156 PathIter::Direct(other) |
160 PathIter::Direct(other) |
| 157 } |
161 } |
| 158 } |
162 } |
| |
163 |
| |
164 pub fn is_in_face(&self, p: &Point) -> bool { |
| |
165 p.iter().map(|t| t.abs()).all(|t| 0.0 <= t && t <= 1.0) |
| |
166 } |
| |
167 |
| |
168 pub fn find_crossing(&self, p : &Point) -> Face { |
| |
169 let &Loc([x, y]) = p; |
| |
170 use std::cmp::Ordering::*; |
| |
171 let crossing = |t| match (0.0 <= t, t<=1.0) { |
| |
172 (false, _) => Less, |
| |
173 (_, false) => Greater, |
| |
174 _ => Equal, |
| |
175 }; |
| |
176 |
| |
177 // TODO: how to properly handle corners? Just throw an error? |
| |
178 match (crossing(x), crossing(y)) { |
| |
179 (Equal, Equal) => *self, |
| |
180 (Less, _) => self.adjacent_faces()[0], |
| |
181 (Greater, _) => self.adjacent_faces()[1], |
| |
182 (Equal, Less) => self.adjacent_faces()[2], |
| |
183 (Equal, Greater) => self.adjacent_faces()[3], |
| |
184 } |
| |
185 } |
| 159 } |
186 } |
| 160 |
187 |
| 161 #[derive(Clone, Debug, PartialEq)] |
188 #[derive(Clone, Debug, PartialEq)] |
| 162 pub struct OnCube { |
189 pub struct OnCube { |
| 163 face : Face, |
190 face : Face, |
| 166 |
193 |
| 167 impl ManifoldPoint for OnCube { |
194 impl ManifoldPoint for OnCube { |
| 168 type Tangent = Point; |
195 type Tangent = Point; |
| 169 |
196 |
| 170 fn exp(&self, tangent : &Self::Tangent) -> Self { |
197 fn exp(&self, tangent : &Self::Tangent) -> Self { |
| 171 unimplemented!(); |
198 let mut face = self.face; |
| |
199 let mut point = self.point + tangent; |
| |
200 loop { |
| |
201 let next_face = face.find_crossing(&point); |
| |
202 if next_face == face { |
| |
203 break |
| |
204 } |
| |
205 point = next_face.convert_adjacent(face, &point).unwrap(); |
| |
206 face = next_face; |
| |
207 } |
| |
208 OnCube { face, point } |
| 172 } |
209 } |
| 173 |
210 |
| 174 fn log(&self, other : &Self) -> Self::Tangent { |
211 fn log(&self, other : &Self) -> Self::Tangent { |
| 175 let mut best_len = f64::INFINITY; |
212 let mut best_len = f64::INFINITY; |
| 176 let mut best_tan = Loc([0.0, 0.0]); |
213 let mut best_tan = Loc([0.0, 0.0]); |