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.
#[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();
(*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.
#[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)
}
/// Returns the squared distance between two points.
#[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)
}

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]
fn to_vec(self) -> $tv<N> {
self.to_vec()
@ -132,11 +134,11 @@ macro_rules! pnt_from_homogeneous_impl(
macro_rules! num_float_pnt_impl(
($t: ident, $tv: ident) => (
impl<N> NumPnt<N, $tv<N>> for $t<N>
impl<N> NumPnt<N> for $t<N>
where N: BaseNum {
}
impl<N> FloatPnt<N, $tv<N>> for $t<N>
impl<N> FloatPnt<N> for $t<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.
*/
/// 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.
fn to_vec(self) -> V;
fn to_vec(self) -> Self::Vec;
/// 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
// done on rustc.
/// 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.
// 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.
pub trait NumPnt<N, V>:
pub trait NumPnt<N>:
Copy +
PntAsVec<V> +
PntAsVec +
Dim +
Orig +
PartialEq +
Axpy<N> +
Sub<Self, Output = V> +
Sub<Self, Output = <Self as PntAsVec>::Vec> +
Mul<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>
}
/// 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.
#[inline]
fn sqdist(&self, other: &Self) -> N {