diff options
Diffstat (limited to 'src/cos.rs')
-rw-r--r-- | src/cos.rs | 21 |
1 files changed, 20 insertions, 1 deletions
@@ -7,6 +7,7 @@ use num_traits::real::Real; use num_traits::{one, zero}; use std::cmp::Ordering; +use std::convert::TryFrom; /// Compute the [cosine *similarity*] between two points. /// @@ -397,6 +398,7 @@ where /// /// # use acap::distance::Distance; /// # use acap::cos::AngularDistance; +/// # use std::convert::TryFrom; /// let zero = AngularDistance::from_cos(1.0); /// let pi_2 = AngularDistance::from_cos(0.0); /// let pi = AngularDistance::from_cos(-1.0); @@ -425,8 +427,25 @@ impl<T: PartialOrd> PartialOrd for AngularDistance<T> { } } +/// Error type for failed conversions from angles outside of `$[0, \pi]$` to [`AngularDistance`]. +#[derive(Debug)] +pub struct InvalidAngleError; + macro_rules! impl_distance { - ($f:ty) => { + ($f:ident) => { + impl TryFrom<$f> for AngularDistance<$f> { + type Error = InvalidAngleError; + + #[inline] + fn try_from(value: $f) -> Result<Self, Self::Error> { + if value >= 0.0 && value <= std::$f::consts::PI { + Ok(Self(value.cos())) + } else { + Err(InvalidAngleError) + } + } + } + impl From<AngularDistance<$f>> for $f { #[inline] fn from(value: AngularDistance<$f>) -> $f { |