Skip to main content

use_hypersphere/
lib.rs

1#![forbid(unsafe_code)]
2#![doc = include_str!("../README.md")]
3
4/// An n-sphere represented by its topological dimension and radius.
5#[derive(Debug, Clone, Copy, PartialEq)]
6pub struct Hypersphere<const N: usize> {
7    radius: f64,
8}
9
10impl<const N: usize> Hypersphere<N> {
11    /// Creates an n-sphere with a positive finite radius.
12    #[must_use]
13    pub const fn new(radius: f64) -> Option<Self> {
14        if radius.is_finite() && radius > 0.0 {
15            Some(Self { radius })
16        } else {
17            None
18        }
19    }
20
21    /// Returns the n-sphere dimension.
22    #[must_use]
23    pub const fn dimension(self) -> usize {
24        N
25    }
26
27    /// Returns the ambient Euclidean dimension.
28    #[must_use]
29    pub const fn ambient_dimension(self) -> usize {
30        N + 1
31    }
32
33    /// Returns the radius.
34    #[must_use]
35    pub const fn radius(self) -> f64 {
36        self.radius
37    }
38}
39
40/// A 3-sphere, the boundary of a four-dimensional ball.
41pub type ThreeSphere = Hypersphere<3>;
42
43#[cfg(test)]
44mod tests {
45    use super::{Hypersphere, ThreeSphere};
46
47    #[test]
48    fn stores_hypersphere_metadata() {
49        let hypersphere = Hypersphere::<4>::new(2.0).expect("valid hypersphere");
50        let three_sphere = ThreeSphere::new(1.5).expect("valid 3-sphere");
51
52        assert_eq!(hypersphere.dimension(), 4);
53        assert_eq!(hypersphere.ambient_dimension(), 5);
54        assert_eq!(three_sphere.dimension(), 3);
55        assert_eq!(three_sphere.radius(), 1.5);
56        assert_eq!(Hypersphere::<2>::new(f64::NAN), None);
57    }
58}