@@ -6,7 +6,7 @@ use core::fmt::{Debug, Formatter};
66use core:: iter:: zip;
77use core:: marker:: PhantomData ;
88
9- use crate :: math :: vary:: { Iter , Vary , ZDiv } ;
9+ use super :: vary:: { Iter , Vary , ZDiv } ;
1010
1111/// Trait for types representing elements of an affine space.
1212///
@@ -92,6 +92,24 @@ pub trait Linear: Affine<Diff = Self> {
9292 fn mul ( & self , scalar : Self :: Scalar ) -> Self ;
9393}
9494
95+ pub trait Euclidean : Affine {
96+ /// Returns the canonical origin of this Euclidean space.
97+ fn origin ( ) -> Self ;
98+
99+ /// Returns the length of the translation vector between two points.
100+ fn distance ( & self , other : & Self ) -> f32 ;
101+
102+ /// Returns `self`, moved towards another point by an offset.
103+ ///
104+ /// If the distance to `other` is less than `d`, returns `other`. That is,
105+ /// this method never "overshoots" the target. Negative values of `d` result
106+ /// in moving away from `other`. If `self` equals `other`, returns `other`
107+ /// independent of the value of `d`.
108+ ///
109+ /// To translate by a *relative* offset instead, use [`lerp`][super::Lerp::lerp].
110+ fn approach ( & self , other : & Self , d : f32 ) -> Self ;
111+ }
112+
95113/// Tag type for real vector spaces and Euclidean spaces.
96114///
97115/// For example, the type `Real<3>` corresponds to ℝ³.
@@ -136,6 +154,26 @@ impl Linear for f32 {
136154 }
137155}
138156
157+ impl Euclidean for f32 {
158+ fn origin ( ) -> Self {
159+ 0.0
160+ }
161+
162+ fn distance ( & self , other : & Self ) -> f32 {
163+ ( other - self ) . abs ( )
164+ }
165+
166+ fn approach ( & self , other : & Self , d : f32 ) -> Self {
167+ let diff = other - self ;
168+ let dist = diff. abs ( ) ;
169+ if d < dist && dist != 0.0 {
170+ self + d * diff. signum ( )
171+ } else {
172+ * other
173+ }
174+ }
175+ }
176+
139177impl Affine for i32 {
140178 type Space = ( ) ;
141179 type Diff = Self ;
0 commit comments