diff --git a/src/point.rs b/src/point.rs index f37a6ce..94c8ce7 100644 --- a/src/point.rs +++ b/src/point.rs @@ -68,7 +68,16 @@ impl Point3 { } /// Specifies the numeric operations for point types. -pub trait Point>: Array1 + Clone { +pub trait Point>: Array1 + Clone // where + // FIXME: blocked by rust-lang/rust#20671 + // + // for<'a, 'b> &'a Self: Add<&'b V, Output = Self>, + // for<'a, 'b> &'a Self: Sub<&'b Self, Output = V>, + // + // for<'a> &'a Self: Mul, + // for<'a> &'a Self: Div, + // for<'a> &'a Self: Rem, +{ /// Create a point at the origin. fn origin() -> Self; @@ -131,30 +140,11 @@ impl Point> for Point2 { Vector2::new(self.x, self.y) } - #[inline] - fn mul_s(&self, s: S) -> Point2 { - Point2::new(self.x * s, self.y * s) - } - - #[inline] - fn div_s(&self, s: S) -> Point2 { - Point2::new(self.x / s, self.y / s) - } - - #[inline] - fn rem_s(&self, s: S) -> Point2 { - Point2::new(self.x % s, self.y % s) - } - - #[inline] - fn add_v(&self, v: &Vector2) -> Point2 { - Point2::new(self.x + v.x, self.y + v.y) - } - - #[inline] - fn sub_p(&self, p: &Point2) -> Vector2 { - Vector2::new(self.x - p.x, self.y - p.y) - } + #[inline] fn mul_s(&self, s: S) -> Point2 { self * s } + #[inline] fn div_s(&self, s: S) -> Point2 { self / s } + #[inline] fn rem_s(&self, s: S) -> Point2 { self % s } + #[inline] fn add_v(&self, v: &Vector2) -> Point2 { self + v } + #[inline] fn sub_p(&self, p: &Point2) -> Vector2 { self - p } #[inline] fn mul_self_s(&mut self, s: S) { @@ -223,30 +213,11 @@ impl Point> for Point3 { Vector3::new(self.x, self.y, self.z) } - #[inline] - fn mul_s(&self, s: S) -> Point3 { - Point3::new(self.x * s, self.y * s, self.z * s) - } - - #[inline] - fn div_s(&self, s: S) -> Point3 { - Point3::new(self.x / s, self.y / s, self.z / s) - } - - #[inline] - fn rem_s(&self, s: S) -> Point3 { - Point3::new(self.x % s, self.y % s, self.z % s) - } - - #[inline] - fn add_v(&self, v: &Vector3) -> Point3 { - Point3::new(self.x + v.x, self.y + v.y, self.z + v.z) - } - - #[inline] - fn sub_p(&self, p: &Point3) -> Vector3 { - Vector3::new(self.x - p.x, self.y - p.y, self.z - p.z) - } + #[inline] fn mul_s(&self, s: S) -> Point3 { self * s } + #[inline] fn div_s(&self, s: S) -> Point3 { self / s } + #[inline] fn rem_s(&self, s: S) -> Point3 { self % s } + #[inline] fn add_v(&self, v: &Vector3) -> Point3 { self + v } + #[inline] fn sub_p(&self, p: &Point3) -> Vector3 { self - p } #[inline] fn mul_self_s(&mut self, s: S) { @@ -303,6 +274,59 @@ impl ApproxEq for Point3 { } } + +macro_rules! impl_operators { + ($PointN:ident { $($field:ident),+ }, $VectorN:ident) => { + impl<'a, S: BaseNum> Mul for &'a $PointN { + type Output = $PointN; + + #[inline] + fn mul(self, s: S) -> $PointN { + $PointN::new($(self.$field * s),+) + } + } + + impl<'a, S: BaseNum> Div for &'a $PointN { + type Output = $PointN; + + #[inline] + fn div(self, s: S) -> $PointN { + $PointN::new($(self.$field / s),+) + } + } + + impl<'a, S: BaseNum> Rem for &'a $PointN { + type Output = $PointN; + + #[inline] + fn rem(self, s: S) -> $PointN { + $PointN::new($(self.$field % s),+) + } + } + + impl<'a, 'b, S: BaseNum> Add<&'a $VectorN> for &'b $PointN { + type Output = $PointN; + + #[inline] + fn add(self, v: &'a $VectorN) -> $PointN { + $PointN::new($(self.$field + v.$field),+) + } + } + + impl<'a, 'b, S: BaseNum> Sub<&'a $PointN> for &'b $PointN { + type Output = $VectorN; + + #[inline] + fn sub(self, p: &'a $PointN) -> $VectorN { + $VectorN::new($(self.$field - p.$field),+) + } + } + } +} + +impl_operators!(Point2 { x, y }, Vector2); +impl_operators!(Point3 { x, y, z }, Vector3); + macro_rules! fixed_array_conversions { ($PointN:ident <$S:ident> { $($field:ident : $index:expr),+ }, $n:expr) => { impl<$S> Into<[$S; $n]> for $PointN<$S> {