Implement binary operators for points

We can't yet remove the operator methods, due to rust-lang/rust#20671
This commit is contained in:
Brendan Zabarauskas 2015-09-30 18:23:01 +10:00
parent be5c6fb55b
commit 8b6fb94685

View file

@ -68,7 +68,16 @@ impl<S: BaseNum> Point3<S> {
}
/// Specifies the numeric operations for point types.
pub trait Point<S: BaseNum, V: Vector<S>>: Array1<S> + Clone {
pub trait Point<S: BaseNum, V: Vector<S>>: Array1<S> + 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<S, Output = Self>,
// for<'a> &'a Self: Div<S, Output = Self>,
// for<'a> &'a Self: Rem<S, Output = Self>,
{
/// Create a point at the origin.
fn origin() -> Self;
@ -131,30 +140,11 @@ impl<S: BaseNum> Point<S, Vector2<S>> for Point2<S> {
Vector2::new(self.x, self.y)
}
#[inline]
fn mul_s(&self, s: S) -> Point2<S> {
Point2::new(self.x * s, self.y * s)
}
#[inline]
fn div_s(&self, s: S) -> Point2<S> {
Point2::new(self.x / s, self.y / s)
}
#[inline]
fn rem_s(&self, s: S) -> Point2<S> {
Point2::new(self.x % s, self.y % s)
}
#[inline]
fn add_v(&self, v: &Vector2<S>) -> Point2<S> {
Point2::new(self.x + v.x, self.y + v.y)
}
#[inline]
fn sub_p(&self, p: &Point2<S>) -> Vector2<S> {
Vector2::new(self.x - p.x, self.y - p.y)
}
#[inline] fn mul_s(&self, s: S) -> Point2<S> { self * s }
#[inline] fn div_s(&self, s: S) -> Point2<S> { self / s }
#[inline] fn rem_s(&self, s: S) -> Point2<S> { self % s }
#[inline] fn add_v(&self, v: &Vector2<S>) -> Point2<S> { self + v }
#[inline] fn sub_p(&self, p: &Point2<S>) -> Vector2<S> { self - p }
#[inline]
fn mul_self_s(&mut self, s: S) {
@ -223,30 +213,11 @@ impl<S: BaseNum> Point<S, Vector3<S>> for Point3<S> {
Vector3::new(self.x, self.y, self.z)
}
#[inline]
fn mul_s(&self, s: S) -> Point3<S> {
Point3::new(self.x * s, self.y * s, self.z * s)
}
#[inline]
fn div_s(&self, s: S) -> Point3<S> {
Point3::new(self.x / s, self.y / s, self.z / s)
}
#[inline]
fn rem_s(&self, s: S) -> Point3<S> {
Point3::new(self.x % s, self.y % s, self.z % s)
}
#[inline]
fn add_v(&self, v: &Vector3<S>) -> Point3<S> {
Point3::new(self.x + v.x, self.y + v.y, self.z + v.z)
}
#[inline]
fn sub_p(&self, p: &Point3<S>) -> Vector3<S> {
Vector3::new(self.x - p.x, self.y - p.y, self.z - p.z)
}
#[inline] fn mul_s(&self, s: S) -> Point3<S> { self * s }
#[inline] fn div_s(&self, s: S) -> Point3<S> { self / s }
#[inline] fn rem_s(&self, s: S) -> Point3<S> { self % s }
#[inline] fn add_v(&self, v: &Vector3<S>) -> Point3<S> { self + v }
#[inline] fn sub_p(&self, p: &Point3<S>) -> Vector3<S> { self - p }
#[inline]
fn mul_self_s(&mut self, s: S) {
@ -303,6 +274,59 @@ impl<S: BaseFloat> ApproxEq<S> for Point3<S> {
}
}
macro_rules! impl_operators {
($PointN:ident { $($field:ident),+ }, $VectorN:ident) => {
impl<'a, S: BaseNum> Mul<S> for &'a $PointN<S> {
type Output = $PointN<S>;
#[inline]
fn mul(self, s: S) -> $PointN<S> {
$PointN::new($(self.$field * s),+)
}
}
impl<'a, S: BaseNum> Div<S> for &'a $PointN<S> {
type Output = $PointN<S>;
#[inline]
fn div(self, s: S) -> $PointN<S> {
$PointN::new($(self.$field / s),+)
}
}
impl<'a, S: BaseNum> Rem<S> for &'a $PointN<S> {
type Output = $PointN<S>;
#[inline]
fn rem(self, s: S) -> $PointN<S> {
$PointN::new($(self.$field % s),+)
}
}
impl<'a, 'b, S: BaseNum> Add<&'a $VectorN<S>> for &'b $PointN<S> {
type Output = $PointN<S>;
#[inline]
fn add(self, v: &'a $VectorN<S>) -> $PointN<S> {
$PointN::new($(self.$field + v.$field),+)
}
}
impl<'a, 'b, S: BaseNum> Sub<&'a $PointN<S>> for &'b $PointN<S> {
type Output = $VectorN<S>;
#[inline]
fn sub(self, p: &'a $PointN<S>) -> $VectorN<S> {
$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> {