src/cube.rs

changeset 46
90cc221eb52b
parent 37
d7cd14b8ccc0
child 56
34f8ec636368
equal deleted inserted replaced
45:cac6978dc7dd 46:90cc221eb52b
12 #[derive(Copy, Clone, Debug, Eq, PartialEq, Serialize_repr, Deserialize_repr)] 12 #[derive(Copy, Clone, Debug, Eq, PartialEq, Serialize_repr, Deserialize_repr)]
13 #[repr(u8)] 13 #[repr(u8)]
14 pub enum Face {F1 = 1, F2 = 2, F3 = 3, F4 = 4, F5 = 5, F6 = 6} 14 pub enum Face {F1 = 1, F2 = 2, F3 = 3, F4 = 4, F5 = 5, F6 = 6}
15 use Face::*; 15 use Face::*;
16 16
17 /// General point in 2D
17 pub type Point = Loc<f64, 2>; 18 pub type Point = Loc<f64, 2>;
18 19
20 /// Types for faces adjacent to a given face.
19 pub type AdjacentFaces = [Face; 4]; 21 pub type AdjacentFaces = [Face; 4];
20 22
23 /// Types of paths on a cube
21 #[derive(Clone, Debug, Serialize)] 24 #[derive(Clone, Debug, Serialize)]
22 pub enum Path { 25 pub enum Path {
26 /// Direct path from an unindicated source face to a `destination` face.
23 Direct { destination : Face }, 27 Direct { destination : Face },
28 /// Indirect path from an unindicated source face to a `destination` face,
29 /// via an `intermediate` face.
24 Indirect { destination : Face, intermediate : Face }, 30 Indirect { destination : Face, intermediate : Face },
25 } 31 }
26 32
27 /// An iterator over paths on a cube, from a source face to a destination face. 33 /// An iterator over paths on a cube, from a source face to a destination face.
28 #[derive(Clone, Debug)] 34 #[derive(Clone, Debug)]
29 pub enum PathIter { 35 pub enum PathIter {
36 /// Direct path to a destination.
30 Same { 37 Same {
38 /// Deistination face
31 destination : Face, 39 destination : Face,
40 /// Indicator whether the only possible [`Path::Direct`] has already been returned.
32 exhausted : bool 41 exhausted : bool
33 }, 42 },
43 /// Path via several possible intermedite faces.
44 /// This is used to generate several [`Path::Indirect`].
34 Indirect { 45 Indirect {
46 /// Destination face
35 destination : Face, 47 destination : Face,
48 /// Possible intermediate faces
36 intermediate : AdjacentFaces, 49 intermediate : AdjacentFaces,
50 /// Intermediate face index counter.
37 current : usize 51 current : usize
38 } 52 }
39 } 53 }
40 54
41 impl std::iter::Iterator for PathIter { 55 impl std::iter::Iterator for PathIter {
195 } 209 }
196 } 210 }
197 } 211 }
198 212
199 /// Indicates whether an unfolded point `p` is on this face, i.e., 213 /// Indicates whether an unfolded point `p` is on this face, i.e.,
200 /// has coordinates in [0,1]². 214 /// has coordinates in $\[0,1\]^2$.
201 pub fn is_in_face(&self, p: &Point) -> bool { 215 pub fn is_in_face(&self, p: &Point) -> bool {
202 p.iter().all(|t| 0.0 <= *t && *t <= 1.0) 216 p.iter().all(|t| 0.0 <= *t && *t <= 1.0)
203 } 217 }
204 218
205 /// Given an unfolded point `p` and a destination point `d` in unfolded coordinates, 219 /// Given an unfolded point `p` and a destination point `d` in unfolded coordinates,
262 F6 => [x, y, 1.0], 276 F6 => [x, y, 1.0],
263 }) 277 })
264 } 278 }
265 } 279 }
266 280
281 /// Point on a the surface of the unit cube $\[0,1\]^3$.
267 #[derive(Clone, Debug, PartialEq, Serialize)] 282 #[derive(Clone, Debug, PartialEq, Serialize)]
268 pub struct OnCube { 283 pub struct OnCube {
269 face : Face, 284 face : Face,
270 point : Point, 285 point : Point,
271 } 286 }
346 361
347 #[cfg(test)] 362 #[cfg(test)]
348 mod tests { 363 mod tests {
349 use super::*; 364 use super::*;
350 365
366 /// Tests that the distancse between the centers of all the faces are correctly calculated.
351 #[test] 367 #[test]
352 fn center_distance() { 368 fn center_distance() {
353 let center = Loc([0.5, 0.5]); 369 let center = Loc([0.5, 0.5]);
354 370
355 for f1 in Face::all() { 371 for f1 in Face::all() {
365 } 381 }
366 } 382 }
367 } 383 }
368 } 384 }
369 385
386 /// Tests that the distances between points on the boundaries of distinct faces are
387 /// correctly calculated.
370 #[test] 388 #[test]
371 fn boundary_distance() { 389 fn boundary_distance() {
372 let left = Loc([0.0, 0.5]); 390 let left = Loc([0.0, 0.5]);
373 let right = Loc([1.0, 0.5]); 391 let right = Loc([1.0, 0.5]);
374 let down = Loc([0.5, 0.0]); 392 let down = Loc([0.5, 0.0]);
397 assert_eq!(pu.dist_to(&ao), 1.5); 415 assert_eq!(pu.dist_to(&ao), 1.5);
398 } 416 }
399 } 417 }
400 418
401 419
420 /// Tests that the conversions between the coordinate systems of each face is working correctly.
402 #[test] 421 #[test]
403 fn convert_adjacent() { 422 fn convert_adjacent() {
404 let point = Loc([0.4, 0.6]); 423 let point = Loc([0.4, 0.6]);
405 424
406 for f1 in Face::all() { 425 for f1 in Face::all() {
438 // } 457 // }
439 // } 458 // }
440 // } 459 // }
441 // } 460 // }
442 461
462 /// Tests that the logarithmic map is working correctly between adjacent faces.
443 #[test] 463 #[test]
444 fn log_adjacent() { 464 fn log_adjacent() {
445 let p1 = OnCube{ face : F1, point : Loc([0.5, 0.5])}; 465 let p1 = OnCube{ face : F1, point : Loc([0.5, 0.5])};
446 let p2 = OnCube{ face : F2, point : Loc([0.5, 0.5])}; 466 let p2 = OnCube{ face : F2, point : Loc([0.5, 0.5])};
447 467
448 assert_eq!(p1.log(&p2).norm(L2), 1.0); 468 assert_eq!(p1.log(&p2).norm(L2), 1.0);
449 } 469 }
450 470
471 /// Tests that the logarithmic map is working correctly between opposing faces.
451 #[test] 472 #[test]
452 fn log_opposing_equal() { 473 fn log_opposing_equal() {
453 let p1 = OnCube{ face : F1, point : Loc([0.5, 0.5])}; 474 let p1 = OnCube{ face : F1, point : Loc([0.5, 0.5])};
454 let p2 = OnCube{ face : F6, point : Loc([0.5, 0.5])}; 475 let p2 = OnCube{ face : F6, point : Loc([0.5, 0.5])};
455 476
456 assert_eq!(p1.log(&p2).norm(L2), 2.0); 477 assert_eq!(p1.log(&p2).norm(L2), 2.0);
457 } 478 }
458 479
480 /// Tests that the logarithmic map is working correctly between opposing faces when there
481 /// is a unique shortest geodesic.
459 #[test] 482 #[test]
460 fn log_opposing_unique_shortest() { 483 fn log_opposing_unique_shortest() {
461 let p1 = OnCube{ face : F1, point : Loc([0.3, 0.25])}; 484 let p1 = OnCube{ face : F1, point : Loc([0.3, 0.25])};
462 let p2 = OnCube{ face : F6, point : Loc([0.3, 0.25])}; 485 let p2 = OnCube{ face : F6, point : Loc([0.3, 0.25])};
463 486

mercurial