src/cylinder.rs

Fri, 28 Mar 2025 08:36:08 -0500

author
Tuomo Valkonen <tuomov@iki.fi>
date
Fri, 28 Mar 2025 08:36:08 -0500
changeset 59
743984f4664e
parent 56
34f8ec636368
permissions
-rw-r--r--

Add auxiliary results

37
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
1 /*!
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
2 Implementation of the surface of a 3D cylinder as a [`ManifoldPoint`].
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
3 */
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
4
56
34f8ec636368 Update to current alg_tools
Tuomo Valkonen <tuomov@iki.fi>
parents: 46
diff changeset
5 use alg_tools::euclidean::Euclidean;
37
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
6 use serde_repr::*;
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
7 use serde::{Serialize, Deserialize};
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
8 use alg_tools::loc::Loc;
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
9 use alg_tools::norms::{Norm, L2};
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
10 use alg_tools::types::Float;
56
34f8ec636368 Update to current alg_tools
Tuomo Valkonen <tuomov@iki.fi>
parents: 46
diff changeset
11 use alg_tools::impl_basic_space;
37
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
12 use crate::manifold::{ManifoldPoint, EmbeddedManifoldPoint, FacedManifoldPoint};
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
13 use crate::newton::{newton_sym1x1, newton_sym2x2};
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
14
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
15 /// Angle
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
16 pub type Angle = f64;
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
17
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
18 /// Cylindrical coordinates in ℝ^3
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
19 #[derive(Copy, Clone, Debug, PartialEq, Serialize, Deserialize)]
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
20 pub struct CylCoords {
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
21 pub r : f64,
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
22 pub angle : Angle,
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
23 pub z : f64
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
24 }
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
25
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
26 impl CylCoords {
46
90cc221eb52b More documentation
Tuomo Valkonen <tuomov@iki.fi>
parents: 41
diff changeset
27 /// Convert to cartesian coordinates.
37
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
28 #[inline]
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
29 pub fn to_cartesian(&self) -> Loc<f64, 3> {
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
30 let &CylCoords{r, angle, z} = self;
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
31 [r * angle.cos(), r * angle.sin(), z].into()
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
32 }
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
33
46
90cc221eb52b More documentation
Tuomo Valkonen <tuomov@iki.fi>
parents: 41
diff changeset
34 /// Form cylindrical coordinates from cartesian coordinates.
37
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
35 #[inline]
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
36 #[allow(dead_code)]
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
37 pub fn from_cartesian(coords : Loc<f64, 3>) -> Self {
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
38 let [x, y, z] = coords.into();
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
39 let r = (x*x + y*y).sqrt();
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
40 let angle = y.atan2(x);
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
41 CylCoords {r, angle, z}
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
42 }
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
43 }
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
44
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
45 /// Coordinates on a cap
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
46 #[derive(Copy, Clone, Debug, PartialEq, Serialize, Deserialize)]
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
47 pub struct CapPoint {
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
48 pub r : f64,
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
49 pub angle : Angle
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
50 }
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
51
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
52 impl CapPoint {
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
53 #[inline]
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
54 /// Convert to cylindrical coordinates given z coordinate
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
55 fn cyl_coords(&self, z : f64) -> CylCoords {
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
56 let CapPoint { r, angle } = *self;
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
57 CylCoords { r, angle, z }
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
58 }
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
59
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
60 #[inline]
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
61 /// Convert to cylindrical coordinates given z coordinate
38
63318d1b4f00 Fixes and unit tests for cylinder
Tuomo Valkonen <tuomov@iki.fi>
parents: 37
diff changeset
62 fn to_cartesian(&self) -> Loc<f64, 2> {
37
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
63 let CapPoint { r, angle } = *self;
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
64 [r * angle.cos(), r * angle.sin()].into()
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
65 }
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
66
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
67 #[inline]
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
68 #[allow(dead_code)]
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
69 /// Convert to cylindrical coordinates given z coordinate
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
70 fn from_cartesian(coords : Loc<f64, 2>) -> Self {
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
71 let [x, y] = coords.into();
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
72 let r = (x*x + y*y).sqrt();
38
63318d1b4f00 Fixes and unit tests for cylinder
Tuomo Valkonen <tuomov@iki.fi>
parents: 37
diff changeset
73 let angle = normalise_angle(y.atan2(x));
37
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
74 CapPoint { r, angle }
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
75 }
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
76
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
77 #[inline]
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
78 /// Calculate the vector between two points on the cap
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
79 fn log(&self, other : &CapPoint) -> Loc<f64, 2> {
38
63318d1b4f00 Fixes and unit tests for cylinder
Tuomo Valkonen <tuomov@iki.fi>
parents: 37
diff changeset
80 other.to_cartesian() - self.to_cartesian()
37
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
81 }
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
82
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
83 #[inline]
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
84 /// Calculate partial exponential map until boundary.
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
85 /// Returns the final point within the cap as well as a remaining tangent on
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
86 /// the side of the cylinder, if `t` wasn't fully used.
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
87 fn partial_exp(&self, r : f64, t : &Tangent) -> (CapPoint, Option<Tangent>) {
38
63318d1b4f00 Fixes and unit tests for cylinder
Tuomo Valkonen <tuomov@iki.fi>
parents: 37
diff changeset
88 // |p + s t| <= r
63318d1b4f00 Fixes and unit tests for cylinder
Tuomo Valkonen <tuomov@iki.fi>
parents: 37
diff changeset
89 // |p|^2 + s^2 |t|^2 + 2s<p,t> = r^2
63318d1b4f00 Fixes and unit tests for cylinder
Tuomo Valkonen <tuomov@iki.fi>
parents: 37
diff changeset
90 let p = self.to_cartesian();
63318d1b4f00 Fixes and unit tests for cylinder
Tuomo Valkonen <tuomov@iki.fi>
parents: 37
diff changeset
91 let np2 = p.norm2_squared();
63318d1b4f00 Fixes and unit tests for cylinder
Tuomo Valkonen <tuomov@iki.fi>
parents: 37
diff changeset
92 let nt2 = t.norm2_squared();
63318d1b4f00 Fixes and unit tests for cylinder
Tuomo Valkonen <tuomov@iki.fi>
parents: 37
diff changeset
93 let r2 = r * r;
63318d1b4f00 Fixes and unit tests for cylinder
Tuomo Valkonen <tuomov@iki.fi>
parents: 37
diff changeset
94 let d = p.dot(t);
39
3d5c8ea1522c assert tolerance
Tuomo Valkonen <tuomov@iki.fi>
parents: 38
diff changeset
95 assert!(np2 <= r2 + f64::EPSILON, "‖{p}‖ = {} > {r}", np2.sqrt());
38
63318d1b4f00 Fixes and unit tests for cylinder
Tuomo Valkonen <tuomov@iki.fi>
parents: 37
diff changeset
96 let s = (-d + (d*d + nt2 * (r2 - np2)).sqrt()) / nt2;
63318d1b4f00 Fixes and unit tests for cylinder
Tuomo Valkonen <tuomov@iki.fi>
parents: 37
diff changeset
97 if s < 1.0 {
63318d1b4f00 Fixes and unit tests for cylinder
Tuomo Valkonen <tuomov@iki.fi>
parents: 37
diff changeset
98 (Self::from_cartesian(p + s * t), Some((1.0-s) * t))
37
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
99 } else {
38
63318d1b4f00 Fixes and unit tests for cylinder
Tuomo Valkonen <tuomov@iki.fi>
parents: 37
diff changeset
100 (Self::from_cartesian(p + t), None)
37
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
101 }
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
102 }
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
103
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
104 #[inline]
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
105 /// Convert tangent from side tangent to cap tangent
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
106 fn tangent_from_side(&self, top : bool, t : Tangent) -> Tangent {
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
107 if top {
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
108 // The angle is such that down would be rotated to self.angle, counterclockwise
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
109 // The new tangent is R[down + t] - R[down] = Rt.
40
1d865db9d3e4 Move rotate and reflect to alg_tools
Tuomo Valkonen <tuomov@iki.fi>
parents: 39
diff changeset
110 t.rotate(self.angle+f64::PI/2.0)
37
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
111 } else {
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
112 // The angle is such that up would be rotated to self.angle, clockwise
40
1d865db9d3e4 Move rotate and reflect to alg_tools
Tuomo Valkonen <tuomov@iki.fi>
parents: 39
diff changeset
113 t.reflect_y().rotate(self.angle+f64::PI/2.0)
37
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
114 }
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
115 }
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
116
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
117 #[inline]
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
118 /// Convert tangent from cap tangent to tangent tangent
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
119 fn tangent_to_side(&self, top : bool, t : Tangent) -> Tangent {
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
120 if top {
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
121 // The angle is such that self.angle would be rotated to down, clockwise
40
1d865db9d3e4 Move rotate and reflect to alg_tools
Tuomo Valkonen <tuomov@iki.fi>
parents: 39
diff changeset
122 t.rotate(-self.angle-f64::PI/2.0)
37
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
123 } else {
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
124 // The angle is such that self.angle would be rotated to up, counterclockwise
40
1d865db9d3e4 Move rotate and reflect to alg_tools
Tuomo Valkonen <tuomov@iki.fi>
parents: 39
diff changeset
125 t.rotate(-self.angle-f64::PI/2.0).reflect_y()
37
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
126 }
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
127 }
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
128 }
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
129
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
130 /// Coordinates on a side
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
131 #[derive(Copy, Clone, Debug, PartialEq, Serialize, Deserialize)]
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
132 pub struct SidePoint {
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
133 pub z : f64,
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
134 pub angle : Angle
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
135 }
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
136
46
90cc221eb52b More documentation
Tuomo Valkonen <tuomov@iki.fi>
parents: 41
diff changeset
137 /// Calculates the difference between two angles, normalised to [–π, π].
37
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
138 #[inline]
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
139 fn anglediff(mut φ1 : f64, mut φ2 : f64) -> f64 {
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
140 let π = f64::PI;
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
141 φ1 = normalise_angle(φ1);
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
142 φ2 = normalise_angle(φ2);
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
143 let α = φ2 - φ1;
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
144 if α >= 0.0 {
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
145 if α <= π {
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
146 α
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
147 } else {
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
148 α - 2.0 * π
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
149 }
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
150 } else {
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
151 if α >= -π {
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
152 α
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
153 } else {
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
154 2.0 * π + α
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
155 }
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
156 }
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
157 }
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
158
46
90cc221eb52b More documentation
Tuomo Valkonen <tuomov@iki.fi>
parents: 41
diff changeset
159 /// Normalises an angle to [0, 2π].
37
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
160 #[inline]
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
161 pub fn normalise_angle(φ : f64) -> f64 {
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
162 let π = f64::PI;
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
163 φ.rem_euclid(2.0 * π)
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
164 }
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
165
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
166 impl SidePoint {
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
167 #[inline]
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
168 /// Convert to cylindrical coordinates given radius
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
169 fn cyl_coords(&self, r : f64) -> CylCoords {
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
170 let SidePoint { z, angle } = *self;
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
171 CylCoords { r, angle, z }
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
172 }
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
173
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
174 #[inline]
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
175 /// Calculate tangent vector between two points on the side, given radius
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
176 fn log(&self, r : f64, other : &SidePoint) -> Loc<f64, 2> {
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
177 let SidePoint{ z : z1, angle : angle1 } = *self;
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
178 let SidePoint{ z : z2, angle : angle2 } = *other;
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
179 let φ = anglediff(angle1, angle2);
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
180 // TODO: is this correct?
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
181 [r*φ, z2-z1].into()
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
182 }
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
183
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
184 #[inline]
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
185 /// Calculate partial exponential map under boundary
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
186 /// Returns a point on the next face, as well as a remaining tangent on
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
187 /// the side of the cylinder, if `t` wasn't fully used.
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
188 fn partial_exp(&self, r : f64, (a, b) : (f64, f64), t : &Tangent)
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
189 -> (SidePoint, Option<Tangent>)
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
190 {
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
191 assert!(a <= self.z && self.z <= b);
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
192 let Loc([_, h]) = *t;
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
193 let s = if h > 0.0 {
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
194 ((b - self.z)/h).min(1.0)
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
195 } else if h < 0.0 {
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
196 ((a - self.z)/h).min(1.0)
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
197 } else {
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
198 1.0
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
199 };
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
200 let d = t * s;
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
201 let p = self.unflatten(r, d);
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
202 if s < 1.0 {
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
203 (p, Some(t - d))
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
204 } else {
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
205 (p, None)
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
206 }
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
207 }
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
208
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
209 #[inline]
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
210 /// Unflattens another point in the local coordinate system of self
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
211 fn unflatten(&self, r : f64, Loc([v, h]) : Loc<f64, 2>) -> Self {
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
212 SidePoint{ z : self.z + h, angle : normalise_angle(self.angle + v / r) }
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
213 }
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
214
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
215 }
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
216
46
90cc221eb52b More documentation
Tuomo Valkonen <tuomov@iki.fi>
parents: 41
diff changeset
217 /// Point on some [`Cylinder`]
37
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
218 #[derive(Copy, Clone, Debug, PartialEq, Serialize, Deserialize)]
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
219 pub enum Point {
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
220 Top(CapPoint),
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
221 Bottom(CapPoint),
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
222 Side(SidePoint),
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
223 }
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
224
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
225 /// Face on a [`Cylinder`]
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
226 #[derive(Copy, Clone, Debug, Eq, PartialEq, Serialize_repr, Deserialize_repr)]
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
227 #[repr(u8)]
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
228 pub enum Face {
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
229 Top,
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
230 Bottom,
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
231 Side,
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
232 }
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
233
46
90cc221eb52b More documentation
Tuomo Valkonen <tuomov@iki.fi>
parents: 41
diff changeset
234 /// Point on a specific [`Cylinder`]
37
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
235 #[derive(Clone, Debug, PartialEq)]
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
236 pub struct OnCylinder<'a> {
46
90cc221eb52b More documentation
Tuomo Valkonen <tuomov@iki.fi>
parents: 41
diff changeset
237 /// Face and coordinates of the point
90cc221eb52b More documentation
Tuomo Valkonen <tuomov@iki.fi>
parents: 41
diff changeset
238 point : Point,
90cc221eb52b More documentation
Tuomo Valkonen <tuomov@iki.fi>
parents: 41
diff changeset
239 /// The specific cylinder the `point` lies on.
37
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
240 cylinder : &'a Cylinder,
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
241 }
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
242
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
243
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
244 /// Cylinder configuration
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
245 #[derive(Copy, Clone, Debug, PartialEq, Serialize, Deserialize)]
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
246 pub struct CylinderConfig {
46
90cc221eb52b More documentation
Tuomo Valkonen <tuomov@iki.fi>
parents: 41
diff changeset
247 /// Number of Newton iterates two take to solve geodesics.
37
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
248 pub newton_iters : usize,
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
249 }
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
250
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
251 impl Default for CylinderConfig {
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
252 fn default() -> Self {
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
253 CylinderConfig { newton_iters : 10 }
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
254 }
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
255 }
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
256
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
257 /// A cylinder
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
258 #[derive(Copy, Clone, Debug, PartialEq, Serialize, Deserialize)]
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
259 pub struct Cylinder {
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
260 /// Radius of the cylinder
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
261 pub radius : f64,
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
262 /// Height of the cylinder
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
263 pub height : f64,
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
264 /// Configuration for numerical methods
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
265 pub config : CylinderConfig
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
266 }
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
267
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
268
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
269 impl std::fmt::Display for Face {
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
270 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
271 use Face::*;
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
272 let s = match *self {
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
273 Top => "Top",
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
274 Bottom => "Bottom",
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
275 Side => "Side",
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
276 };
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
277 write!(f, "{}", s)
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
278 }
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
279 }
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
280
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
281 impl Point {
46
90cc221eb52b More documentation
Tuomo Valkonen <tuomov@iki.fi>
parents: 41
diff changeset
282 /// Returns the face of the point
37
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
283 fn face(&self) -> Face {
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
284 match *self {
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
285 Point::Top(..) => Face::Top,
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
286 Point::Bottom(_) => Face::Bottom,
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
287 Point::Side(_) => Face::Side,
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
288 }
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
289 }
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
290 }
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
291
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
292 impl<'a> FacedManifoldPoint for OnCylinder<'a> {
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
293 type Face = Face;
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
294 /// Returns the face of this point.
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
295 fn face(&self) -> Face {
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
296 self.point.face()
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
297 }
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
298 }
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
299
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
300 // Tangent vector
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
301 type Tangent = Loc<f64, 2>;
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
302
46
90cc221eb52b More documentation
Tuomo Valkonen <tuomov@iki.fi>
parents: 41
diff changeset
303 /// Goes through list of potential tangents (corresponding to several geodesics taking
90cc221eb52b More documentation
Tuomo Valkonen <tuomov@iki.fi>
parents: 41
diff changeset
304 /// different paths), and retuns the shortest tangent vector and the corresponding length.
37
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
305 #[inline]
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
306 fn best_tangent<I>(tangents : I) -> (Tangent, f64)
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
307 where I : IntoIterator<Item = Tangent> {
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
308 tangents.into_iter()
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
309 .map(|t| (t, t.norm(L2)))
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
310 .reduce(|a@(_, la), b@(_, lb)| if la < lb { a } else { b })
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
311 .unwrap()
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
312 }
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
313
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
314 /// Swap the elements of a two-tuple
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
315 #[inline]
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
316 fn swap<A>((a, b) : (A, A)) -> (A, A) {
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
317 (b, a)
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
318 }
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
319
46
90cc221eb52b More documentation
Tuomo Valkonen <tuomov@iki.fi>
parents: 41
diff changeset
320 /// Indicates whether the `a` and `b` are a distance of less than [`f64::EPSILON`].
37
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
321 #[inline]
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
322 fn indistinguishable(a : f64, b : f64) -> bool {
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
323 a > b - f64::EPSILON && a < b + f64::EPSILON
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
324 }
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
325
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
326 impl Cylinder {
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
327 /// Return the cylindrical coordinates of `point` on this cylinder
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
328 fn cyl_coords(&self, point : &Point) -> CylCoords {
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
329 match *point {
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
330 Point::Top(cap) => { cap.cyl_coords(self.top_z()) },
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
331 Point::Bottom(cap) => { cap.cyl_coords(self.bottom_z()) },
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
332 Point::Side(side) => { side.cyl_coords(self.radius) },
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
333 }
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
334 }
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
335
46
90cc221eb52b More documentation
Tuomo Valkonen <tuomov@iki.fi>
parents: 41
diff changeset
336 /// Returns the z coordinate of the top (cap) of the cylinder.
37
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
337 #[inline]
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
338 pub fn top_z(&self) -> f64 {
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
339 self.height / 2.0
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
340 }
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
341
46
90cc221eb52b More documentation
Tuomo Valkonen <tuomov@iki.fi>
parents: 41
diff changeset
342 /// Returns the z coordinate of the bottom (cap) of the cylinder.
37
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
343 #[inline]
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
344 pub fn bottom_z(&self) -> f64 {
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
345 -self.height / 2.0
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
346 }
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
347
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
348 /// Find angle where a geodesic from `side` to `(cap, z)` crosses the cap edge.
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
349 ///
46
90cc221eb52b More documentation
Tuomo Valkonen <tuomov@iki.fi>
parents: 41
diff changeset
350 /// Uses [`newton_sym1x1`].
37
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
351 fn side_cap_crossing(
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
352 &self,
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
353 side : &SidePoint,
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
354 cap : &CapPoint, z : f64, // `z` is the z coordinate of cap
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
355 ) -> Angle {
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
356 let &SidePoint { z : z_1, angle : φ_1 } = side;
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
357 let &CapPoint { r : r_2, angle : φ_2 } = cap;
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
358 assert_ne!(z, z_1);
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
359 let d_1 = z - z_1;
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
360 let d2_1 = d_1 * d_1;
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
361 let r = self.radius;
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
362 let r2 = r * r;
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
363 let r2_2 = r_2 * r_2;
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
364 let rr_2 = r * r_2;
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
365
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
366 let g = |α_1 : f64| {
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
367 let ψ = φ_2 - φ_1 - α_1;
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
368 let ψ_cos = ψ.cos();
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
369 let ψ_sin = ψ.sin();
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
370 let ψ_sin2 = ψ_sin * ψ_sin;
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
371 let ψ_cos2 = ψ_cos * ψ_cos;
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
372 let α2_1 = α_1 * α_1;
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
373 let c = d2_1 + r2 * α2_1;
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
374 let e = r2 + r2_2 - 2.0 * rr_2 * ψ_cos;
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
375 let g = r2 * α_1 / c.sqrt() - rr_2 * ψ_sin / e.sqrt();
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
376 let h = r2 * d2_1 / c.powf(3.0/2.0)
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
377 + r * r_2 * ((r2 + r2_2) * ψ_cos - rr_2 * (ψ_sin2 - 2.0 * ψ_cos2))
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
378 / e.powf(3.0/2.0);
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
379 (h, g)
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
380 };
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
381
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
382 let α_1 = newton_sym1x1(g, 0.0, self.config.newton_iters);
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
383 normalise_angle(φ_1 + α_1)
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
384
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
385 }
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
386
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
387 /// Find angles where the geodesic passing through a cap at height `z` from `side1` to `side2`
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
388 /// crosses the cap edge. **Panics if `side2.angle < side1.angle`.**
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
389 ///
46
90cc221eb52b More documentation
Tuomo Valkonen <tuomov@iki.fi>
parents: 41
diff changeset
390 /// Uses [`newton_sym2x2`].
37
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
391 fn side_cap_side_crossing(
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
392 &self,
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
393 side1 : &SidePoint,
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
394 z : f64,
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
395 side2 : &SidePoint
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
396 ) -> (Angle, Angle) {
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
397 let &SidePoint { z : z_1, angle : φ_1 } = side1;
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
398 let &SidePoint { z : z_2, angle : φ_2 } = side2;
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
399 assert!(φ_2 >= φ_1);
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
400 assert_ne!(z_1, z);
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
401 assert_ne!(z_2, z);
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
402 let r = self.radius;
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
403 let r2 = r * r;
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
404 let d_1 = z - z_1;
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
405 let d_2 = z - z_2;
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
406 let d2_1 = d_1 * d_1;
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
407 let d2_2 = d_2 * d_2;
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
408 let g = |α_1 : f64, α_2 : f64| {
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
409 let α2_1 = α_1 * α_1;
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
410 let α2_2 = α_2 * α_2;
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
411 let ψ = (α_1 + α_2 + φ_1 - φ_2) / 2.0;
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
412 let ψ_sin = ψ.sin();
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
413 let ψ_cos = ψ.cos();
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
414 let c_1 = d2_1 + r2 * α2_1;
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
415 let c_2 = d2_2 + r2 * α2_2;
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
416 let g_1 = r2 * α_1 / c_1.sqrt() - r * ψ_cos;
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
417 let g_2 = r2 * α_2 / c_2.sqrt() - r * ψ_cos;
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
418 let h_12 = (r / 2.0) * ψ_sin;
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
419 let h_11 = r2 * d2_1 / c_1.powf(3.0 / 2.0) + h_12;
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
420 let h_22 = r2 * d2_2 / c_2.powf(3.0 / 2.0) + h_12;
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
421 ([h_11, h_12, h_22], [g_1, g_2])
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
422 };
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
423
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
424 let [α_1, α_2] = newton_sym2x2(g, [0.0, 0.0], self.config.newton_iters);
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
425 (normalise_angle(φ_1 + α_1), normalise_angle(φ_2 + α_2))
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
426
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
427 }
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
428
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
429 /// Find angles where the geodesic passing through the side from `cap1` at height `z_1`
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
430 /// to `cap2` at height `z_2` crosses the cap edges.
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
431 /// **Panics if `cap2.angle < cap1.angle`.**
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
432 ///
46
90cc221eb52b More documentation
Tuomo Valkonen <tuomov@iki.fi>
parents: 41
diff changeset
433 /// Uses [`newton_sym2x2`].
37
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
434 fn cap_side_cap_crossing(
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
435 &self,
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
436 cap1 : &CapPoint, z_1 : f64,
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
437 cap2 : &CapPoint, z_2 : f64,
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
438 init_by_cap2 : bool
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
439 ) -> (Angle, Angle) {
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
440 let r = self.radius;
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
441 let &CapPoint { r : r_1, angle : φ_1 } = cap1;
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
442 let &CapPoint { r : r_2, angle : φ_2 } = cap2;
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
443 assert!(φ_2 >= φ_1);
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
444 assert_ne!(r_1, r);
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
445 assert_ne!(r_2, r);
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
446 assert_ne!(z_2, z_1);
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
447 if r_1 == 0.0 && r_2 == 0.0 {
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
448 // Singular case: both points are in the middle of the caps.
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
449 return (φ_1, φ_1)
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
450 }
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
451 let r2 = r * r;
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
452 let d = (z_2 - z_1).abs();
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
453 let d2 = d * d;
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
454 let r2_1 = r_1 * r_1;
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
455 let r2_2 = r_2 * r_2;
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
456 let rr_1 = r * r_1;
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
457 let rr_2 = r * r_2;
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
458 let f = |α_1 : f64, α_2 : f64| {
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
459 let cos_α1 = α_1.cos();
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
460 let sin_α1 = α_1.sin();
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
461 let cos_α2 = α_2.cos();
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
462 let sin_α2 = α_2.sin();
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
463 //let cos2_α1 = cos_α1 * cos_α1;
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
464 let sin2_α1 = sin_α1 * sin_α1;
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
465 //let cos2_α2 = cos_α2 * cos_α2;
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
466 let sin2_α2 = sin_α2 * sin_α2;
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
467 let ψ = φ_2 - φ_1 - α_1 - α_2;
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
468 let ψ2 = ψ * ψ;
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
469 let ψ2r2 = ψ2 * r2;
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
470 //let r4 = r2 * r2;
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
471 let b = d2 + ψ2r2;
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
472 let c = r2 * ψ / b.sqrt();
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
473 let e_1 = r2 + r2_1 - 2.0 * rr_1 * cos_α1;
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
474 let e_2 = r2 + r2_2 - 2.0 * rr_2 * cos_α2;
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
475 let g_1 = rr_1 * sin_α1 / e_1.sqrt() - c;
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
476 let g_2 = rr_2 * sin_α2 / e_2.sqrt() - c;
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
477 let h_12 = r2 * (1.0 - ψ2r2 / b) / b.sqrt();
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
478 // let h_11 = rr_1 * ( (r2 + r2_1) * cos_α1 - rr_1 * ( sin2_α1 + 2.0 * cos2_α1) )
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
479 // / e_1.powf(3.0/2.0) + h_12;
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
480 // let h_22 = rr_2 * ( (r2 + r2_2) * cos_α2 - rr_2 * ( sin2_α2 + 2.0 * cos2_α2) )
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
481 // / e_2.powf(3.0/2.0) + h_12;
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
482 // let h_11 = rr_1 * cos_α1 / e_1.sqrt() - rr_1*rr_1 * sin2_α1 / e_1.powf(3.0/2.0) + h_12;
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
483 // let h_22 = rr_2 * cos_α2 / e_2.sqrt() - rr_2*rr_2 * sin2_α2 / e_2.powf(3.0/2.0) + h_12;
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
484 let h_11 = rr_1 * (cos_α1 - rr_1 * sin2_α1 / e_1) / e_1.sqrt() + h_12;
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
485 let h_22 = rr_2 * (cos_α2 - rr_2 * sin2_α2 / e_2) / e_2.sqrt() + h_12;
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
486 ([h_11, h_12, h_22], [g_1, g_2])
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
487 };
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
488
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
489 let α_init = if init_by_cap2 {
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
490 [φ_2 - φ_1, 0.0]
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
491 } else {
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
492 [0.0, φ_2 - φ_1]
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
493 };
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
494 let [α_1, α_2] = newton_sym2x2(f, α_init, self.config.newton_iters);
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
495 (normalise_angle(φ_1 + α_1), normalise_angle(φ_2 - α_2))
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
496 }
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
497
46
90cc221eb52b More documentation
Tuomo Valkonen <tuomov@iki.fi>
parents: 41
diff changeset
498 /// Calculates the log between points on a `cap` and a `side` of the cylinder, in this direction.
90cc221eb52b More documentation
Tuomo Valkonen <tuomov@iki.fi>
parents: 41
diff changeset
499 /// The `z` coordinate of the cap and an indication whether it is a `top` or bottom cap must
90cc221eb52b More documentation
Tuomo Valkonen <tuomov@iki.fi>
parents: 41
diff changeset
500 /// also be given.
37
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
501 fn cap_side_log(
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
502 &self,
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
503 cap : &CapPoint, (z, top) : (f64, bool),
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
504 side : &SidePoint
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
505 ) -> Tangent {
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
506 let r = self.radius;
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
507 if indistinguishable(side.z, z) {
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
508 // Degenerate case
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
509 let capedge = CapPoint{ angle : side.angle, r };
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
510 cap.log(&capedge)
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
511 } else if indistinguishable(r, cap.r)
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
512 && anglediff(side.angle, cap.angle).abs() < f64::PI/2.0 {
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
513 // Degenerate case
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
514 let sideedge = SidePoint{ angle : cap.angle, z};
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
515 cap.tangent_from_side(top, sideedge.log(r, side))
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
516 } else {
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
517 let φ = self.side_cap_crossing(side, cap, z);
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
518 let capedge = CapPoint{ angle : φ, r };
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
519 let sideedge = SidePoint{ angle : φ, z };
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
520 let t1 = cap.log(&capedge);
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
521 let t2 = sideedge.log(r, side);
41
56d609b70a3b Cylinder numerical stability hacks
Tuomo Valkonen <tuomov@iki.fi>
parents: 40
diff changeset
522 // Either option should give the same result.
56d609b70a3b Cylinder numerical stability hacks
Tuomo Valkonen <tuomov@iki.fi>
parents: 40
diff changeset
523 // The first one avoids division, but seems numerically more unstable due to
56d609b70a3b Cylinder numerical stability hacks
Tuomo Valkonen <tuomov@iki.fi>
parents: 40
diff changeset
524 // sines and cosines.
56d609b70a3b Cylinder numerical stability hacks
Tuomo Valkonen <tuomov@iki.fi>
parents: 40
diff changeset
525 //t1 + capedge.tangent_from_side(top, t2)
56d609b70a3b Cylinder numerical stability hacks
Tuomo Valkonen <tuomov@iki.fi>
parents: 40
diff changeset
526 let n = t1.norm(L2);
56d609b70a3b Cylinder numerical stability hacks
Tuomo Valkonen <tuomov@iki.fi>
parents: 40
diff changeset
527 if n < f64::EPSILON {
56d609b70a3b Cylinder numerical stability hacks
Tuomo Valkonen <tuomov@iki.fi>
parents: 40
diff changeset
528 capedge.tangent_from_side(top, t2)
56d609b70a3b Cylinder numerical stability hacks
Tuomo Valkonen <tuomov@iki.fi>
parents: 40
diff changeset
529 } else {
56d609b70a3b Cylinder numerical stability hacks
Tuomo Valkonen <tuomov@iki.fi>
parents: 40
diff changeset
530 (t1/n)*(n + t2.norm(L2))
56d609b70a3b Cylinder numerical stability hacks
Tuomo Valkonen <tuomov@iki.fi>
parents: 40
diff changeset
531 }
37
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
532 }
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
533 }
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
534
46
90cc221eb52b More documentation
Tuomo Valkonen <tuomov@iki.fi>
parents: 41
diff changeset
535 /// Calculates the log between points on a `side` and a `cap` of the cylinder, in this direction.
90cc221eb52b More documentation
Tuomo Valkonen <tuomov@iki.fi>
parents: 41
diff changeset
536 /// The `z` coordinate of the cap and an indication whether it is a `top` or bottom cap must
90cc221eb52b More documentation
Tuomo Valkonen <tuomov@iki.fi>
parents: 41
diff changeset
537 /// also be given.
37
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
538 fn side_cap_log(
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
539 &self,
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
540 side : &SidePoint,
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
541 cap : &CapPoint, (z, top) : (f64, bool),
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
542 ) -> Tangent {
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
543 let r = self.radius;
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
544 if indistinguishable(side.z, z) {
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
545 // Degenerate case
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
546 let capedge = CapPoint{ angle : side.angle, r };
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
547 capedge.tangent_to_side(top, capedge.log(cap))
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
548 } else if indistinguishable(r, cap.r)
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
549 && anglediff(side.angle, cap.angle).abs() < f64::PI/2.0 {
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
550 // Degenerate case
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
551 side.log(r, &SidePoint{ z, angle : cap.angle })
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
552 } else {
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
553 let φ = self.side_cap_crossing(side, cap, z);
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
554 let capedge = CapPoint{ angle : φ, r };
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
555 let sideedge = SidePoint{ angle : φ, z };
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
556 let t1 = side.log(r, &sideedge);
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
557 let t2 = capedge.log(cap);
41
56d609b70a3b Cylinder numerical stability hacks
Tuomo Valkonen <tuomov@iki.fi>
parents: 40
diff changeset
558 // Either option should give the same result.
56d609b70a3b Cylinder numerical stability hacks
Tuomo Valkonen <tuomov@iki.fi>
parents: 40
diff changeset
559 // The first one avoids division, but seems numerically more unstable due to
56d609b70a3b Cylinder numerical stability hacks
Tuomo Valkonen <tuomov@iki.fi>
parents: 40
diff changeset
560 // sines and cosines.
56d609b70a3b Cylinder numerical stability hacks
Tuomo Valkonen <tuomov@iki.fi>
parents: 40
diff changeset
561 // t1 + capedge.tangent_to_side(top, t2)
56d609b70a3b Cylinder numerical stability hacks
Tuomo Valkonen <tuomov@iki.fi>
parents: 40
diff changeset
562 let n = t1.norm(L2);
56d609b70a3b Cylinder numerical stability hacks
Tuomo Valkonen <tuomov@iki.fi>
parents: 40
diff changeset
563 if n < f64::EPSILON {
56d609b70a3b Cylinder numerical stability hacks
Tuomo Valkonen <tuomov@iki.fi>
parents: 40
diff changeset
564 capedge.tangent_to_side(top, t2)
56d609b70a3b Cylinder numerical stability hacks
Tuomo Valkonen <tuomov@iki.fi>
parents: 40
diff changeset
565 } else {
56d609b70a3b Cylinder numerical stability hacks
Tuomo Valkonen <tuomov@iki.fi>
parents: 40
diff changeset
566 (t1/n)*(n + t2.norm(L2))
56d609b70a3b Cylinder numerical stability hacks
Tuomo Valkonen <tuomov@iki.fi>
parents: 40
diff changeset
567 }
37
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
568 }
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
569 }
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
570
46
90cc221eb52b More documentation
Tuomo Valkonen <tuomov@iki.fi>
parents: 41
diff changeset
571 /// Calculates the log between points on two sides of the cylinder, assuming the corresonding
90cc221eb52b More documentation
Tuomo Valkonen <tuomov@iki.fi>
parents: 41
diff changeset
572 /// geodesic crosses a cap at height `z`. The `top` parameter indicates whether this is a
90cc221eb52b More documentation
Tuomo Valkonen <tuomov@iki.fi>
parents: 41
diff changeset
573 /// top cap.
37
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
574 fn side_cap_side_log(
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
575 &self,
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
576 side1 : &SidePoint,
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
577 (z, top) : (f64, bool),
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
578 side2 : &SidePoint
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
579 ) -> Tangent {
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
580 let r = self.radius;
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
581 if indistinguishable(side1.z, z) {
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
582 // Degenerate case
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
583 let capedge1 = CapPoint{ angle : side1.angle, r };
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
584 capedge1.tangent_to_side(top, self.cap_side_log(&capedge1, (z, top), side2))
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
585 } else if indistinguishable(side2.z, z) {
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
586 // Degenerate case
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
587 let capedge2 = CapPoint{ angle : side2.angle, r };
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
588 self.side_cap_log(side1, &capedge2, (z, top))
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
589 } else {
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
590 let (φ1, φ2) = if side2.angle >= side1.angle {
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
591 self.side_cap_side_crossing(side1, z, side2)
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
592 } else {
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
593 swap(self.side_cap_side_crossing(side2, z, side1))
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
594 };
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
595 let capedge1 = CapPoint{ angle : φ1, r };
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
596 let sideedge1 = SidePoint{ angle : φ1, z };
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
597 let capedge2 = CapPoint{ angle : φ2, r };
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
598 let sideedge2 = SidePoint{ angle : φ2, z };
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
599 let t1 = side1.log(r, &sideedge1);
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
600 let t2 = capedge1.log(&capedge2);
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
601 let t3 = sideedge2.log(r, &side2);
41
56d609b70a3b Cylinder numerical stability hacks
Tuomo Valkonen <tuomov@iki.fi>
parents: 40
diff changeset
602 // Either option should give the same result.
56d609b70a3b Cylinder numerical stability hacks
Tuomo Valkonen <tuomov@iki.fi>
parents: 40
diff changeset
603 // The first one avoids division, but seems numerically more unstable due to
56d609b70a3b Cylinder numerical stability hacks
Tuomo Valkonen <tuomov@iki.fi>
parents: 40
diff changeset
604 // sines and cosines.
37
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
605 //
41
56d609b70a3b Cylinder numerical stability hacks
Tuomo Valkonen <tuomov@iki.fi>
parents: 40
diff changeset
606 // t1 + capedge1.tangent_to_side(top, t2 + capedge2.tangent_from_side(top, t3))
37
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
607 let n = t1.norm(L2);
41
56d609b70a3b Cylinder numerical stability hacks
Tuomo Valkonen <tuomov@iki.fi>
parents: 40
diff changeset
608 if n < f64::EPSILON {
56d609b70a3b Cylinder numerical stability hacks
Tuomo Valkonen <tuomov@iki.fi>
parents: 40
diff changeset
609 let n2 = t2.norm(L2);
56d609b70a3b Cylinder numerical stability hacks
Tuomo Valkonen <tuomov@iki.fi>
parents: 40
diff changeset
610 capedge1.tangent_to_side(top,
56d609b70a3b Cylinder numerical stability hacks
Tuomo Valkonen <tuomov@iki.fi>
parents: 40
diff changeset
611 if n2 < f64::EPSILON {
56d609b70a3b Cylinder numerical stability hacks
Tuomo Valkonen <tuomov@iki.fi>
parents: 40
diff changeset
612 capedge2.tangent_from_side(top, t3)
56d609b70a3b Cylinder numerical stability hacks
Tuomo Valkonen <tuomov@iki.fi>
parents: 40
diff changeset
613 } else {
56d609b70a3b Cylinder numerical stability hacks
Tuomo Valkonen <tuomov@iki.fi>
parents: 40
diff changeset
614 (t2/n2)*(n2 + t3.norm(L2))
56d609b70a3b Cylinder numerical stability hacks
Tuomo Valkonen <tuomov@iki.fi>
parents: 40
diff changeset
615 }
56d609b70a3b Cylinder numerical stability hacks
Tuomo Valkonen <tuomov@iki.fi>
parents: 40
diff changeset
616 )
56d609b70a3b Cylinder numerical stability hacks
Tuomo Valkonen <tuomov@iki.fi>
parents: 40
diff changeset
617 } else {
56d609b70a3b Cylinder numerical stability hacks
Tuomo Valkonen <tuomov@iki.fi>
parents: 40
diff changeset
618 (t1/n)*(n + t2.norm(L2) + t3.norm(L2))
56d609b70a3b Cylinder numerical stability hacks
Tuomo Valkonen <tuomov@iki.fi>
parents: 40
diff changeset
619 }
37
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
620 }
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
621 }
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
622
46
90cc221eb52b More documentation
Tuomo Valkonen <tuomov@iki.fi>
parents: 41
diff changeset
623 /// Calculates the log between points on two caps of the cylinder, assuming the corresonding
90cc221eb52b More documentation
Tuomo Valkonen <tuomov@iki.fi>
parents: 41
diff changeset
624 /// geodesic crosses the side. The heights of the caps and indications whether they are
90cc221eb52b More documentation
Tuomo Valkonen <tuomov@iki.fi>
parents: 41
diff changeset
625 /// top caps, must also be given.
37
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
626 fn cap_side_cap_log(
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
627 &self,
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
628 cap1 : &CapPoint, (z1, top1) : (f64, bool),
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
629 cap2 : &CapPoint, (z2, top2) : (f64, bool),
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
630 init_by_cap2 : bool,
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
631 ) -> Tangent {
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
632 let r = self.radius;
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
633 if indistinguishable(cap1.r, r) {
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
634 // Degenerate case
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
635 let sideedge1 = SidePoint{ angle : cap1.angle, z : z1 };
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
636 cap1.tangent_from_side(top1, self.side_cap_log(&sideedge1, cap2, (z2, top2)))
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
637 } else if indistinguishable(cap2.r, r) {
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
638 // Degenerate case
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
639 let sideedge2 = SidePoint{ angle : cap2.angle, z : z2 };
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
640 self.cap_side_log(cap1, (z1, top1), &sideedge2)
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
641 } else {
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
642 let (φ1, φ2) = if cap2.angle >= cap1.angle {
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
643 self.cap_side_cap_crossing(cap1, z1, cap2, z2, init_by_cap2)
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
644 } else {
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
645 swap(self.cap_side_cap_crossing(cap2, z2, cap1, z1, !init_by_cap2))
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
646 };
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
647 let sideedge1 = SidePoint{ angle : φ1, z : z1 };
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
648 let capedge1 = CapPoint{ angle : φ1, r };
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
649 let sideedge2 = SidePoint{ angle : φ2, z : z2};
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
650 let capedge2 = CapPoint{ angle : φ2, r };
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
651 let t1 = cap1.log(&capedge1);
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
652 let t2 = sideedge1.log(r, &sideedge2);
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
653 let t3 = capedge2.log(cap2);
41
56d609b70a3b Cylinder numerical stability hacks
Tuomo Valkonen <tuomov@iki.fi>
parents: 40
diff changeset
654 // Either option should give the same result.
56d609b70a3b Cylinder numerical stability hacks
Tuomo Valkonen <tuomov@iki.fi>
parents: 40
diff changeset
655 // The first one avoids division, but seems numerically more unstable due to
56d609b70a3b Cylinder numerical stability hacks
Tuomo Valkonen <tuomov@iki.fi>
parents: 40
diff changeset
656 // sines and cosines.
56d609b70a3b Cylinder numerical stability hacks
Tuomo Valkonen <tuomov@iki.fi>
parents: 40
diff changeset
657 // t1 + capedge1.tangent_from_side(top1, t2 + capedge2.tangent_to_side(top2, t3))
56d609b70a3b Cylinder numerical stability hacks
Tuomo Valkonen <tuomov@iki.fi>
parents: 40
diff changeset
658 let n = t1.norm(L2);
56d609b70a3b Cylinder numerical stability hacks
Tuomo Valkonen <tuomov@iki.fi>
parents: 40
diff changeset
659 if n < f64::EPSILON {
56d609b70a3b Cylinder numerical stability hacks
Tuomo Valkonen <tuomov@iki.fi>
parents: 40
diff changeset
660 let n2 = t2.norm(L2);
56d609b70a3b Cylinder numerical stability hacks
Tuomo Valkonen <tuomov@iki.fi>
parents: 40
diff changeset
661 capedge1.tangent_from_side(top1,
56d609b70a3b Cylinder numerical stability hacks
Tuomo Valkonen <tuomov@iki.fi>
parents: 40
diff changeset
662 if n2 < f64::EPSILON {
56d609b70a3b Cylinder numerical stability hacks
Tuomo Valkonen <tuomov@iki.fi>
parents: 40
diff changeset
663 capedge2.tangent_to_side(top2, t3)
56d609b70a3b Cylinder numerical stability hacks
Tuomo Valkonen <tuomov@iki.fi>
parents: 40
diff changeset
664 } else {
56d609b70a3b Cylinder numerical stability hacks
Tuomo Valkonen <tuomov@iki.fi>
parents: 40
diff changeset
665 (t2/n2)*(n2 + t3.norm(L2))
56d609b70a3b Cylinder numerical stability hacks
Tuomo Valkonen <tuomov@iki.fi>
parents: 40
diff changeset
666 }
56d609b70a3b Cylinder numerical stability hacks
Tuomo Valkonen <tuomov@iki.fi>
parents: 40
diff changeset
667 )
56d609b70a3b Cylinder numerical stability hacks
Tuomo Valkonen <tuomov@iki.fi>
parents: 40
diff changeset
668 } else {
56d609b70a3b Cylinder numerical stability hacks
Tuomo Valkonen <tuomov@iki.fi>
parents: 40
diff changeset
669 (t1/n)*(n + t2.norm(L2) + t3.norm(L2))
56d609b70a3b Cylinder numerical stability hacks
Tuomo Valkonen <tuomov@iki.fi>
parents: 40
diff changeset
670 }
37
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
671 }
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
672 }
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
673
46
90cc221eb52b More documentation
Tuomo Valkonen <tuomov@iki.fi>
parents: 41
diff changeset
674 /// Calculates both the logarithmic map and distance between two points.
37
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
675 fn log_dist(&self, source : &Point, destination : &Point) -> (Tangent, f64) {
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
676 use Point::*;
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
677 match (source, destination) {
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
678 (Top(cap1), Top(cap2)) => {
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
679 best_tangent([cap1.log(cap2)])
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
680 },
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
681 (Bottom(cap1), Bottom(cap2)) => {
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
682 best_tangent([cap1.log(cap2)])
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
683 },
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
684 (Bottom(cap), Side(side)) => {
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
685 best_tangent([self.cap_side_log(cap, (self.bottom_z(), false), side)])
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
686 },
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
687 (Top(cap), Side(side)) => {
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
688 best_tangent([self.cap_side_log(cap, (self.top_z(), true), side)])
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
689 },
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
690 (Side(side), Bottom(cap)) => {
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
691 best_tangent([self.side_cap_log(side, cap, (self.bottom_z(), false))])
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
692 },
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
693 (Side(side), Top(cap)) => {
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
694 best_tangent([self.side_cap_log(side, cap, (self.top_z(), true))])
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
695 },
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
696 (Side(side1), Side(side2)) => {
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
697 best_tangent([
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
698 side1.log(self.radius, side2),
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
699 self.side_cap_side_log(side1, (self.top_z(), true), side2),
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
700 self.side_cap_side_log(side1, (self.bottom_z(), false), side2),
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
701 ])
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
702 },
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
703 (Top(cap1), Bottom(cap2)) => {
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
704 best_tangent([
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
705 // We try a few possible initialisations for Newton
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
706 self.cap_side_cap_log(
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
707 cap1, (self.top_z(), true),
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
708 cap2, (self.bottom_z(), false),
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
709 false
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
710 ),
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
711 self.cap_side_cap_log(
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
712 cap1, (self.top_z(), true),
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
713 cap2, (self.bottom_z(), false),
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
714 true
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
715 ),
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
716 ])
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
717 },
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
718 (Bottom(cap1), Top(cap2)) => {
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
719 best_tangent([
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
720 // We try a few possible initialisations for Newton
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
721 self.cap_side_cap_log(
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
722 cap1, (self.bottom_z(), false),
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
723 cap2, (self.top_z(), true),
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
724 false
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
725 ),
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
726 self.cap_side_cap_log(
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
727 cap1, (self.bottom_z(), false),
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
728 cap2, (self.top_z(), true),
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
729 true
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
730 ),
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
731 ])
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
732 },
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
733 }
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
734 }
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
735
46
90cc221eb52b More documentation
Tuomo Valkonen <tuomov@iki.fi>
parents: 41
diff changeset
736 /// Calculates the exponential map of `point` in the direction `t` until the next edge.
90cc221eb52b More documentation
Tuomo Valkonen <tuomov@iki.fi>
parents: 41
diff changeset
737 /// If `t` was fully exhausted before reaching an edge, the second return value is [`None`],
90cc221eb52b More documentation
Tuomo Valkonen <tuomov@iki.fi>
parents: 41
diff changeset
738 /// otherwise it is a [`Some`] of the remaining tangent, translated at the returned point.
37
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
739 #[allow(unreachable_code)]
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
740 #[allow(unused_variables)]
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
741 fn partial_exp(&self, point : Point, t : Tangent) -> (Point, Option<Tangent>) {
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
742 match point {
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
743 Point::Top(cap) => {
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
744 let (cap_new, t_new_basis) = cap.partial_exp(self.radius, &t);
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
745 match t_new_basis {
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
746 None => (Point::Top(cap_new), None),
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
747 Some(t_new) => {
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
748 let side_new = SidePoint{ angle : cap_new.angle, z : self.top_z() };
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
749 (Point::Side(side_new), Some(cap_new.tangent_to_side(true, t_new)))
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
750 }
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
751 }
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
752 },
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
753 Point::Bottom(cap) => {
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
754 let (cap_new, t_new_basis) = cap.partial_exp(self.radius, &t);
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
755 match t_new_basis {
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
756 None => (Point::Bottom(cap_new), None),
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
757 Some(t_new) => {
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
758 let side_new = SidePoint{ angle : cap_new.angle, z : self.bottom_z() };
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
759 (Point::Side(side_new), Some(cap_new.tangent_to_side(false, t_new)))
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
760 }
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
761 }
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
762 },
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
763 Point::Side(side) => {
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
764 let lims = (self.bottom_z(), self.top_z());
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
765 let (side_new, t_new_basis) = side.partial_exp(self.radius, lims, &t);
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
766 match t_new_basis {
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
767 None => (Point::Side(side_new), None),
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
768 Some(t_new) => {
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
769 if side_new.z >= self.top_z() - f64::EPSILON {
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
770 let cap_new = CapPoint { angle : side_new.angle, r : self.radius };
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
771 (Point::Top(cap_new), Some(cap_new.tangent_from_side(true, t_new)))
38
63318d1b4f00 Fixes and unit tests for cylinder
Tuomo Valkonen <tuomov@iki.fi>
parents: 37
diff changeset
772 } else if side_new.z <= self.bottom_z() + f64::EPSILON {
37
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
773 let cap_new = CapPoint { angle : side_new.angle, r : self.radius };
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
774 (Point::Bottom(cap_new), Some(cap_new.tangent_from_side(false, t_new)))
38
63318d1b4f00 Fixes and unit tests for cylinder
Tuomo Valkonen <tuomov@iki.fi>
parents: 37
diff changeset
775 } else {
63318d1b4f00 Fixes and unit tests for cylinder
Tuomo Valkonen <tuomov@iki.fi>
parents: 37
diff changeset
776 (Point::Side(side_new), None)
37
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
777 }
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
778 }
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
779 }
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
780 }
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
781 }
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
782 }
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
783
46
90cc221eb52b More documentation
Tuomo Valkonen <tuomov@iki.fi>
parents: 41
diff changeset
784 /// Calculates the exponential map from `point` in the direction of `tangent`.
37
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
785 fn exp(&self, point : &Point, tangent : &Tangent) -> Point {
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
786 let mut p = *point;
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
787 let mut t = *tangent;
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
788 loop {
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
789 (p, t) = match self.partial_exp(p, t) {
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
790 (p, None) => break p,
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
791 (p, Some(t)) => (p, t),
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
792 };
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
793 }
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
794 }
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
795
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
796 /// Check that `point` has valid coordinates, and normalise angles
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
797 pub fn normalise(&self, point : Point) -> Option<Point> {
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
798 match point {
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
799 Point::Side(side) => {
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
800 let a = self.bottom_z();
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
801 let b = self.top_z();
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
802 (a <= side.z && side.z <= b).then(|| {
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
803 Point::Side(SidePoint{ angle : normalise_angle(side.angle), .. side })
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
804 })
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
805 },
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
806 Point::Bottom(cap) => {
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
807 (cap.r <= self.radius).then(|| {
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
808 Point::Bottom(CapPoint{ angle : normalise_angle(cap.angle), .. cap })
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
809 })
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
810 },
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
811 Point::Top(cap) => {
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
812 (cap.r <= self.radius).then(|| {
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
813 Point::Top(CapPoint{ angle : normalise_angle(cap.angle), .. cap })
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
814 })
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
815 },
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
816 }
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
817 }
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
818
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
819 /// Convert `p` into a a point associated with the cylinder.
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
820 ///
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
821 /// May panic if the coordinates are invalid.
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
822 pub fn point_on(&self, point : Point) -> OnCylinder<'_> {
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
823 match self.normalise(point) {
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
824 None => panic!("{point:?} not on cylinder {self:?}"),
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
825 Some(point) => OnCylinder { cylinder : self, point }
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
826 }
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
827 }
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
828
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
829 /// Convert `p` into a a point on side associated with the cylinder.
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
830 ///
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
831 /// May panic if the coordinates are invalid.
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
832 pub fn point_on_side(&self, side : SidePoint) -> OnCylinder<'_> {
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
833 self.point_on(Point::Side(side))
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
834 }
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
835
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
836 /// Convert `p` into a a point on top associated with the cylinder.
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
837 ///
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
838 /// May panic if the coordinates are invalid.
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
839 pub fn point_on_top(&self, cap : CapPoint) -> OnCylinder<'_> {
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
840 self.point_on(Point::Top(cap))
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
841 }
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
842
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
843 /// Convert `p` into a a point on bottom associated with the cylinder.
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
844 ///
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
845 /// May panic if the coordinates are invalid.
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
846 pub fn point_on_bottom(&self, cap : CapPoint) -> OnCylinder<'_> {
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
847 self.point_on(Point::Bottom(cap))
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
848 }
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
849
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
850 /// Convert `p` into a a point on side associated with the cylinder.
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
851 ///
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
852 /// May panic if the coordinates are invalid.
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
853 pub fn on_side(&self, angle : Angle, z : f64) -> OnCylinder<'_> {
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
854 self.point_on_side(SidePoint{ angle, z })
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
855 }
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
856
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
857 /// Convert `p` into a a point on top associated with the cylinder.
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
858 ///
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
859 /// May panic if the coordinates are invalid.
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
860 pub fn on_top(&self, angle : Angle, r : f64) -> OnCylinder<'_> {
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
861 self.point_on_top(CapPoint{ angle, r })
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
862 }
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
863
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
864 /// Convert `p` into a a point on bottom associated with the cylinder.
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
865 ///
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
866 /// May panic if the coordinates are invalid.
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
867 pub fn on_bottom(&self, angle : Angle, r : f64) -> OnCylinder<'_> {
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
868 self.point_on_bottom(CapPoint{ angle, r })
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
869 }
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
870 }
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
871
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
872 impl<'a> OnCylinder<'a> {
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
873 /// Return the cylindrical coordinates of this point
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
874 pub fn cyl_coords(&self) -> CylCoords {
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
875 self.cylinder.cyl_coords(&self.point)
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
876 }
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
877 }
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
878
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
879 impl<'a> EmbeddedManifoldPoint for OnCylinder<'a> {
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
880 type EmbeddedCoords = Loc<f64, 3>;
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
881
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
882 /// Get embedded 3D coordinates
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
883 fn embedded_coords(&self) -> Loc<f64, 3> {
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
884 self.cyl_coords().to_cartesian()
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
885 }
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
886 }
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
887
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
888 impl<'a> ManifoldPoint for OnCylinder<'a> {
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
889 type Tangent = Tangent;
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
890
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
891 fn exp(self, tangent : &Self::Tangent) -> Self {
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
892 let cylinder = self.cylinder;
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
893 let point = cylinder.exp(&self.point, tangent);
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
894 OnCylinder { cylinder, point }
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
895 }
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
896
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
897 fn log(&self, other : &Self) -> Self::Tangent {
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
898 assert!(self.cylinder == other.cylinder);
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
899 self.cylinder.log_dist(&self.point, &other.point).0
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
900 }
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
901
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
902 fn dist_to(&self, other : &Self) -> f64 {
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
903 assert!(self.cylinder == other.cylinder);
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
904 self.cylinder.log_dist(&self.point, &other.point).1
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
905 }
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
906
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
907 fn tangent_origin(&self) -> Self::Tangent {
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
908 Loc([0.0, 0.0])
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
909 }
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
910 }
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
911
56
34f8ec636368 Update to current alg_tools
Tuomo Valkonen <tuomov@iki.fi>
parents: 46
diff changeset
912 impl_basic_space!(OnCylinder<'a> where 'a);
34f8ec636368 Update to current alg_tools
Tuomo Valkonen <tuomov@iki.fi>
parents: 46
diff changeset
913
37
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
914 #[cfg(test)]
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
915 mod tests {
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
916 use super::*;
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
917
41
56d609b70a3b Cylinder numerical stability hacks
Tuomo Valkonen <tuomov@iki.fi>
parents: 40
diff changeset
918 static TOL : f64 = 1e-7;
38
63318d1b4f00 Fixes and unit tests for cylinder
Tuomo Valkonen <tuomov@iki.fi>
parents: 37
diff changeset
919
63318d1b4f00 Fixes and unit tests for cylinder
Tuomo Valkonen <tuomov@iki.fi>
parents: 37
diff changeset
920 macro_rules! check_distance {
63318d1b4f00 Fixes and unit tests for cylinder
Tuomo Valkonen <tuomov@iki.fi>
parents: 37
diff changeset
921 ($distance : expr, $expected : expr) => {
63318d1b4f00 Fixes and unit tests for cylinder
Tuomo Valkonen <tuomov@iki.fi>
parents: 37
diff changeset
922 assert!(
63318d1b4f00 Fixes and unit tests for cylinder
Tuomo Valkonen <tuomov@iki.fi>
parents: 37
diff changeset
923 ($distance-$expected).abs() < TOL,
63318d1b4f00 Fixes and unit tests for cylinder
Tuomo Valkonen <tuomov@iki.fi>
parents: 37
diff changeset
924 "{} = {}, expected = {}",
63318d1b4f00 Fixes and unit tests for cylinder
Tuomo Valkonen <tuomov@iki.fi>
parents: 37
diff changeset
925 stringify!($distance),
63318d1b4f00 Fixes and unit tests for cylinder
Tuomo Valkonen <tuomov@iki.fi>
parents: 37
diff changeset
926 $distance,
63318d1b4f00 Fixes and unit tests for cylinder
Tuomo Valkonen <tuomov@iki.fi>
parents: 37
diff changeset
927 $expected,
63318d1b4f00 Fixes and unit tests for cylinder
Tuomo Valkonen <tuomov@iki.fi>
parents: 37
diff changeset
928 )
63318d1b4f00 Fixes and unit tests for cylinder
Tuomo Valkonen <tuomov@iki.fi>
parents: 37
diff changeset
929 }
63318d1b4f00 Fixes and unit tests for cylinder
Tuomo Valkonen <tuomov@iki.fi>
parents: 37
diff changeset
930 }
63318d1b4f00 Fixes and unit tests for cylinder
Tuomo Valkonen <tuomov@iki.fi>
parents: 37
diff changeset
931
63318d1b4f00 Fixes and unit tests for cylinder
Tuomo Valkonen <tuomov@iki.fi>
parents: 37
diff changeset
932 macro_rules! check_vec_eq {
63318d1b4f00 Fixes and unit tests for cylinder
Tuomo Valkonen <tuomov@iki.fi>
parents: 37
diff changeset
933 ($left : expr, $right : expr) => {
63318d1b4f00 Fixes and unit tests for cylinder
Tuomo Valkonen <tuomov@iki.fi>
parents: 37
diff changeset
934 let err = ($left-$right).norm(L2);
63318d1b4f00 Fixes and unit tests for cylinder
Tuomo Valkonen <tuomov@iki.fi>
parents: 37
diff changeset
935 if err > TOL {
63318d1b4f00 Fixes and unit tests for cylinder
Tuomo Valkonen <tuomov@iki.fi>
parents: 37
diff changeset
936 panic!("{:?} != {:?} [error {err}]", $left, $right);
63318d1b4f00 Fixes and unit tests for cylinder
Tuomo Valkonen <tuomov@iki.fi>
parents: 37
diff changeset
937 }
63318d1b4f00 Fixes and unit tests for cylinder
Tuomo Valkonen <tuomov@iki.fi>
parents: 37
diff changeset
938 }
63318d1b4f00 Fixes and unit tests for cylinder
Tuomo Valkonen <tuomov@iki.fi>
parents: 37
diff changeset
939 }
63318d1b4f00 Fixes and unit tests for cylinder
Tuomo Valkonen <tuomov@iki.fi>
parents: 37
diff changeset
940
63318d1b4f00 Fixes and unit tests for cylinder
Tuomo Valkonen <tuomov@iki.fi>
parents: 37
diff changeset
941 macro_rules! check_point_eq {
63318d1b4f00 Fixes and unit tests for cylinder
Tuomo Valkonen <tuomov@iki.fi>
parents: 37
diff changeset
942 ($left : expr, $right : expr) => {
63318d1b4f00 Fixes and unit tests for cylinder
Tuomo Valkonen <tuomov@iki.fi>
parents: 37
diff changeset
943 match ($left, $right) {
63318d1b4f00 Fixes and unit tests for cylinder
Tuomo Valkonen <tuomov@iki.fi>
parents: 37
diff changeset
944 (Point::Top(a), Point::Top(b)) | (Point::Bottom(a), Point::Bottom(b))=> {
63318d1b4f00 Fixes and unit tests for cylinder
Tuomo Valkonen <tuomov@iki.fi>
parents: 37
diff changeset
945 if (a.angle-b.angle).abs() > TOL || (a.r-b.r).abs() > TOL {
63318d1b4f00 Fixes and unit tests for cylinder
Tuomo Valkonen <tuomov@iki.fi>
parents: 37
diff changeset
946 panic!("{:?} != {:?}", a, b)
63318d1b4f00 Fixes and unit tests for cylinder
Tuomo Valkonen <tuomov@iki.fi>
parents: 37
diff changeset
947 }
63318d1b4f00 Fixes and unit tests for cylinder
Tuomo Valkonen <tuomov@iki.fi>
parents: 37
diff changeset
948 },
63318d1b4f00 Fixes and unit tests for cylinder
Tuomo Valkonen <tuomov@iki.fi>
parents: 37
diff changeset
949 (Point::Side(a), Point::Side(b)) => {
63318d1b4f00 Fixes and unit tests for cylinder
Tuomo Valkonen <tuomov@iki.fi>
parents: 37
diff changeset
950 if (a.angle-b.angle).abs() > TOL || (a.z-b.z).abs() > TOL {
63318d1b4f00 Fixes and unit tests for cylinder
Tuomo Valkonen <tuomov@iki.fi>
parents: 37
diff changeset
951 panic!("{:?} != {:?}", a, b)
63318d1b4f00 Fixes and unit tests for cylinder
Tuomo Valkonen <tuomov@iki.fi>
parents: 37
diff changeset
952 }
63318d1b4f00 Fixes and unit tests for cylinder
Tuomo Valkonen <tuomov@iki.fi>
parents: 37
diff changeset
953 },
63318d1b4f00 Fixes and unit tests for cylinder
Tuomo Valkonen <tuomov@iki.fi>
parents: 37
diff changeset
954 (a, b) => {
63318d1b4f00 Fixes and unit tests for cylinder
Tuomo Valkonen <tuomov@iki.fi>
parents: 37
diff changeset
955 panic!("{:?} != {:?}", a, b)
63318d1b4f00 Fixes and unit tests for cylinder
Tuomo Valkonen <tuomov@iki.fi>
parents: 37
diff changeset
956 }
63318d1b4f00 Fixes and unit tests for cylinder
Tuomo Valkonen <tuomov@iki.fi>
parents: 37
diff changeset
957 }
63318d1b4f00 Fixes and unit tests for cylinder
Tuomo Valkonen <tuomov@iki.fi>
parents: 37
diff changeset
958 }
63318d1b4f00 Fixes and unit tests for cylinder
Tuomo Valkonen <tuomov@iki.fi>
parents: 37
diff changeset
959 }
63318d1b4f00 Fixes and unit tests for cylinder
Tuomo Valkonen <tuomov@iki.fi>
parents: 37
diff changeset
960
37
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
961 static CYL : Cylinder = Cylinder {
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
962 radius : 1.0,
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
963 height : 1.0,
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
964 config : CylinderConfig { newton_iters : 20 },
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
965 };
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
966
46
90cc221eb52b More documentation
Tuomo Valkonen <tuomov@iki.fi>
parents: 41
diff changeset
967 /// Tests for correct distance calculation beween two points on the same cap.
37
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
968 #[test]
46
90cc221eb52b More documentation
Tuomo Valkonen <tuomov@iki.fi>
parents: 41
diff changeset
969 fn intra_cap_dist() {
37
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
970 let π = f64::PI;
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
971 let p1 = CYL.on_top(0.0, 0.5);
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
972 let p2 = CYL.on_top(π, 0.5);
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
973 let p3 = CYL.on_top(π/2.0, 0.5);
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
974
38
63318d1b4f00 Fixes and unit tests for cylinder
Tuomo Valkonen <tuomov@iki.fi>
parents: 37
diff changeset
975 check_distance!(p1.dist_to(&p2), 1.0);
63318d1b4f00 Fixes and unit tests for cylinder
Tuomo Valkonen <tuomov@iki.fi>
parents: 37
diff changeset
976 check_distance!(p2.dist_to(&p3), 0.5_f64.sqrt());
63318d1b4f00 Fixes and unit tests for cylinder
Tuomo Valkonen <tuomov@iki.fi>
parents: 37
diff changeset
977 check_distance!(p3.dist_to(&p1), 0.5_f64.sqrt());
37
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
978 }
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
979
46
90cc221eb52b More documentation
Tuomo Valkonen <tuomov@iki.fi>
parents: 41
diff changeset
980 /// Tests for correct distance calculation beween two points on the side.
37
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
981 #[test]
46
90cc221eb52b More documentation
Tuomo Valkonen <tuomov@iki.fi>
parents: 41
diff changeset
982 fn intra_side_dist() {
37
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
983 let π = f64::PI;
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
984 let p1 = CYL.on_side(0.0, 0.0);
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
985 let p2 = CYL.on_side(0.0, 0.4);
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
986 let p3 = CYL.on_side(π/2.0, 0.0);
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
987
38
63318d1b4f00 Fixes and unit tests for cylinder
Tuomo Valkonen <tuomov@iki.fi>
parents: 37
diff changeset
988 check_distance!(p1.dist_to(&p2), 0.4);
63318d1b4f00 Fixes and unit tests for cylinder
Tuomo Valkonen <tuomov@iki.fi>
parents: 37
diff changeset
989 check_distance!(p1.dist_to(&p3), π/2.0*CYL.radius);
37
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
990 }
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
991
46
90cc221eb52b More documentation
Tuomo Valkonen <tuomov@iki.fi>
parents: 41
diff changeset
992 /// Tests for correct distance calculation beween two points on the side, when the corresponding
90cc221eb52b More documentation
Tuomo Valkonen <tuomov@iki.fi>
parents: 41
diff changeset
993 /// minimal geodesic has to cross a cap.
37
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
994 #[test]
46
90cc221eb52b More documentation
Tuomo Valkonen <tuomov@iki.fi>
parents: 41
diff changeset
995 fn intra_side_over_cap_dist() {
37
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
996 let π = f64::PI;
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
997 let off = 0.05;
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
998 let z = CYL.top_z() - off;
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
999 let p1 = CYL.on_side(0.0, z);
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
1000 let p2 = CYL.on_side(π, z);
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
1001
38
63318d1b4f00 Fixes and unit tests for cylinder
Tuomo Valkonen <tuomov@iki.fi>
parents: 37
diff changeset
1002 check_distance!(p1.dist_to(&p2), 2.0 * (CYL.radius + off));
37
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
1003 }
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
1004
46
90cc221eb52b More documentation
Tuomo Valkonen <tuomov@iki.fi>
parents: 41
diff changeset
1005 /// Tests for correct distance calculation between points on top and bottom caps.
37
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
1006 #[test]
46
90cc221eb52b More documentation
Tuomo Valkonen <tuomov@iki.fi>
parents: 41
diff changeset
1007 fn top_bottom_dist() {
37
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
1008 let π = f64::PI;
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
1009 let p1 = CYL.on_top(0.0, 0.0);
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
1010 let p2 = CYL.on_bottom(0.0, 0.0);
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
1011
38
63318d1b4f00 Fixes and unit tests for cylinder
Tuomo Valkonen <tuomov@iki.fi>
parents: 37
diff changeset
1012 check_distance!(p1.dist_to(&p2), 2.0 * CYL.radius + CYL.height);
37
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
1013
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
1014 let p1 = CYL.on_top(0.0, CYL.radius / 2.0);
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
1015 let p2 = CYL.on_bottom(0.0, CYL.radius / 2.0);
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
1016 let p3 = CYL.on_bottom(π, CYL.radius / 2.0);
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
1017
38
63318d1b4f00 Fixes and unit tests for cylinder
Tuomo Valkonen <tuomov@iki.fi>
parents: 37
diff changeset
1018 check_distance!(p1.dist_to(&p2), CYL.radius + CYL.height);
63318d1b4f00 Fixes and unit tests for cylinder
Tuomo Valkonen <tuomov@iki.fi>
parents: 37
diff changeset
1019 check_distance!(p1.dist_to(&p3), 2.0 * CYL.radius + CYL.height);
37
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
1020 }
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
1021
46
90cc221eb52b More documentation
Tuomo Valkonen <tuomov@iki.fi>
parents: 41
diff changeset
1022 /// Test for correct distance calculation between points on the side and a cap.
37
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
1023 #[test]
46
90cc221eb52b More documentation
Tuomo Valkonen <tuomov@iki.fi>
parents: 41
diff changeset
1024 fn top_side_dist() {
37
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
1025 let p1 = CYL.on_top(0.0, 0.0);
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
1026 let p2 = CYL.on_side(0.0, 0.0);
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
1027
38
63318d1b4f00 Fixes and unit tests for cylinder
Tuomo Valkonen <tuomov@iki.fi>
parents: 37
diff changeset
1028 check_distance!(p1.dist_to(&p2), CYL.radius + CYL.height / 2.0);
63318d1b4f00 Fixes and unit tests for cylinder
Tuomo Valkonen <tuomov@iki.fi>
parents: 37
diff changeset
1029 }
63318d1b4f00 Fixes and unit tests for cylinder
Tuomo Valkonen <tuomov@iki.fi>
parents: 37
diff changeset
1030
46
90cc221eb52b More documentation
Tuomo Valkonen <tuomov@iki.fi>
parents: 41
diff changeset
1031 /// Tests for correct tangent calculation from a cap to the side.
38
63318d1b4f00 Fixes and unit tests for cylinder
Tuomo Valkonen <tuomov@iki.fi>
parents: 37
diff changeset
1032 #[test]
63318d1b4f00 Fixes and unit tests for cylinder
Tuomo Valkonen <tuomov@iki.fi>
parents: 37
diff changeset
1033 fn cap_side_partial_exp() {
63318d1b4f00 Fixes and unit tests for cylinder
Tuomo Valkonen <tuomov@iki.fi>
parents: 37
diff changeset
1034 let π = f64::PI;
63318d1b4f00 Fixes and unit tests for cylinder
Tuomo Valkonen <tuomov@iki.fi>
parents: 37
diff changeset
1035 let angles = [0.0, π/2.0, π*5.0/6.0, π*7.0/5.0];
63318d1b4f00 Fixes and unit tests for cylinder
Tuomo Valkonen <tuomov@iki.fi>
parents: 37
diff changeset
1036
63318d1b4f00 Fixes and unit tests for cylinder
Tuomo Valkonen <tuomov@iki.fi>
parents: 37
diff changeset
1037 for φ in angles {
63318d1b4f00 Fixes and unit tests for cylinder
Tuomo Valkonen <tuomov@iki.fi>
parents: 37
diff changeset
1038 let p = CYL.on_top(φ, CYL.radius / 2.0);
63318d1b4f00 Fixes and unit tests for cylinder
Tuomo Valkonen <tuomov@iki.fi>
parents: 37
diff changeset
1039 let q_target = CYL.on_side(φ, CYL.height / 2.0);
40
1d865db9d3e4 Move rotate and reflect to alg_tools
Tuomo Valkonen <tuomov@iki.fi>
parents: 39
diff changeset
1040 let t = Loc([CYL.radius, 0.0]).rotate(φ);
38
63318d1b4f00 Fixes and unit tests for cylinder
Tuomo Valkonen <tuomov@iki.fi>
parents: 37
diff changeset
1041 let t_target = Loc([0.0, -CYL.radius / 2.0]);
63318d1b4f00 Fixes and unit tests for cylinder
Tuomo Valkonen <tuomov@iki.fi>
parents: 37
diff changeset
1042 let (q, t_left) = CYL.partial_exp(p.point, t);
63318d1b4f00 Fixes and unit tests for cylinder
Tuomo Valkonen <tuomov@iki.fi>
parents: 37
diff changeset
1043 check_point_eq!(q, q_target.point);
63318d1b4f00 Fixes and unit tests for cylinder
Tuomo Valkonen <tuomov@iki.fi>
parents: 37
diff changeset
1044 if let Some(t_left_) = t_left {
63318d1b4f00 Fixes and unit tests for cylinder
Tuomo Valkonen <tuomov@iki.fi>
parents: 37
diff changeset
1045 check_vec_eq!(t_left_, t_target);
63318d1b4f00 Fixes and unit tests for cylinder
Tuomo Valkonen <tuomov@iki.fi>
parents: 37
diff changeset
1046 } else {
63318d1b4f00 Fixes and unit tests for cylinder
Tuomo Valkonen <tuomov@iki.fi>
parents: 37
diff changeset
1047 panic!("No tangent left");
63318d1b4f00 Fixes and unit tests for cylinder
Tuomo Valkonen <tuomov@iki.fi>
parents: 37
diff changeset
1048 }
63318d1b4f00 Fixes and unit tests for cylinder
Tuomo Valkonen <tuomov@iki.fi>
parents: 37
diff changeset
1049 }
63318d1b4f00 Fixes and unit tests for cylinder
Tuomo Valkonen <tuomov@iki.fi>
parents: 37
diff changeset
1050
63318d1b4f00 Fixes and unit tests for cylinder
Tuomo Valkonen <tuomov@iki.fi>
parents: 37
diff changeset
1051 for φ in angles {
63318d1b4f00 Fixes and unit tests for cylinder
Tuomo Valkonen <tuomov@iki.fi>
parents: 37
diff changeset
1052 let p = CYL.on_top(φ + π/2.0, CYL.radius);
63318d1b4f00 Fixes and unit tests for cylinder
Tuomo Valkonen <tuomov@iki.fi>
parents: 37
diff changeset
1053 let q_target = CYL.on_side(φ, CYL.height / 2.0);
40
1d865db9d3e4 Move rotate and reflect to alg_tools
Tuomo Valkonen <tuomov@iki.fi>
parents: 39
diff changeset
1054 let t = 2.0 * Loc([CYL.radius, -CYL.radius]).rotate(φ);
38
63318d1b4f00 Fixes and unit tests for cylinder
Tuomo Valkonen <tuomov@iki.fi>
parents: 37
diff changeset
1055 let t_target = Loc([-CYL.radius, -CYL.radius]);
63318d1b4f00 Fixes and unit tests for cylinder
Tuomo Valkonen <tuomov@iki.fi>
parents: 37
diff changeset
1056 let (q, t_left) = CYL.partial_exp(p.point, t);
63318d1b4f00 Fixes and unit tests for cylinder
Tuomo Valkonen <tuomov@iki.fi>
parents: 37
diff changeset
1057 check_point_eq!(q, q_target.point);
63318d1b4f00 Fixes and unit tests for cylinder
Tuomo Valkonen <tuomov@iki.fi>
parents: 37
diff changeset
1058 if let Some(t_left_) = t_left {
63318d1b4f00 Fixes and unit tests for cylinder
Tuomo Valkonen <tuomov@iki.fi>
parents: 37
diff changeset
1059 check_vec_eq!(t_left_, t_target);
63318d1b4f00 Fixes and unit tests for cylinder
Tuomo Valkonen <tuomov@iki.fi>
parents: 37
diff changeset
1060 } else {
63318d1b4f00 Fixes and unit tests for cylinder
Tuomo Valkonen <tuomov@iki.fi>
parents: 37
diff changeset
1061 panic!("No tangent left");
63318d1b4f00 Fixes and unit tests for cylinder
Tuomo Valkonen <tuomov@iki.fi>
parents: 37
diff changeset
1062 }
63318d1b4f00 Fixes and unit tests for cylinder
Tuomo Valkonen <tuomov@iki.fi>
parents: 37
diff changeset
1063 }
63318d1b4f00 Fixes and unit tests for cylinder
Tuomo Valkonen <tuomov@iki.fi>
parents: 37
diff changeset
1064 }
63318d1b4f00 Fixes and unit tests for cylinder
Tuomo Valkonen <tuomov@iki.fi>
parents: 37
diff changeset
1065
46
90cc221eb52b More documentation
Tuomo Valkonen <tuomov@iki.fi>
parents: 41
diff changeset
1066 /// Tests for correct tangent calculation from the side to a cap.
38
63318d1b4f00 Fixes and unit tests for cylinder
Tuomo Valkonen <tuomov@iki.fi>
parents: 37
diff changeset
1067 #[test]
63318d1b4f00 Fixes and unit tests for cylinder
Tuomo Valkonen <tuomov@iki.fi>
parents: 37
diff changeset
1068 fn side_top_exp() {
63318d1b4f00 Fixes and unit tests for cylinder
Tuomo Valkonen <tuomov@iki.fi>
parents: 37
diff changeset
1069 let π = f64::PI;
63318d1b4f00 Fixes and unit tests for cylinder
Tuomo Valkonen <tuomov@iki.fi>
parents: 37
diff changeset
1070 let angles = [0.0, π/2.0, π*5.0/6.0, π*7.0/5.0];
63318d1b4f00 Fixes and unit tests for cylinder
Tuomo Valkonen <tuomov@iki.fi>
parents: 37
diff changeset
1071
63318d1b4f00 Fixes and unit tests for cylinder
Tuomo Valkonen <tuomov@iki.fi>
parents: 37
diff changeset
1072 for φ in angles {
63318d1b4f00 Fixes and unit tests for cylinder
Tuomo Valkonen <tuomov@iki.fi>
parents: 37
diff changeset
1073 let pt = CYL.on_top(φ, CYL.radius);
40
1d865db9d3e4 Move rotate and reflect to alg_tools
Tuomo Valkonen <tuomov@iki.fi>
parents: 39
diff changeset
1074 let t = Loc([0.1, 0.3]).rotate(φ);
38
63318d1b4f00 Fixes and unit tests for cylinder
Tuomo Valkonen <tuomov@iki.fi>
parents: 37
diff changeset
1075 let b = pt.clone().exp(&t);
63318d1b4f00 Fixes and unit tests for cylinder
Tuomo Valkonen <tuomov@iki.fi>
parents: 37
diff changeset
1076 let a = pt.exp(&(-t));
63318d1b4f00 Fixes and unit tests for cylinder
Tuomo Valkonen <tuomov@iki.fi>
parents: 37
diff changeset
1077 check_point_eq!(a.exp(&(2.0*t)).point, b.point);
63318d1b4f00 Fixes and unit tests for cylinder
Tuomo Valkonen <tuomov@iki.fi>
parents: 37
diff changeset
1078 }
63318d1b4f00 Fixes and unit tests for cylinder
Tuomo Valkonen <tuomov@iki.fi>
parents: 37
diff changeset
1079 }
63318d1b4f00 Fixes and unit tests for cylinder
Tuomo Valkonen <tuomov@iki.fi>
parents: 37
diff changeset
1080
63318d1b4f00 Fixes and unit tests for cylinder
Tuomo Valkonen <tuomov@iki.fi>
parents: 37
diff changeset
1081 /// Tests that tangent “returned” on edge from cap to top, correctly
63318d1b4f00 Fixes and unit tests for cylinder
Tuomo Valkonen <tuomov@iki.fi>
parents: 37
diff changeset
1082 /// sums with a top tangent.
63318d1b4f00 Fixes and unit tests for cylinder
Tuomo Valkonen <tuomov@iki.fi>
parents: 37
diff changeset
1083 #[test]
63318d1b4f00 Fixes and unit tests for cylinder
Tuomo Valkonen <tuomov@iki.fi>
parents: 37
diff changeset
1084 fn cap_side_log_exp() {
63318d1b4f00 Fixes and unit tests for cylinder
Tuomo Valkonen <tuomov@iki.fi>
parents: 37
diff changeset
1085 let π = f64::PI;
63318d1b4f00 Fixes and unit tests for cylinder
Tuomo Valkonen <tuomov@iki.fi>
parents: 37
diff changeset
1086 let angles = [0.0, π/2.0, π*5.0/6.0, π*7.0/5.0];
63318d1b4f00 Fixes and unit tests for cylinder
Tuomo Valkonen <tuomov@iki.fi>
parents: 37
diff changeset
1087
63318d1b4f00 Fixes and unit tests for cylinder
Tuomo Valkonen <tuomov@iki.fi>
parents: 37
diff changeset
1088 for top in [true, false] {
63318d1b4f00 Fixes and unit tests for cylinder
Tuomo Valkonen <tuomov@iki.fi>
parents: 37
diff changeset
1089 for (&φ, &ψ) in angles.iter().zip(angles.iter().rev()) {
63318d1b4f00 Fixes and unit tests for cylinder
Tuomo Valkonen <tuomov@iki.fi>
parents: 37
diff changeset
1090 let a = if top {
63318d1b4f00 Fixes and unit tests for cylinder
Tuomo Valkonen <tuomov@iki.fi>
parents: 37
diff changeset
1091 CYL.on_top(φ, CYL.radius/2.0)
63318d1b4f00 Fixes and unit tests for cylinder
Tuomo Valkonen <tuomov@iki.fi>
parents: 37
diff changeset
1092 } else {
63318d1b4f00 Fixes and unit tests for cylinder
Tuomo Valkonen <tuomov@iki.fi>
parents: 37
diff changeset
1093 CYL.on_bottom(φ, CYL.radius/2.0)
63318d1b4f00 Fixes and unit tests for cylinder
Tuomo Valkonen <tuomov@iki.fi>
parents: 37
diff changeset
1094 };
63318d1b4f00 Fixes and unit tests for cylinder
Tuomo Valkonen <tuomov@iki.fi>
parents: 37
diff changeset
1095 let b = CYL.on_side(ψ, 0.0);
63318d1b4f00 Fixes and unit tests for cylinder
Tuomo Valkonen <tuomov@iki.fi>
parents: 37
diff changeset
1096 let t = a.log(&b);
63318d1b4f00 Fixes and unit tests for cylinder
Tuomo Valkonen <tuomov@iki.fi>
parents: 37
diff changeset
1097 let (p@Point::Side(side), Some(tpb)) = CYL.partial_exp(a.point, t) else {
63318d1b4f00 Fixes and unit tests for cylinder
Tuomo Valkonen <tuomov@iki.fi>
parents: 37
diff changeset
1098 panic!("No tangent or point not on side");
63318d1b4f00 Fixes and unit tests for cylinder
Tuomo Valkonen <tuomov@iki.fi>
parents: 37
diff changeset
1099 };
63318d1b4f00 Fixes and unit tests for cylinder
Tuomo Valkonen <tuomov@iki.fi>
parents: 37
diff changeset
1100 let pp = CYL.point_on(p);
63318d1b4f00 Fixes and unit tests for cylinder
Tuomo Valkonen <tuomov@iki.fi>
parents: 37
diff changeset
1101 let tpb2 = pp.log(&b);
63318d1b4f00 Fixes and unit tests for cylinder
Tuomo Valkonen <tuomov@iki.fi>
parents: 37
diff changeset
1102 let tap = a.log(&pp);
63318d1b4f00 Fixes and unit tests for cylinder
Tuomo Valkonen <tuomov@iki.fi>
parents: 37
diff changeset
1103 check_vec_eq!(tpb, tpb2);
63318d1b4f00 Fixes and unit tests for cylinder
Tuomo Valkonen <tuomov@iki.fi>
parents: 37
diff changeset
1104 if top {
63318d1b4f00 Fixes and unit tests for cylinder
Tuomo Valkonen <tuomov@iki.fi>
parents: 37
diff changeset
1105 assert!(indistinguishable(side.z, CYL.top_z()));
63318d1b4f00 Fixes and unit tests for cylinder
Tuomo Valkonen <tuomov@iki.fi>
parents: 37
diff changeset
1106 } else {
63318d1b4f00 Fixes and unit tests for cylinder
Tuomo Valkonen <tuomov@iki.fi>
parents: 37
diff changeset
1107 assert!(indistinguishable(side.z, CYL.bottom_z()));
63318d1b4f00 Fixes and unit tests for cylinder
Tuomo Valkonen <tuomov@iki.fi>
parents: 37
diff changeset
1108 }
63318d1b4f00 Fixes and unit tests for cylinder
Tuomo Valkonen <tuomov@iki.fi>
parents: 37
diff changeset
1109 let cap = CapPoint{ angle : side.angle, r : CYL.radius };
63318d1b4f00 Fixes and unit tests for cylinder
Tuomo Valkonen <tuomov@iki.fi>
parents: 37
diff changeset
1110 let tbpcap = cap.tangent_from_side(top, tpb);
63318d1b4f00 Fixes and unit tests for cylinder
Tuomo Valkonen <tuomov@iki.fi>
parents: 37
diff changeset
1111 check_vec_eq!(tap + tbpcap, t);
63318d1b4f00 Fixes and unit tests for cylinder
Tuomo Valkonen <tuomov@iki.fi>
parents: 37
diff changeset
1112 }
63318d1b4f00 Fixes and unit tests for cylinder
Tuomo Valkonen <tuomov@iki.fi>
parents: 37
diff changeset
1113 }
63318d1b4f00 Fixes and unit tests for cylinder
Tuomo Valkonen <tuomov@iki.fi>
parents: 37
diff changeset
1114 }
63318d1b4f00 Fixes and unit tests for cylinder
Tuomo Valkonen <tuomov@iki.fi>
parents: 37
diff changeset
1115
63318d1b4f00 Fixes and unit tests for cylinder
Tuomo Valkonen <tuomov@iki.fi>
parents: 37
diff changeset
1116
63318d1b4f00 Fixes and unit tests for cylinder
Tuomo Valkonen <tuomov@iki.fi>
parents: 37
diff changeset
1117 /// Tests that tangent “returned” on edge from top to side, correctly
63318d1b4f00 Fixes and unit tests for cylinder
Tuomo Valkonen <tuomov@iki.fi>
parents: 37
diff changeset
1118 /// sums with a side tangent.
63318d1b4f00 Fixes and unit tests for cylinder
Tuomo Valkonen <tuomov@iki.fi>
parents: 37
diff changeset
1119 #[test]
63318d1b4f00 Fixes and unit tests for cylinder
Tuomo Valkonen <tuomov@iki.fi>
parents: 37
diff changeset
1120 fn side_cap_log_exp() {
63318d1b4f00 Fixes and unit tests for cylinder
Tuomo Valkonen <tuomov@iki.fi>
parents: 37
diff changeset
1121 let π = f64::PI;
63318d1b4f00 Fixes and unit tests for cylinder
Tuomo Valkonen <tuomov@iki.fi>
parents: 37
diff changeset
1122 let angles = [0.0, π/2.0, π*5.0/6.0, π*7.0/5.0];
63318d1b4f00 Fixes and unit tests for cylinder
Tuomo Valkonen <tuomov@iki.fi>
parents: 37
diff changeset
1123
63318d1b4f00 Fixes and unit tests for cylinder
Tuomo Valkonen <tuomov@iki.fi>
parents: 37
diff changeset
1124 for top in [true, false] {
63318d1b4f00 Fixes and unit tests for cylinder
Tuomo Valkonen <tuomov@iki.fi>
parents: 37
diff changeset
1125 for (&φ, &ψ) in angles.iter().zip(angles.iter().rev()) {
63318d1b4f00 Fixes and unit tests for cylinder
Tuomo Valkonen <tuomov@iki.fi>
parents: 37
diff changeset
1126 let a = CYL.on_side(ψ, 0.0);
63318d1b4f00 Fixes and unit tests for cylinder
Tuomo Valkonen <tuomov@iki.fi>
parents: 37
diff changeset
1127 let b = if top {
63318d1b4f00 Fixes and unit tests for cylinder
Tuomo Valkonen <tuomov@iki.fi>
parents: 37
diff changeset
1128 CYL.on_top(φ, CYL.radius/2.0)
63318d1b4f00 Fixes and unit tests for cylinder
Tuomo Valkonen <tuomov@iki.fi>
parents: 37
diff changeset
1129 } else {
63318d1b4f00 Fixes and unit tests for cylinder
Tuomo Valkonen <tuomov@iki.fi>
parents: 37
diff changeset
1130 CYL.on_bottom(φ, CYL.radius/2.0)
63318d1b4f00 Fixes and unit tests for cylinder
Tuomo Valkonen <tuomov@iki.fi>
parents: 37
diff changeset
1131 };
63318d1b4f00 Fixes and unit tests for cylinder
Tuomo Valkonen <tuomov@iki.fi>
parents: 37
diff changeset
1132 let t = a.log(&b);
63318d1b4f00 Fixes and unit tests for cylinder
Tuomo Valkonen <tuomov@iki.fi>
parents: 37
diff changeset
1133 let (p, cap, tpb) = match CYL.partial_exp(a.point, t) {
63318d1b4f00 Fixes and unit tests for cylinder
Tuomo Valkonen <tuomov@iki.fi>
parents: 37
diff changeset
1134 (p@Point::Top(cap), Some(tpb)) if top => (p, cap, tpb),
63318d1b4f00 Fixes and unit tests for cylinder
Tuomo Valkonen <tuomov@iki.fi>
parents: 37
diff changeset
1135 (p@Point::Bottom(cap), Some(tpb)) if !top => (p, cap, tpb),
63318d1b4f00 Fixes and unit tests for cylinder
Tuomo Valkonen <tuomov@iki.fi>
parents: 37
diff changeset
1136 _ => panic!("No tangent or point not on correct cap"),
63318d1b4f00 Fixes and unit tests for cylinder
Tuomo Valkonen <tuomov@iki.fi>
parents: 37
diff changeset
1137 };
63318d1b4f00 Fixes and unit tests for cylinder
Tuomo Valkonen <tuomov@iki.fi>
parents: 37
diff changeset
1138 let pp = CYL.point_on(p);
63318d1b4f00 Fixes and unit tests for cylinder
Tuomo Valkonen <tuomov@iki.fi>
parents: 37
diff changeset
1139 let tpb2 = pp.log(&b);
63318d1b4f00 Fixes and unit tests for cylinder
Tuomo Valkonen <tuomov@iki.fi>
parents: 37
diff changeset
1140 let tap = a.log(&pp);
63318d1b4f00 Fixes and unit tests for cylinder
Tuomo Valkonen <tuomov@iki.fi>
parents: 37
diff changeset
1141 check_vec_eq!(tpb, tpb2);
63318d1b4f00 Fixes and unit tests for cylinder
Tuomo Valkonen <tuomov@iki.fi>
parents: 37
diff changeset
1142 let tbpside = cap.tangent_to_side(top, tpb);
63318d1b4f00 Fixes and unit tests for cylinder
Tuomo Valkonen <tuomov@iki.fi>
parents: 37
diff changeset
1143 check_vec_eq!(tap + tbpside, t);
63318d1b4f00 Fixes and unit tests for cylinder
Tuomo Valkonen <tuomov@iki.fi>
parents: 37
diff changeset
1144 }
63318d1b4f00 Fixes and unit tests for cylinder
Tuomo Valkonen <tuomov@iki.fi>
parents: 37
diff changeset
1145 }
37
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
1146 }
d7cd14b8ccc0 Basic cylinder implementation
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
1147 }
56
34f8ec636368 Update to current alg_tools
Tuomo Valkonen <tuomov@iki.fi>
parents: 46
diff changeset
1148

mercurial