summaryrefslogtreecommitdiff
path: root/src/geometry/vec.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/geometry/vec.rs')
-rw-r--r--src/geometry/vec.rs182
1 files changed, 42 insertions, 140 deletions
diff --git a/src/geometry/vec.rs b/src/geometry/vec.rs
index c99cf5e..375a0f9 100644
--- a/src/geometry/vec.rs
+++ b/src/geometry/vec.rs
@@ -1,160 +1,62 @@
use std::ops::*;
-use num_traits::{NumOps, NumAssignOps, Signed};
-use num_traits::pow::Pow;
-use num_traits::real::Real;
-macro_rules! fold_array {
- ($method:ident, { $x:expr }) => { $x };
- ($method:ident, { $x:expr, $y:expr }) => { $x.$method($y) };
- ($method:ident, { $x:expr, $y:expr, $z:expr }) => { $x.$method($y).$method($z) };
+#[derive(Debug, Default, Clone, Copy, Hash, PartialEq, Eq)]
+pub struct Vec2d {
+ pub x: i8,
+ pub y: i8,
}
-macro_rules! impl_vector {
- ($VecN:ident { $($field:ident),+ }) => {
- #[derive(Debug, Default, Clone, Copy, Hash, PartialEq, Eq)]
- pub struct $VecN<T> {
- $(pub $field: T),+
- }
-
- impl<T> $VecN<T> {
- pub const fn new($($field: T),+) -> $VecN<T> {
- $VecN { $($field),+ }
- }
- }
-
- impl<T: NumOps + Ord + Signed + Copy> $VecN<T> {
- pub fn walking_distance(&self) -> T {
- fold_array!(max, { $(self.$field.abs()),+ })
- }
- }
-
- impl<T: NumOps + Pow<u8, Output=T> + Copy> $VecN<T> {
- pub fn magnitude_squared(&self) -> T {
- fold_array!(add, { $(self.$field.pow(2)),+ })
- }
- }
-
- impl<T: Real + Pow<u8, Output=T>> $VecN<T> {
- pub fn magnitude(&self) -> T {
- self.magnitude_squared().sqrt()
- }
-
- pub fn unit(&self) -> $VecN<T> {
- let mag = self.magnitude();
- $VecN {
- $($field: self.$field / mag),+
- }
- }
- }
-
- impl<T: NumOps + Copy> $VecN<T> {
- pub fn dot(&self, other: $VecN<T>) -> T {
- fold_array!(add, { $(self.$field * other.$field),+ })
- }
- }
-
- impl<T: NumOps> Add for $VecN<T> {
- type Output = Self;
-
- fn add(self, other: Self) -> Self {
- $VecN {
- $($field: self.$field + other.$field),+
- }
- }
- }
-
- impl<T: NumAssignOps> AddAssign for $VecN<T> {
- fn add_assign(&mut self, other: Self) {
- $(self.$field += other.$field);+
- }
- }
-
- impl<T: NumOps> Sub for $VecN<T> {
- type Output = Self;
-
- fn sub(self, other: Self) -> Self {
- $VecN {
- $($field: self.$field - other.$field),+
- }
- }
- }
-
- impl<T: NumOps + Copy> Mul<T> for $VecN<T> {
- type Output = Self;
-
- fn mul(self, rhs: T) -> Self {
- $VecN {
- $($field: self.$field * rhs),+
- }
- }
- }
-
- impl<T: Neg<Output=T>> Neg for $VecN<T> {
- type Output = Self;
-
- fn neg(self) -> Self {
- $VecN {
- $($field: -self.$field),+
- }
- }
- }
-
+impl Vec2d {
+ pub const fn new(x: i8, y: i8) -> Vec2d {
+ Vec2d { x, y }
+ }
+ pub fn magnitude_squared(&self) -> i8 {
+ self.x
+ .saturating_pow(2)
+ .saturating_add(self.y.saturating_pow(2))
}
}
-impl_vector!(Vec2d { x, y });
-impl_vector!(Vec3d { x, y, z });
+impl Add for Vec2d {
+ type Output = Self;
-impl<T: Real + Pow<u8, Output=T>> Vec2d<T> {
- pub fn angle(&self) -> T {
- self.y.atan2(self.x)
+ fn add(self, other: Self) -> Self {
+ Vec2d {
+ x: self.x.saturating_add(other.x),
+ y: self.y.saturating_add(other.y),
+ }
}
}
+impl Sub for Vec2d {
+ type Output = Self;
-#[cfg(test)]
-mod tests {
- use super::*;
-
- #[test]
- fn right_angles_in_2d_vectors() {
- use std::f32::consts::{FRAC_PI_2, PI};
-
- assert_eq!(0., Vec2d::new(1., 0.).angle());
- assert_eq!(FRAC_PI_2, Vec2d::new(0., 1.).angle());
- assert_eq!(PI, Vec2d::new(-1., 0.).angle());
- assert_eq!(-FRAC_PI_2, Vec2d::new(0., -1.).angle());
+ fn sub(self, other: Self) -> Self {
+ Vec2d {
+ x: self.x.saturating_sub(other.x),
+ y: self.y.saturating_sub(other.y),
+ }
}
+}
- #[test]
- fn unit_normalizes_2d_vector() {
- let before = Vec2d::new(2., 10.);
- let after = before.unit();
+impl Mul<i8> for Vec2d {
+ type Output = Self;
- assert_eq!(1., after.magnitude());
- assert_eq!(before.angle(), after.angle());
+ fn mul(self, other: i8) -> Self {
+ Vec2d {
+ x: self.x.saturating_mul(other),
+ y: self.y.saturating_mul(other),
+ }
}
+}
- #[test]
- fn unit_normalizes_3d_vector() {
- let before = Vec3d::new(2., 10., -5.);
- let after = before.unit();
-
- assert_eq!(1., after.magnitude());
- // How to define 3d angle? 2 angles I suppose?
- // assert_eq!(before.angle(), after.angle());
- }
-
- #[test]
- fn dot_product_example_2d() {
- let a = Vec2d::new(-6., 8.);
- let b = Vec2d::new(5., 12.);
- assert_eq!(66., a.dot(b));
- }
+impl Neg for Vec2d {
+ type Output = Self;
- #[test]
- fn magnitude_squared_of_an_integer() {
- let a = Vec2d::new(3, 4);
- assert_eq!(25, a.magnitude_squared());
+ fn neg(self) -> Self {
+ Vec2d {
+ x: -self.x,
+ y: -self.y,
+ }
}
}