Made PntAsVec use associated types. (#179)

Fix #177
This commit is contained in:
Jeroen Bollen 2016-04-17 09:23:37 +02:00 committed by Sébastien Crozet
parent f8c925c096
commit dea0ccc1fd
3 changed files with 26 additions and 16 deletions

View File

@ -311,9 +311,11 @@ pub fn orig<P: Orig>() -> P {
/// Returns the center of two points. /// Returns the center of two points.
#[inline] #[inline]
pub fn center<N: BaseFloat, P: FloatPnt<N, V>, V: Copy + Norm<N>>(a: &P, b: &P) -> P { pub fn center<N: BaseFloat, P: FloatPnt<N>>(a: &P, b: &P) -> P
where <P as PntAsVec>::Vec: Norm<N>
{
let _2 = one::<N>() + one(); let _2 = one::<N>() + one();
(*a + *b.as_vec()) / _2 (*a + b.to_vec()) / _2
} }
/* /*
@ -321,13 +323,15 @@ pub fn center<N: BaseFloat, P: FloatPnt<N, V>, V: Copy + Norm<N>>(a: &P, b: &P)
*/ */
/// Returns the distance between two points. /// Returns the distance between two points.
#[inline(always)] #[inline(always)]
pub fn dist<N: BaseFloat, P: FloatPnt<N, V>, V: Norm<N>>(a: &P, b: &P) -> N { pub fn dist<N: BaseFloat, P: FloatPnt<N>>(a: &P, b: &P) -> N where <P as PntAsVec>::Vec: Norm<N> {
a.dist(b) a.dist(b)
} }
/// Returns the squared distance between two points. /// Returns the squared distance between two points.
#[inline(always)] #[inline(always)]
pub fn sqdist<N: BaseFloat, P: FloatPnt<N, V>, V: Norm<N>>(a: &P, b: &P) -> N { pub fn sqdist<N: BaseFloat, P: FloatPnt<N>>(a: &P, b: &P) -> N
where <P as PntAsVec>::Vec: Norm<N>
{
a.sqdist(b) a.sqdist(b)
} }

View File

@ -82,7 +82,9 @@ macro_rules! pnt_as_vec_impl(
} }
} }
impl<N> PntAsVec<$tv<N>> for $t<N> { impl<N> PntAsVec for $t<N> {
type Vec = $tv<N>;
#[inline] #[inline]
fn to_vec(self) -> $tv<N> { fn to_vec(self) -> $tv<N> {
self.to_vec() self.to_vec()
@ -132,11 +134,11 @@ macro_rules! pnt_from_homogeneous_impl(
macro_rules! num_float_pnt_impl( macro_rules! num_float_pnt_impl(
($t: ident, $tv: ident) => ( ($t: ident, $tv: ident) => (
impl<N> NumPnt<N, $tv<N>> for $t<N> impl<N> NumPnt<N> for $t<N>
where N: BaseNum { where N: BaseNum {
} }
impl<N> FloatPnt<N, $tv<N>> for $t<N> impl<N> FloatPnt<N> for $t<N>
where N: BaseFloat + ApproxEq<N> { where N: BaseFloat + ApproxEq<N> {
} }
) )

View File

@ -236,38 +236,42 @@ pub trait FloatVec<N: BaseFloat>: NumVec<N> + Norm<N> + Neg<Output = Self> + Bas
* Pnt related traits. * Pnt related traits.
*/ */
/// Trait that relates a point of an affine space to a vector of the associated vector space. /// Trait that relates a point of an affine space to a vector of the associated vector space.
pub trait PntAsVec<V> { pub trait PntAsVec {
/// The vector type of the vector space associated to this point's affine space.
type Vec;
/// Converts this point to its associated vector. /// Converts this point to its associated vector.
fn to_vec(self) -> V; fn to_vec(self) -> Self::Vec;
/// Converts a reference to this point to a reference to its associated vector. /// Converts a reference to this point to a reference to its associated vector.
fn as_vec<'a>(&'a self) -> &'a V; fn as_vec<'a>(&'a self) -> &'a Self::Vec;
// NOTE: this is used in some places to overcome some limitations untill the trait reform is // NOTE: this is used in some places to overcome some limitations untill the trait reform is
// done on rustc. // done on rustc.
/// Sets the coordinates of this point to match those of a given vector. /// Sets the coordinates of this point to match those of a given vector.
fn set_coords(&mut self, coords: V); fn set_coords(&mut self, coords: Self::Vec);
} }
/// Trait grouping most common operations on points. /// Trait grouping most common operations on points.
// XXX: the vector space element `V` should be an associated type. Though this would prevent V from // XXX: the vector space element `V` should be an associated type. Though this would prevent V from
// having bounds (they are not supported yet). So, for now, we will just use a type parameter. // having bounds (they are not supported yet). So, for now, we will just use a type parameter.
pub trait NumPnt<N, V>: pub trait NumPnt<N>:
Copy + Copy +
PntAsVec<V> + PntAsVec +
Dim + Dim +
Orig + Orig +
PartialEq + PartialEq +
Axpy<N> + Axpy<N> +
Sub<Self, Output = V> + Sub<Self, Output = <Self as PntAsVec>::Vec> +
Mul<N, Output = Self> + Mul<N, Output = Self> +
Div<N, Output = Self> + Div<N, Output = Self> +
Add<V, Output = Self> + Add<<Self as PntAsVec>::Vec, Output = Self> +
Index<usize, Output = N> { // FIXME: + Sub<V, Self> Index<usize, Output = N> { // FIXME: + Sub<V, Self>
} }
/// Trait of points with components implementing the `BaseFloat` trait. /// Trait of points with components implementing the `BaseFloat` trait.
pub trait FloatPnt<N: BaseFloat, V: Norm<N>>: NumPnt<N, V> + Sized { pub trait FloatPnt<N: BaseFloat>: NumPnt<N> + Sized
where <Self as PntAsVec>::Vec: Norm<N> {
/// Computes the square distance between two points. /// Computes the square distance between two points.
#[inline] #[inline]
fn sqdist(&self, other: &Self) -> N { fn sqdist(&self, other: &Self) -> N {