Added scalar arithmetic operators for Point types
This commit is contained in:
parent
1e6f615f9e
commit
3febc46d5a
2 changed files with 79 additions and 1 deletions
27
src/point.rs
27
src/point.rs
|
@ -172,6 +172,19 @@ macro_rules! impl_point {
|
||||||
fn rem_assign(&mut self, scalar) { $(self.$field %= scalar);+ }
|
fn rem_assign(&mut self, scalar) { $(self.$field %= scalar);+ }
|
||||||
});
|
});
|
||||||
|
|
||||||
|
impl_scalar_ops!($PointN<usize> { $($field),+ });
|
||||||
|
impl_scalar_ops!($PointN<u8> { $($field),+ });
|
||||||
|
impl_scalar_ops!($PointN<u16> { $($field),+ });
|
||||||
|
impl_scalar_ops!($PointN<u32> { $($field),+ });
|
||||||
|
impl_scalar_ops!($PointN<u64> { $($field),+ });
|
||||||
|
impl_scalar_ops!($PointN<isize> { $($field),+ });
|
||||||
|
impl_scalar_ops!($PointN<i8> { $($field),+ });
|
||||||
|
impl_scalar_ops!($PointN<i16> { $($field),+ });
|
||||||
|
impl_scalar_ops!($PointN<i32> { $($field),+ });
|
||||||
|
impl_scalar_ops!($PointN<i64> { $($field),+ });
|
||||||
|
impl_scalar_ops!($PointN<f32> { $($field),+ });
|
||||||
|
impl_scalar_ops!($PointN<f64> { $($field),+ });
|
||||||
|
|
||||||
impl_index_operators!($PointN<S>, $n, S, usize);
|
impl_index_operators!($PointN<S>, $n, S, usize);
|
||||||
impl_index_operators!($PointN<S>, $n, [S], Range<usize>);
|
impl_index_operators!($PointN<S>, $n, [S], Range<usize>);
|
||||||
impl_index_operators!($PointN<S>, $n, [S], RangeTo<usize>);
|
impl_index_operators!($PointN<S>, $n, [S], RangeTo<usize>);
|
||||||
|
@ -180,6 +193,20 @@ macro_rules! impl_point {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
macro_rules! impl_scalar_ops {
|
||||||
|
($PointN:ident<$S:ident> { $($field:ident),+ }) => {
|
||||||
|
impl_operator!(Mul<$PointN<$S>> for $S {
|
||||||
|
fn mul(scalar, vector) -> $PointN<$S> { $PointN::new($(scalar * vector.$field),+) }
|
||||||
|
});
|
||||||
|
impl_operator!(Div<$PointN<$S>> for $S {
|
||||||
|
fn div(scalar, vector) -> $PointN<$S> { $PointN::new($(scalar / vector.$field),+) }
|
||||||
|
});
|
||||||
|
impl_operator!(Rem<$PointN<$S>> for $S {
|
||||||
|
fn rem(scalar, vector) -> $PointN<$S> { $PointN::new($(scalar % vector.$field),+) }
|
||||||
|
});
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
impl_point!(Point2 { x, y }, Vector2, 2);
|
impl_point!(Point2 { x, y }, Vector2, 2);
|
||||||
impl_point!(Point3 { x, y, z }, Vector3, 3);
|
impl_point!(Point3 { x, y, z }, Vector3, 3);
|
||||||
|
|
||||||
|
|
|
@ -16,11 +16,62 @@
|
||||||
|
|
||||||
extern crate cgmath;
|
extern crate cgmath;
|
||||||
|
|
||||||
use cgmath::Point3;
|
use cgmath::{Point2, Point3};
|
||||||
use cgmath::ApproxEq;
|
use cgmath::ApproxEq;
|
||||||
|
|
||||||
|
macro_rules! impl_test_mul {
|
||||||
|
($PointN:ident { $($field:ident),+ }, $s:expr, $v:expr) => (
|
||||||
|
// point * scalar ops
|
||||||
|
assert_eq!($v * $s, $PointN::new($($v.$field * $s),+));
|
||||||
|
assert_eq!($s * $v, $PointN::new($($s * $v.$field),+));
|
||||||
|
assert_eq!(&$v * $s, $v * $s);
|
||||||
|
assert_eq!($s * &$v, $s * $v);
|
||||||
|
// commutativity
|
||||||
|
assert_eq!($v * $s, $s * $v);
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
macro_rules! impl_test_div {
|
||||||
|
($PointN:ident { $($field:ident),+ }, $s:expr, $v:expr) => (
|
||||||
|
// point / scalar ops
|
||||||
|
assert_eq!($v / $s, $PointN::new($($v.$field / $s),+));
|
||||||
|
assert_eq!($s / $v, $PointN::new($($s / $v.$field),+));
|
||||||
|
assert_eq!(&$v / $s, $v / $s);
|
||||||
|
assert_eq!($s / &$v, $s / $v);
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
macro_rules! impl_test_rem {
|
||||||
|
($PointN:ident { $($field:ident),+ }, $s:expr, $v:expr) => (
|
||||||
|
// point % scalar ops
|
||||||
|
assert_eq!($v % $s, $PointN::new($($v.$field % $s),+));
|
||||||
|
assert_eq!($s % $v, $PointN::new($($s % $v.$field),+));
|
||||||
|
assert_eq!(&$v % $s, $v % $s);
|
||||||
|
assert_eq!($s % &$v, $s % $v);
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_homogeneous() {
|
fn test_homogeneous() {
|
||||||
let p = Point3::new(1.0f64, 2.0f64, 3.0f64);
|
let p = Point3::new(1.0f64, 2.0f64, 3.0f64);
|
||||||
assert!(p.approx_eq(&Point3::from_homogeneous(p.to_homogeneous())));
|
assert!(p.approx_eq(&Point3::from_homogeneous(p.to_homogeneous())));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_mul() {
|
||||||
|
impl_test_mul!(Point3 { x, y, z }, 2.0f32, Point3::new(2.0f32, 4.0, 6.0));
|
||||||
|
impl_test_mul!(Point2 { x, y }, 2.0f32, Point2::new(2.0f32, 4.0));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_div() {
|
||||||
|
impl_test_div!(Point3 { x, y, z }, 2.0f32, Point3::new(2.0f32, 4.0, 6.0));
|
||||||
|
impl_test_div!(Point2 { x, y }, 2.0f32, Point2::new(2.0f32, 4.0));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_rem() {
|
||||||
|
impl_test_rem!(Point3 { x, y, z }, 2.0f32, Point3::new(2.0f32, 4.0, 6.0));
|
||||||
|
impl_test_rem!(Point2 { x, y }, 2.0f32, Point2::new(2.0f32, 4.0));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue