#![forbid(unsafe_code)]
#![doc = include_str!("../README.md")]
use core::f64::consts::{PI, TAU};
#[derive(Debug, Clone, Copy, PartialEq)]
pub struct Angle {
radians: f64,
}
impl Angle {
pub const ZERO: Self = Self { radians: 0.0 };
pub const HALF_TURN: Self = Self { radians: PI };
pub const FULL_TURN: Self = Self { radians: TAU };
#[must_use]
pub const fn from_radians(radians: f64) -> Self {
Self { radians }
}
#[must_use]
pub fn from_degrees(degrees: f64) -> Self {
Self::from_radians(degrees.to_radians())
}
#[must_use]
pub const fn radians(self) -> f64 {
self.radians
}
#[must_use]
pub fn degrees(self) -> f64 {
self.radians.to_degrees()
}
#[must_use]
pub fn normalized(self) -> Self {
Self::from_radians(self.radians.rem_euclid(TAU))
}
}
#[cfg(test)]
mod tests {
use core::f64::consts::PI;
use super::Angle;
#[test]
fn converts_degrees_and_radians() {
assert_eq!(Angle::from_degrees(180.0).radians(), PI);
assert_eq!(Angle::from_radians(PI).degrees(), 180.0);
assert_eq!(Angle::ZERO.radians(), 0.0);
assert_eq!(Angle::HALF_TURN.radians(), PI);
}
#[test]
fn normalizes_angles() {
assert_eq!(Angle::from_degrees(450.0).normalized().degrees(), 90.0);
}
}