Convert from spherical back to Cartesian coordinates.
(sph: &[f32])
| 193 | |
| 194 | /// Convert from spherical back to Cartesian coordinates. |
| 195 | fn spherical_to_cartesian(sph: &[f32]) -> Vec<f32> { |
| 196 | let n = sph.len(); |
| 197 | if n == 0 { |
| 198 | return Vec::new(); |
| 199 | } |
| 200 | if n == 1 { |
| 201 | return vec![sph[0]]; |
| 202 | } |
| 203 | |
| 204 | let r = sph[0]; |
| 205 | let angles = &sph[1..]; |
| 206 | let dims = n; // same dimensionality |
| 207 | |
| 208 | let mut cart = Vec::with_capacity(dims); |
| 209 | |
| 210 | for i in 0..dims - 1 { |
| 211 | let mut val = r; |
| 212 | for a in &angles[..i] { |
| 213 | val *= a.sin(); |
| 214 | } |
| 215 | if i < dims - 2 { |
| 216 | val *= angles[i].cos(); |
| 217 | } else { |
| 218 | // Second-to-last uses sin, last uses the atan2 angle. |
| 219 | val *= angles[dims - 2].sin(); |
| 220 | } |
| 221 | cart.push(val); |
| 222 | } |
| 223 | |
| 224 | // Last coordinate. |
| 225 | let mut val = r; |
| 226 | for angle in &angles[..dims - 2] { |
| 227 | val *= angle.sin(); |
| 228 | } |
| 229 | val *= angles[dims - 2].cos(); |
| 230 | cart.push(val); |
| 231 | |
| 232 | cart |
| 233 | } |
| 234 | |
| 235 | fn build_header(dims: u32, vectors: u32, transform: u8, compressed: &[u8]) -> Vec<u8> { |
| 236 | let mut out = Vec::with_capacity(9 + compressed.len()); |