From 3e54b01003aa9d27de8f4ca13c9240fe785ec0e1 Mon Sep 17 00:00:00 2001 From: Justin Worthe Date: Mon, 22 Apr 2019 14:38:40 +0200 Subject: Structures representing game state --- src/geometry/point.rs | 84 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 84 insertions(+) create mode 100644 src/geometry/point.rs (limited to 'src/geometry/point.rs') diff --git a/src/geometry/point.rs b/src/geometry/point.rs new file mode 100644 index 0000000..c34d00f --- /dev/null +++ b/src/geometry/point.rs @@ -0,0 +1,84 @@ +use crate::geometry::vec::*; + +use std::ops::*; +use num_traits::{NumOps, NumAssignOps}; +use num_traits::pow::Pow; +use num_traits::real::Real; + +macro_rules! impl_point { + ($PointN:ident { $($field:ident),+ }, $VecN:ident) => { + #[derive(Debug, Default, Clone, Copy, Hash, PartialEq, Eq)] + pub struct $PointN { + $(pub $field: T),+ + } + + impl $PointN { + pub fn new($($field: T),+) -> $PointN { + $PointN { $($field),+ } + } + } + + impl + Copy> $PointN { + pub fn distance_squared(self, other: $PointN) -> T { + (self - other).magnitude_squared() + } + } + + + impl> $PointN { + pub fn distance(self, other: $PointN) -> T { + (self - other).magnitude() + } + } + + impl Add<$VecN> for $PointN { + type Output = Self; + + fn add(self, other: $VecN) -> Self { + $PointN { + $($field: self.$field + other.$field),+ + } + } + } + + impl AddAssign<$VecN> for $PointN { + fn add_assign(&mut self, other: $VecN) { + $(self.$field += other.$field);+ + } + } + + impl Sub for $PointN { + type Output = $VecN; + + fn sub(self, other: Self) -> $VecN { + $VecN { + $($field: self.$field - other.$field),+ + } + } + } + } +} + +impl_point!(Point2d { x, y }, Vec2d); +impl_point!(Point3d { x, y, z }, Vec3d); + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn distance_in_x_dimension_example() { + let a = Point2d::new(1., 1.); + let b = Point2d::new(3., 1.); + assert_eq!(a.distance(b), 2.); + assert_eq!(a.distance_squared(b), 4.); + } + + #[test] + fn distance_in_y_dimension_example() { + let a = Point2d::new(1., 1.); + let b = Point2d::new(1., 3.); + assert_eq!(b.distance(a), 2.); + assert_eq!(b.distance_squared(a), 4.); + } +} -- cgit v1.2.3