From 40232ec0639bce90d92a87d6dd021b1e545b50f3 Mon Sep 17 00:00:00 2001 From: Brendan Zabarauskas Date: Sun, 3 Apr 2016 13:32:55 +1000 Subject: [PATCH 1/5] Remove Angle::equiv Thus relied on the == operator, which doesn't make sense for floats. It seems better to leave this up to clients to decide if they want to normalize. --- src/angle.rs | 5 ----- tests/angle.rs | 13 +------------ 2 files changed, 1 insertion(+), 17 deletions(-) diff --git a/src/angle.rs b/src/angle.rs index 403a887..6aa45a0 100644 --- a/src/angle.rs +++ b/src/angle.rs @@ -107,11 +107,6 @@ pub trait Angle where fn turn_div_4() -> Self; fn turn_div_6() -> Self; - #[inline] - fn equiv(&self, other: &Self) -> bool { - self.normalize() == other.normalize() - } - fn sin(self) -> Self::Unitless; fn cos(self) -> Self::Unitless; fn tan(self) -> Self::Unitless; diff --git a/tests/angle.rs b/tests/angle.rs index 6a5643d..c660547 100644 --- a/tests/angle.rs +++ b/tests/angle.rs @@ -15,7 +15,7 @@ extern crate cgmath; -use cgmath::{Angle, Rad, Deg, rad, deg}; +use cgmath::{Rad, Deg, rad, deg}; use cgmath::ApproxEq; #[test] @@ -36,14 +36,3 @@ fn conv() { let angle: Rad<_> = angle.into(); assert!(angle.approx_eq(&rad(30.0f64))); } - -#[test] -fn equiv() { - assert!(Deg::::full_turn().equiv(&-Deg::::full_turn())); - assert!(Deg::::turn_div_2().equiv(&-Deg::::turn_div_2())); - assert!((Deg::::turn_div_3() - Deg::::full_turn()).equiv(&Deg::::turn_div_3())); - - assert!(Rad::::full_turn().equiv(&-Rad::::full_turn())); - assert!(Rad::::turn_div_2().equiv(&-Rad::::turn_div_2())); - assert!((Rad::::turn_div_3() - Rad::::full_turn()).equiv(&Rad::::turn_div_3())); -} From aa6fd71ab8ba3ffa75b4a4534a1f11d15bd025db Mon Sep 17 00:00:00 2001 From: Brendan Zabarauskas Date: Sun, 3 Apr 2016 13:36:12 +1000 Subject: [PATCH 2/5] Move Angle::new to be implemented directly on angle types This is more in keeping with most Rust APIs, and the other types in this library --- src/angle.rs | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/angle.rs b/src/angle.rs index 6aa45a0..053f349 100644 --- a/src/angle.rs +++ b/src/angle.rs @@ -34,6 +34,7 @@ use num::BaseFloat; #[repr(C, packed)] #[derive(Copy, Clone, PartialEq, PartialOrd, RustcEncodable, RustcDecodable)] pub struct Rad { pub s: S } + /// An angle, in degrees. /// /// This type is marked as `#[repr(C, packed)]`. @@ -77,9 +78,6 @@ pub trait Angle where { type Unitless: BaseFloat; - /// Create an angle from a unitless value. - fn new(value: Self::Unitless) -> Self; - /// Return the angle, normalized to the range `[0, full_turn)`. #[inline] fn normalize(self) -> Self { @@ -124,13 +122,15 @@ pub trait Angle where macro_rules! impl_angle { ($Angle:ident, $fmt:expr, $full_turn:expr, $hi:expr) => { - impl Angle for $Angle { - type Unitless = S; - + impl $Angle { #[inline] - fn new(value: S) -> $Angle { + pub fn new(value: S) -> $Angle { $Angle { s: value } } + } + + impl Angle for $Angle { + type Unitless = S; #[inline] fn zero() -> $Angle { From 1d33c231e381cae340814ef3e5ed1d35f4872a22 Mon Sep 17 00:00:00 2001 From: Brendan Zabarauskas Date: Sun, 3 Apr 2016 13:49:58 +1000 Subject: [PATCH 3/5] Improve the documentation for some angle methods --- src/angle.rs | 160 ++++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 151 insertions(+), 9 deletions(-) diff --git a/src/angle.rs b/src/angle.rs index 053f349..3429f42 100644 --- a/src/angle.rs +++ b/src/angle.rs @@ -61,7 +61,12 @@ impl From> for Rad where S: BaseFloat { } } -/// Operations on angles. +/// Angles and their associated trigonometric functions. +/// +/// Typed angles allow for the writing of self-documenting code that makes it +/// clear when semantic violations have occured - for example, adding degrees to +/// radians, or adding a number to an angle. +/// pub trait Angle where Self: Copy + Clone, Self: PartialEq + PartialOrd, @@ -85,38 +90,175 @@ pub trait Angle where if rem < Self::zero() { rem + Self::full_turn() } else { rem } } - /// Return the angle rotated by half a turn + /// Return the angle rotated by half a turn. #[inline] fn opposite(self) -> Self { Self::normalize(self + Self::turn_div_2()) } - /// Returns the interior bisector of the two angles + /// Returns the interior bisector of the two angles. #[inline] fn bisect(self, other: Self) -> Self { let half = cast(0.5f64).unwrap(); Self::normalize((self - other) * half + self) } + /// The additive identity. + /// + /// Adding this to another angle has no affect. + /// + /// For example: + /// + /// ```rust + /// use cgmath::prelude::*; + /// use cgmath::Deg; + /// + /// let v = Deg::new(180.0); + /// assert_eq!(v + Deg::zero(), v); + /// ``` fn zero() -> Self; + + /// A full rotation. fn full_turn() -> Self; + + /// Half of a full rotation. fn turn_div_2() -> Self; + + /// A third of a full rotation. fn turn_div_3() -> Self; + + /// A quarter of a full rotation. fn turn_div_4() -> Self; + + /// A sixth of a full rotation. fn turn_div_6() -> Self; + /// Compute the sine of the angle, returning a unitless ratio. + /// + /// ```rust + /// use cgmath::prelude::*; + /// use cgmath::Rad; + /// + /// let angle = Rad::new(35.0); + /// let ratio: f32 = Rad::sin(angle); + /// ``` fn sin(self) -> Self::Unitless; + + /// Compute the cosine of the angle, returning a unitless ratio. + /// + /// ```rust + /// use cgmath::prelude::*; + /// use cgmath::Rad; + /// + /// let angle = Rad::new(35.0); + /// let ratio: f32 = Rad::cos(angle); + /// ``` fn cos(self) -> Self::Unitless; + + /// Compute the tangent of the angle, returning a unitless ratio. + /// + /// ```rust + /// use cgmath::prelude::*; + /// use cgmath::Rad; + /// + /// let angle = Rad::new(35.0); + /// let ratio: f32 = Rad::tan(angle); + /// ``` fn tan(self) -> Self::Unitless; + + /// Compute the sine and cosine of the angle, returning the result as a + /// pair. + /// + /// This does not have any performance benefits, but calculating both the + /// sine and cosine of a single angle is a common operation. + /// + /// ```rust + /// use cgmath::prelude::*; + /// use cgmath::Rad; + /// + /// let angle = Rad::new(35.0); + /// let (s, c) = Rad::sin_cos(angle); + /// ``` fn sin_cos(self) -> (Self::Unitless, Self::Unitless); - #[inline] fn cot(self) -> Self::Unitless { Self::tan(self).recip() } - #[inline] fn sec(self) -> Self::Unitless { Self::cos(self).recip() } - #[inline] fn csc(self) -> Self::Unitless { Self::sin(self).recip() } + /// Compute the cosecant of the angle. + /// + /// This is the same a computing the reciprocal of `Self::sin`. + /// + /// ```rust + /// use cgmath::prelude::*; + /// use cgmath::Rad; + /// + /// let angle = Rad::new(35.0); + /// let ratio: f32 = Rad::csc(angle); + /// ``` + #[inline] + fn csc(self) -> Self::Unitless { + Self::sin(self).recip() + } + + /// Compute the secant of the angle. + /// + /// This is the same a computing the reciprocal of `Self::tan`. + /// + /// ```rust + /// use cgmath::prelude::*; + /// use cgmath::Rad; + /// + /// let angle = Rad::new(35.0); + /// let ratio: f32 = Rad::cot(angle); + /// ``` + #[inline] + fn cot(self) -> Self::Unitless { + Self::tan(self).recip() + } + + /// Compute the cotatangent of the angle. + /// + /// This is the same a computing the reciprocal of `Self::cos`. + /// + /// ```rust + /// use cgmath::prelude::*; + /// use cgmath::Rad; + /// + /// let angle = Rad::new(35.0); + /// let ratio: f32 = Rad::sec(angle); + /// ``` + #[inline] + fn sec(self) -> Self::Unitless { + Self::cos(self).recip() + } + + /// Compute the arcsine of the ratio, returning the resulting angle. + /// + /// ```rust + /// use cgmath::prelude::*; + /// use cgmath::Rad; + /// + /// let angle: Rad = Rad::asin(0.5); + /// ``` + fn asin(ratio: Self::Unitless) -> Self; + + /// Compute the arccosine of the ratio, returning the resulting angle. + /// + /// ```rust + /// use cgmath::prelude::*; + /// use cgmath::Rad; + /// + /// let angle: Rad = Rad::acos(0.5); + /// ``` + fn acos(ratio: Self::Unitless) -> Self; + + /// Compute the arctangent of the ratio, returning the resulting angle. + /// + /// ```rust + /// use cgmath::prelude::*; + /// use cgmath::Rad; + /// + /// let angle: Rad = Rad::atan(0.5); + /// ``` + fn atan(ratio: Self::Unitless) -> Self; - fn asin(a: Self::Unitless) -> Self; - fn acos(a: Self::Unitless) -> Self; - fn atan(a: Self::Unitless) -> Self; fn atan2(a: Self::Unitless, b: Self::Unitless) -> Self; } From 1b63ed3e88fa7b63b02013503b690ff36f656f62 Mon Sep 17 00:00:00 2001 From: Brendan Zabarauskas Date: Sun, 3 Apr 2016 13:52:07 +1000 Subject: [PATCH 4/5] Update changelog --- CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index e5c6174..f7e3606 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -21,11 +21,13 @@ This project adheres to [Semantic Versioning](http://semver.org/). formatting. - Marks vectors, points, matrices, and angles as `#[repr(C, packed)]`. - Renames the `Vector::{length, length2}` functions to `Vector::{magnitude, magnitude2}`. +- Moved `Angle::new` to be directly implemented on the `Rad` and `Deg` types. ### Removed - The non-mathematical operator trait implementations have been removed from the `Vector` trait, in favor of the `ElementWise` trait. +- `Angle::equiv`. ## [v0.7.0] - 2015-12-23 From 1905354d26bb7066a634fa595b4f791f8ffae7cb Mon Sep 17 00:00:00 2001 From: Brendan Zabarauskas Date: Sun, 3 Apr 2016 13:56:26 +1000 Subject: [PATCH 5/5] Fix spelling --- src/angle.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/angle.rs b/src/angle.rs index 3429f42..f97d8af 100644 --- a/src/angle.rs +++ b/src/angle.rs @@ -183,7 +183,7 @@ pub trait Angle where /// Compute the cosecant of the angle. /// - /// This is the same a computing the reciprocal of `Self::sin`. + /// This is the same as computing the reciprocal of `Self::sin`. /// /// ```rust /// use cgmath::prelude::*; @@ -199,7 +199,7 @@ pub trait Angle where /// Compute the secant of the angle. /// - /// This is the same a computing the reciprocal of `Self::tan`. + /// This is the same as computing the reciprocal of `Self::tan`. /// /// ```rust /// use cgmath::prelude::*; @@ -215,7 +215,7 @@ pub trait Angle where /// Compute the cotatangent of the angle. /// - /// This is the same a computing the reciprocal of `Self::cos`. + /// This is the same as computing the reciprocal of `Self::cos`. /// /// ```rust /// use cgmath::prelude::*;