Make scalar an an associated type on Vector

This commit is contained in:
Brendan Zabarauskas 2015-11-03 14:30:59 +11:00
parent a434f18ba4
commit 25aea84e0d
3 changed files with 40 additions and 37 deletions

View file

@ -249,7 +249,7 @@ impl<S: Copy + Neg<Output = S>> Matrix4<S> {
} }
} }
pub trait Matrix<S: BaseFloat, V: Vector<S>> where pub trait Matrix<S: BaseFloat, V: Vector<Scalar = S>> where
Self: Array2<Element = S, Column = V, Row = V>, Self: Array2<Element = S, Column = V, Row = V>,
Self: ApproxEq<Epsilon = S> + Sized, Self: ApproxEq<Epsilon = S> + Sized,
// FIXME: blocked by rust-lang/rust#20671 // FIXME: blocked by rust-lang/rust#20671

View file

@ -77,7 +77,7 @@ pub trait Point<S: BaseNum>: Array1<Element = S> + Clone // where
// for<'a> &'a Self: Rem<S, Output = Self>, // for<'a> &'a Self: Rem<S, Output = Self>,
{ {
/// The associated displacement vector. /// The associated displacement vector.
type Vector: Vector<S>; type Vector: Vector<Scalar = S>;
/// Create a point at the origin. /// Create a point at the origin.
fn origin() -> Self; fn origin() -> Self;

View file

@ -111,7 +111,7 @@ use num::{BaseNum, BaseFloat};
/// A trait that specifies a range of numeric operations for vectors. Not all /// A trait that specifies a range of numeric operations for vectors. Not all
/// of these make sense from a linear algebra point of view, but are included /// of these make sense from a linear algebra point of view, but are included
/// for pragmatic reasons. /// for pragmatic reasons.
pub trait Vector<S: BaseNum>: Array1<Element = S> + Clone // where pub trait Vector: Array1<Element = <Self as Vector>::Scalar> + Clone // where
// FIXME: blocked by rust-lang/rust#20671 // FIXME: blocked by rust-lang/rust#20671
// //
// for<'a, 'b> &'a Self: Add<&'b Self, Output = Self>, // for<'a, 'b> &'a Self: Add<&'b Self, Output = Self>,
@ -127,31 +127,34 @@ pub trait Vector<S: BaseNum>: Array1<Element = S> + Clone // where
// for<'a> &'a Self: Div<S, Output = Self>, // for<'a> &'a Self: Div<S, Output = Self>,
// for<'a> &'a Self: Rem<S, Output = Self>, // for<'a> &'a Self: Rem<S, Output = Self>,
{ {
// The associated scalar
type Scalar: BaseNum;
/// Construct a vector from a single value, replicating it. /// Construct a vector from a single value, replicating it.
fn from_value(s: S) -> Self; fn from_value(scalar: Self::Scalar) -> Self;
/// The zero vector (with all components set to zero) /// The zero vector (with all components set to zero)
#[inline] #[inline]
fn zero() -> Self { Self::from_value(S::zero()) } fn zero() -> Self { Self::from_value(Self::Scalar::zero()) }
/// The identity vector (with all components set to one) /// The identity vector (with all components set to one)
#[inline] #[inline]
fn one() -> Self { Self::from_value(S::one()) } fn one() -> Self { Self::from_value(Self::Scalar::one()) }
/// Add a scalar to this vector, returning a new vector. /// Add a scalar to this vector, returning a new vector.
#[must_use] #[must_use]
fn add_s(&self, s: S) -> Self; fn add_s(&self, scalar: Self::Scalar) -> Self;
/// Subtract a scalar from this vector, returning a new vector. /// Subtract a scalar from this vector, returning a new vector.
#[must_use] #[must_use]
fn sub_s(&self, s: S) -> Self; fn sub_s(&self, scalar: Self::Scalar) -> Self;
/// Multiply this vector by a scalar, returning a new vector. /// Multiply this vector by a scalar, returning a new vector.
#[must_use] #[must_use]
fn mul_s(&self, s: S) -> Self; fn mul_s(&self, scalar: Self::Scalar) -> Self;
/// Divide this vector by a scalar, returning a new vector. /// Divide this vector by a scalar, returning a new vector.
#[must_use] #[must_use]
fn div_s(&self, s: S) -> Self; fn div_s(&self, scalar: Self::Scalar) -> Self;
/// Take the remainder of this vector by a scalar, returning a new vector. /// Take the remainder of this vector by a scalar, returning a new vector.
#[must_use] #[must_use]
fn rem_s(&self, s: S) -> Self; fn rem_s(&self, scalar: Self::Scalar) -> Self;
/// Add this vector to another, returning a new vector. /// Add this vector to another, returning a new vector.
#[must_use] #[must_use]
@ -170,15 +173,15 @@ pub trait Vector<S: BaseNum>: Array1<Element = S> + Clone // where
fn rem_v(&self, v: &Self) -> Self; fn rem_v(&self, v: &Self) -> Self;
/// Add a scalar to this vector in-place. /// Add a scalar to this vector in-place.
fn add_self_s(&mut self, s: S); fn add_self_s(&mut self, scalar: Self::Scalar);
/// Subtract a scalar from this vector, in-place. /// Subtract a scalar from this vector, in-place.
fn sub_self_s(&mut self, s: S); fn sub_self_s(&mut self, scalar: Self::Scalar);
/// Multiply this vector by a scalar, in-place. /// Multiply this vector by a scalar, in-place.
fn mul_self_s(&mut self, s: S); fn mul_self_s(&mut self, scalar: Self::Scalar);
/// Divide this vector by a scalar, in-place. /// Divide this vector by a scalar, in-place.
fn div_self_s(&mut self, s: S); fn div_self_s(&mut self, scalar: Self::Scalar);
/// Take the remainder of this vector by a scalar, in-place. /// Take the remainder of this vector by a scalar, in-place.
fn rem_self_s(&mut self, s: S); fn rem_self_s(&mut self, scalar: Self::Scalar);
/// Add another vector to this one, in-place. /// Add another vector to this one, in-place.
fn add_self_v(&mut self, v: &Self); fn add_self_v(&mut self, v: &Self);
@ -192,22 +195,22 @@ pub trait Vector<S: BaseNum>: Array1<Element = S> + Clone // where
fn rem_self_v(&mut self, v: &Self); fn rem_self_v(&mut self, v: &Self);
/// The sum of the components of the vector. /// The sum of the components of the vector.
fn sum(&self) -> S; fn sum(&self) -> Self::Scalar;
/// The product of the components of the vector. /// The product of the components of the vector.
fn product(&self) -> S; fn product(&self) -> Self::Scalar;
/// Vector dot product. /// Vector dot product.
#[inline] #[inline]
fn dot(&self, v: &Self) -> S { self.mul_v(v).sum() } fn dot(&self, v: &Self) -> Self::Scalar { self.mul_v(v).sum() }
/// The minimum component of the vector. /// The minimum component of the vector.
fn comp_min(&self) -> S; fn comp_min(&self) -> Self::Scalar;
/// The maximum component of the vector. /// The maximum component of the vector.
fn comp_max(&self) -> S; fn comp_max(&self) -> Self::Scalar;
} }
/// Dot product of two vectors. /// Dot product of two vectors.
#[inline] pub fn dot<S: BaseNum, V: Vector<S>>(a: V, b: V) -> S { a.dot(&b) } #[inline] pub fn dot<V: Vector>(a: V, b: V) -> V::Scalar { a.dot(&b) }
// Utility macro for generating associated functions for the vectors // Utility macro for generating associated functions for the vectors
macro_rules! vec { macro_rules! vec {
@ -249,14 +252,16 @@ macro_rules! vec {
type Element = S; type Element = S;
} }
impl<S: BaseNum> Vector<S> for $VectorN<S> { impl<S: BaseNum> Vector for $VectorN<S> {
#[inline] fn from_value(s: S) -> $VectorN<S> { $VectorN { $($field: s),+ } } type Scalar = S;
#[inline] fn add_s(&self, s: S) -> $VectorN<S> { self + s } #[inline] fn from_value(scalar: S) -> $VectorN<S> { $VectorN { $($field: scalar),+ } }
#[inline] fn sub_s(&self, s: S) -> $VectorN<S> { self - s }
#[inline] fn mul_s(&self, s: S) -> $VectorN<S> { self * s } #[inline] fn add_s(&self, scalar: S) -> $VectorN<S> { self + scalar }
#[inline] fn div_s(&self, s: S) -> $VectorN<S> { self / s } #[inline] fn sub_s(&self, scalar: S) -> $VectorN<S> { self - scalar }
#[inline] fn rem_s(&self, s: S) -> $VectorN<S> { self % s } #[inline] fn mul_s(&self, scalar: S) -> $VectorN<S> { self * scalar }
#[inline] fn div_s(&self, scalar: S) -> $VectorN<S> { self / scalar }
#[inline] fn rem_s(&self, scalar: S) -> $VectorN<S> { self % scalar }
#[inline] fn add_v(&self, v: &$VectorN<S>) -> $VectorN<S> { self + v } #[inline] fn add_v(&self, v: &$VectorN<S>) -> $VectorN<S> { self + v }
#[inline] fn sub_v(&self, v: &$VectorN<S>) -> $VectorN<S> { self - v } #[inline] fn sub_v(&self, v: &$VectorN<S>) -> $VectorN<S> { self - v }
@ -264,11 +269,11 @@ macro_rules! vec {
#[inline] fn div_v(&self, v: &$VectorN<S>) -> $VectorN<S> { self / v } #[inline] fn div_v(&self, v: &$VectorN<S>) -> $VectorN<S> { self / v }
#[inline] fn rem_v(&self, v: &$VectorN<S>) -> $VectorN<S> { self % v } #[inline] fn rem_v(&self, v: &$VectorN<S>) -> $VectorN<S> { self % v }
#[inline] fn add_self_s(&mut self, s: S) { *self = &*self + s; } #[inline] fn add_self_s(&mut self, scalar: S) { *self = &*self + scalar; }
#[inline] fn sub_self_s(&mut self, s: S) { *self = &*self - s; } #[inline] fn sub_self_s(&mut self, scalar: S) { *self = &*self - scalar; }
#[inline] fn mul_self_s(&mut self, s: S) { *self = &*self * s; } #[inline] fn mul_self_s(&mut self, scalar: S) { *self = &*self * scalar; }
#[inline] fn div_self_s(&mut self, s: S) { *self = &*self / s; } #[inline] fn div_self_s(&mut self, scalar: S) { *self = &*self / scalar; }
#[inline] fn rem_self_s(&mut self, s: S) { *self = &*self % s; } #[inline] fn rem_self_s(&mut self, scalar: S) { *self = &*self % scalar; }
#[inline] fn add_self_v(&mut self, v: &$VectorN<S>) { *self = &*self + v; } #[inline] fn add_self_v(&mut self, v: &$VectorN<S>) { *self = &*self + v; }
#[inline] fn sub_self_v(&mut self, v: &$VectorN<S>) { *self = &*self - v; } #[inline] fn sub_self_v(&mut self, v: &$VectorN<S>) { *self = &*self - v; }
@ -621,9 +626,7 @@ impl<S: BaseNum> Vector4<S> {
/// Specifies geometric operations for vectors. This is only implemented for /// Specifies geometric operations for vectors. This is only implemented for
/// 2-dimensional and 3-dimensional vectors. /// 2-dimensional and 3-dimensional vectors.
pub trait EuclideanVector<S: BaseFloat>: Vector<S> pub trait EuclideanVector<S: BaseFloat>: Vector<Scalar = S> + ApproxEq<Epsilon = <Self as Vector>::Scalar> + Sized {
+ ApproxEq<Epsilon = S>
+ Sized {
/// Returns `true` if the vector is perpendicular (at right angles) to the /// Returns `true` if the vector is perpendicular (at right angles) to the
/// other vector. /// other vector.
fn is_perpendicular(&self, other: &Self) -> bool { fn is_perpendicular(&self, other: &Self) -> bool {