Skip to main content

use_dihedral/
lib.rs

1#![forbid(unsafe_code)]
2#![doc = include_str!("../README.md")]
3
4use use_angle::Angle;
5
6/// A dihedral angle stored as an `Angle`.
7#[derive(Debug, Clone, Copy, PartialEq)]
8pub struct DihedralAngle {
9    angle: Angle,
10}
11
12impl DihedralAngle {
13    /// Creates a dihedral angle from an existing angle.
14    #[must_use]
15    pub const fn new(angle: Angle) -> Self {
16        Self { angle }
17    }
18
19    /// Creates a dihedral angle from radians.
20    #[must_use]
21    pub const fn from_radians(radians: f64) -> Self {
22        Self::new(Angle::from_radians(radians))
23    }
24
25    /// Creates a dihedral angle from degrees.
26    #[must_use]
27    pub fn from_degrees(degrees: f64) -> Self {
28        Self::new(Angle::from_degrees(degrees))
29    }
30
31    /// Returns the underlying angle.
32    #[must_use]
33    pub const fn angle(self) -> Angle {
34        self.angle
35    }
36
37    /// Returns the angle in radians.
38    #[must_use]
39    pub const fn radians(self) -> f64 {
40        self.angle.radians()
41    }
42
43    /// Returns the angle in degrees.
44    #[must_use]
45    pub fn degrees(self) -> f64 {
46        self.angle.degrees()
47    }
48
49    /// Returns the equivalent dihedral angle in `[0, 2pi)`.
50    #[must_use]
51    pub fn normalized(self) -> Self {
52        Self::new(self.angle.normalized())
53    }
54}
55
56#[cfg(test)]
57mod tests {
58    use super::DihedralAngle;
59
60    #[test]
61    fn converts_and_normalizes_dihedral_angles() {
62        let angle = DihedralAngle::from_degrees(450.0).normalized();
63
64        assert_eq!(angle.degrees(), 90.0);
65        assert_eq!(
66            DihedralAngle::from_radians(core::f64::consts::PI).degrees(),
67            180.0
68        );
69    }
70}