use std::ops::{Add, Sub, Mul, Index};
#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)]
pub struct Vec2 {
pub x: i32,
pub y: i32,
}
impl Vec2 {
pub const fn new(x: i32, y: i32) -> Vec2 {
Vec2 {
x: x,
y: y,
}
}
pub fn dist_sq(self, other: Vec2) -> u32 {
(self - other).norm()
}
pub fn norm(self) -> u32 {
(self.x * self.x + self.y * self.y) as u32
}
}
impl Add for Vec2 {
type Output = Vec2;
fn add(self, rhs: Vec2) -> Vec2 {
Vec2 {
x: self.x + rhs.x,
y: self.y + rhs.y,
}
}
}
impl Sub for Vec2 {
type Output = Vec2;
fn sub(self, rhs: Vec2) -> Vec2 {
Vec2 {
x: self.x - rhs.x,
y: self.y - rhs.y,
}
}
}
impl Mul<i32> for Vec2 {
type Output = Vec2;
fn mul(self, rhs: i32) -> Vec2 {
Vec2 {
x: self.x * rhs,
y: self.y * rhs,
}
}
}
pub trait GetPos {
type Output: Copy;
fn get_pos(&self, vec: Vec2) -> Self::Output;
}
impl<T: Copy, I: Index<usize, Output = J>, J: Index<usize, Output = T>> GetPos for I {
type Output = T;
fn get_pos(&self, vec: Vec2) -> T {
self[vec.y as usize][vec.x as usize]
}
}
#[cfg(test)]
mod test {
use super::*;
#[test]
fn test_vec2_ops() {
assert_eq!(Vec2::new(5, 6) + Vec2::new(5, 4), Vec2::new(10, 10));
assert_eq!(Vec2::new(5, 6) - Vec2::new(5, 4), Vec2::new(0, 2));
assert_eq!(Vec2::new(5, 6).norm(), 61);
assert_eq!(Vec2::new(1, 0).dist_sq(Vec2::new(2, 0)), 1);
}
}