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]); |