From e58a1769e81c5fa8019a75f7292f534021e9565d Mon Sep 17 00:00:00 2001 From: =?utf8?q?Tomas=20Wenstr=C3=B6m?= Date: Sat, 16 Jan 2021 14:38:42 +0100 Subject: [PATCH] Add Degrees and Radians as newtypes --- src/common.rs | 44 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 44 insertions(+) diff --git a/src/common.rs b/src/common.rs index c75274c..2be427e 100644 --- a/src/common.rs +++ b/src/common.rs @@ -116,6 +116,41 @@ impl From<(T, T)> for Point2D { } } +impl From for Point2D { + fn from(item: Degrees) -> Self { + Point2D { + x: (item.0 * std::f64::consts::PI / 180.0).cos(), + y: (item.0 * std::f64::consts::PI / 180.0).sin(), + } + } +} + +impl From for Point2D { + fn from(item: Radians) -> Self { + Point2D { + x: item.0.cos(), + y: item.0.sin(), + } + } +} + +#[derive(Debug, PartialEq, Clone, Copy)] +struct Degrees(f64); +#[derive(Debug, PartialEq, Clone, Copy)] +struct Radians(f64); + +impl Degrees { + fn to_radians(&self) -> Radians { + Radians(self.0 * std::f64::consts::PI / 180.0) + } +} + +impl Radians { + fn to_degrees(&self) -> Degrees { + Degrees(self.0 * 180.0 * std::f64::consts::FRAC_1_PI) + } +} + #[macro_export] macro_rules! rect { ( $x:expr, $y:expr ) => { @@ -206,6 +241,15 @@ mod tests { } #[test] + fn angles() { + assert_eq!(Radians(0.0).to_degrees(), Degrees(0.0)); + assert_eq!(Radians(std::f64::consts::PI).to_degrees(), Degrees(180.0)); + assert_eq!(Degrees(180.0).to_radians(), Radians(std::f64::consts::PI)); + assert!((Point2D::from(Degrees(90.0)) - point!(0.0, 1.0)).length() < 0.001); + assert!((Point2D::from(Radians(std::f64::consts::FRAC_PI_2)) - point!(0.0, 1.0)).length() < 0.001); + } + + #[test] fn area_for_rect_of_multipliable_type() { let r: Rect<_> = (30, 20).into(); // the Into trait uses the From trait assert_eq!(r.area(), 30 * 20); -- 2.11.0