src/cube.rs

changeset 3
ff4656da04af
parent 0
989e2fe08db2
child 5
f248e1434c3b
equal deleted inserted replaced
2:86e0228f38f8 3:ff4656da04af
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]);

mercurial