Skip to content

Commit 8b6fb94

Browse files
committed
Implement binary operators for points
We can't yet remove the operator methods, due to rust-lang/rust#20671
1 parent be5c6fb commit 8b6fb94

File tree

1 file changed

+73
-49
lines changed

1 file changed

+73
-49
lines changed

src/point.rs

Lines changed: 73 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,16 @@ impl<S: BaseNum> Point3<S> {
6868
}
6969

7070
/// Specifies the numeric operations for point types.
71-
pub trait Point<S: BaseNum, V: Vector<S>>: Array1<S> + Clone {
71+
pub trait Point<S: BaseNum, V: Vector<S>>: Array1<S> + Clone // where
72+
// FIXME: blocked by rust-lang/rust#20671
73+
//
74+
// for<'a, 'b> &'a Self: Add<&'b V, Output = Self>,
75+
// for<'a, 'b> &'a Self: Sub<&'b Self, Output = V>,
76+
//
77+
// for<'a> &'a Self: Mul<S, Output = Self>,
78+
// for<'a> &'a Self: Div<S, Output = Self>,
79+
// for<'a> &'a Self: Rem<S, Output = Self>,
80+
{
7281
/// Create a point at the origin.
7382
fn origin() -> Self;
7483

@@ -131,30 +140,11 @@ impl<S: BaseNum> Point<S, Vector2<S>> for Point2<S> {
131140
Vector2::new(self.x, self.y)
132141
}
133142

134-
#[inline]
135-
fn mul_s(&self, s: S) -> Point2<S> {
136-
Point2::new(self.x * s, self.y * s)
137-
}
138-
139-
#[inline]
140-
fn div_s(&self, s: S) -> Point2<S> {
141-
Point2::new(self.x / s, self.y / s)
142-
}
143-
144-
#[inline]
145-
fn rem_s(&self, s: S) -> Point2<S> {
146-
Point2::new(self.x % s, self.y % s)
147-
}
148-
149-
#[inline]
150-
fn add_v(&self, v: &Vector2<S>) -> Point2<S> {
151-
Point2::new(self.x + v.x, self.y + v.y)
152-
}
153-
154-
#[inline]
155-
fn sub_p(&self, p: &Point2<S>) -> Vector2<S> {
156-
Vector2::new(self.x - p.x, self.y - p.y)
157-
}
143+
#[inline] fn mul_s(&self, s: S) -> Point2<S> { self * s }
144+
#[inline] fn div_s(&self, s: S) -> Point2<S> { self / s }
145+
#[inline] fn rem_s(&self, s: S) -> Point2<S> { self % s }
146+
#[inline] fn add_v(&self, v: &Vector2<S>) -> Point2<S> { self + v }
147+
#[inline] fn sub_p(&self, p: &Point2<S>) -> Vector2<S> { self - p }
158148

159149
#[inline]
160150
fn mul_self_s(&mut self, s: S) {
@@ -223,30 +213,11 @@ impl<S: BaseNum> Point<S, Vector3<S>> for Point3<S> {
223213
Vector3::new(self.x, self.y, self.z)
224214
}
225215

226-
#[inline]
227-
fn mul_s(&self, s: S) -> Point3<S> {
228-
Point3::new(self.x * s, self.y * s, self.z * s)
229-
}
230-
231-
#[inline]
232-
fn div_s(&self, s: S) -> Point3<S> {
233-
Point3::new(self.x / s, self.y / s, self.z / s)
234-
}
235-
236-
#[inline]
237-
fn rem_s(&self, s: S) -> Point3<S> {
238-
Point3::new(self.x % s, self.y % s, self.z % s)
239-
}
240-
241-
#[inline]
242-
fn add_v(&self, v: &Vector3<S>) -> Point3<S> {
243-
Point3::new(self.x + v.x, self.y + v.y, self.z + v.z)
244-
}
245-
246-
#[inline]
247-
fn sub_p(&self, p: &Point3<S>) -> Vector3<S> {
248-
Vector3::new(self.x - p.x, self.y - p.y, self.z - p.z)
249-
}
216+
#[inline] fn mul_s(&self, s: S) -> Point3<S> { self * s }
217+
#[inline] fn div_s(&self, s: S) -> Point3<S> { self / s }
218+
#[inline] fn rem_s(&self, s: S) -> Point3<S> { self % s }
219+
#[inline] fn add_v(&self, v: &Vector3<S>) -> Point3<S> { self + v }
220+
#[inline] fn sub_p(&self, p: &Point3<S>) -> Vector3<S> { self - p }
250221

251222
#[inline]
252223
fn mul_self_s(&mut self, s: S) {
@@ -303,6 +274,59 @@ impl<S: BaseFloat> ApproxEq<S> for Point3<S> {
303274
}
304275
}
305276

277+
278+
macro_rules! impl_operators {
279+
($PointN:ident { $($field:ident),+ }, $VectorN:ident) => {
280+
impl<'a, S: BaseNum> Mul<S> for &'a $PointN<S> {
281+
type Output = $PointN<S>;
282+
283+
#[inline]
284+
fn mul(self, s: S) -> $PointN<S> {
285+
$PointN::new($(self.$field * s),+)
286+
}
287+
}
288+
289+
impl<'a, S: BaseNum> Div<S> for &'a $PointN<S> {
290+
type Output = $PointN<S>;
291+
292+
#[inline]
293+
fn div(self, s: S) -> $PointN<S> {
294+
$PointN::new($(self.$field / s),+)
295+
}
296+
}
297+
298+
impl<'a, S: BaseNum> Rem<S> for &'a $PointN<S> {
299+
type Output = $PointN<S>;
300+
301+
#[inline]
302+
fn rem(self, s: S) -> $PointN<S> {
303+
$PointN::new($(self.$field % s),+)
304+
}
305+
}
306+
307+
impl<'a, 'b, S: BaseNum> Add<&'a $VectorN<S>> for &'b $PointN<S> {
308+
type Output = $PointN<S>;
309+
310+
#[inline]
311+
fn add(self, v: &'a $VectorN<S>) -> $PointN<S> {
312+
$PointN::new($(self.$field + v.$field),+)
313+
}
314+
}
315+
316+
impl<'a, 'b, S: BaseNum> Sub<&'a $PointN<S>> for &'b $PointN<S> {
317+
type Output = $VectorN<S>;
318+
319+
#[inline]
320+
fn sub(self, p: &'a $PointN<S>) -> $VectorN<S> {
321+
$VectorN::new($(self.$field - p.$field),+)
322+
}
323+
}
324+
}
325+
}
326+
327+
impl_operators!(Point2 { x, y }, Vector2);
328+
impl_operators!(Point3 { x, y, z }, Vector3);
329+
306330
macro_rules! fixed_array_conversions {
307331
($PointN:ident <$S:ident> { $($field:ident : $index:expr),+ }, $n:expr) => {
308332
impl<$S> Into<[$S; $n]> for $PointN<$S> {

0 commit comments

Comments
 (0)