From 25aea84e0d9b970245aca4ff2c2c2ffaa465e55b Mon Sep 17 00:00:00 2001 From: Brendan Zabarauskas Date: Tue, 3 Nov 2015 14:30:59 +1100 Subject: [PATCH] Make scalar an an associated type on Vector --- src/matrix.rs | 2 +- src/point.rs | 2 +- src/vector.rs | 73 +++++++++++++++++++++++++++------------------------ 3 files changed, 40 insertions(+), 37 deletions(-) diff --git a/src/matrix.rs b/src/matrix.rs index 5b05ab8..21f448a 100644 --- a/src/matrix.rs +++ b/src/matrix.rs @@ -249,7 +249,7 @@ impl> Matrix4 { } } -pub trait Matrix> where +pub trait Matrix> where Self: Array2, Self: ApproxEq + Sized, // FIXME: blocked by rust-lang/rust#20671 diff --git a/src/point.rs b/src/point.rs index 809c94d..11756ce 100644 --- a/src/point.rs +++ b/src/point.rs @@ -77,7 +77,7 @@ pub trait Point: Array1 + Clone // where // for<'a> &'a Self: Rem, { /// The associated displacement vector. - type Vector: Vector; + type Vector: Vector; /// Create a point at the origin. fn origin() -> Self; diff --git a/src/vector.rs b/src/vector.rs index 77e63f1..fdd08be 100644 --- a/src/vector.rs +++ b/src/vector.rs @@ -111,7 +111,7 @@ use num::{BaseNum, BaseFloat}; /// 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 /// for pragmatic reasons. -pub trait Vector: Array1 + Clone // where +pub trait Vector: Array1::Scalar> + Clone // where // FIXME: blocked by rust-lang/rust#20671 // // for<'a, 'b> &'a Self: Add<&'b Self, Output = Self>, @@ -127,31 +127,34 @@ pub trait Vector: Array1 + Clone // where // for<'a> &'a Self: Div, // for<'a> &'a Self: Rem, { + // The associated scalar + type Scalar: BaseNum; + /// 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) #[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) #[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. #[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. #[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. #[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. #[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. #[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. #[must_use] @@ -170,15 +173,15 @@ pub trait Vector: Array1 + Clone // where fn rem_v(&self, v: &Self) -> Self; /// 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. - 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. - 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. - 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. - 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. fn add_self_v(&mut self, v: &Self); @@ -192,22 +195,22 @@ pub trait Vector: Array1 + Clone // where fn rem_self_v(&mut self, v: &Self); /// 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. - fn product(&self) -> S; + fn product(&self) -> Self::Scalar; /// Vector dot product. #[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. - fn comp_min(&self) -> S; + fn comp_min(&self) -> Self::Scalar; /// The maximum component of the vector. - fn comp_max(&self) -> S; + fn comp_max(&self) -> Self::Scalar; } /// Dot product of two vectors. -#[inline] pub fn dot>(a: V, b: V) -> S { a.dot(&b) } +#[inline] pub fn dot(a: V, b: V) -> V::Scalar { a.dot(&b) } // Utility macro for generating associated functions for the vectors macro_rules! vec { @@ -249,14 +252,16 @@ macro_rules! vec { type Element = S; } - impl Vector for $VectorN { - #[inline] fn from_value(s: S) -> $VectorN { $VectorN { $($field: s),+ } } + impl Vector for $VectorN { + type Scalar = S; - #[inline] fn add_s(&self, s: S) -> $VectorN { self + s } - #[inline] fn sub_s(&self, s: S) -> $VectorN { self - s } - #[inline] fn mul_s(&self, s: S) -> $VectorN { self * s } - #[inline] fn div_s(&self, s: S) -> $VectorN { self / s } - #[inline] fn rem_s(&self, s: S) -> $VectorN { self % s } + #[inline] fn from_value(scalar: S) -> $VectorN { $VectorN { $($field: scalar),+ } } + + #[inline] fn add_s(&self, scalar: S) -> $VectorN { self + scalar } + #[inline] fn sub_s(&self, scalar: S) -> $VectorN { self - scalar } + #[inline] fn mul_s(&self, scalar: S) -> $VectorN { self * scalar } + #[inline] fn div_s(&self, scalar: S) -> $VectorN { self / scalar } + #[inline] fn rem_s(&self, scalar: S) -> $VectorN { self % scalar } #[inline] fn add_v(&self, v: &$VectorN) -> $VectorN { self + v } #[inline] fn sub_v(&self, v: &$VectorN) -> $VectorN { self - v } @@ -264,11 +269,11 @@ macro_rules! vec { #[inline] fn div_v(&self, v: &$VectorN) -> $VectorN { self / v } #[inline] fn rem_v(&self, v: &$VectorN) -> $VectorN { self % v } - #[inline] fn add_self_s(&mut self, s: S) { *self = &*self + s; } - #[inline] fn sub_self_s(&mut self, s: S) { *self = &*self - s; } - #[inline] fn mul_self_s(&mut self, s: S) { *self = &*self * s; } - #[inline] fn div_self_s(&mut self, s: S) { *self = &*self / s; } - #[inline] fn rem_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, scalar: S) { *self = &*self - scalar; } + #[inline] fn mul_self_s(&mut self, scalar: S) { *self = &*self * scalar; } + #[inline] fn div_self_s(&mut self, scalar: S) { *self = &*self / scalar; } + #[inline] fn rem_self_s(&mut self, scalar: S) { *self = &*self % scalar; } #[inline] fn add_self_v(&mut self, v: &$VectorN) { *self = &*self + v; } #[inline] fn sub_self_v(&mut self, v: &$VectorN) { *self = &*self - v; } @@ -621,9 +626,7 @@ impl Vector4 { /// Specifies geometric operations for vectors. This is only implemented for /// 2-dimensional and 3-dimensional vectors. -pub trait EuclideanVector: Vector - + ApproxEq - + Sized { +pub trait EuclideanVector: Vector + ApproxEq::Scalar> + Sized { /// Returns `true` if the vector is perpendicular (at right angles) to the /// other vector. fn is_perpendicular(&self, other: &Self) -> bool {