summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/cos.rs21
1 files changed, 20 insertions, 1 deletions
diff --git a/src/cos.rs b/src/cos.rs
index 99a08f4..e7f0a87 100644
--- a/src/cos.rs
+++ b/src/cos.rs
@@ -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 {