use std::ops::{Add, Sub};
#[derive(Debug, Copy, Clone)]
pub struct Vec2 {
pub x: f32,
pub y: f32,
}
impl Vec2 {
pub fn new(x: f32, y: f32) -> Vec2 {
Vec2 { x, y }
}
pub fn get_mag_normalized(&self) -> (f32, Vec2) {
let mag = self.magnitude();
let norm_vec = Vec2::new(self.x / mag, self.y / mag);
(mag, norm_vec)
}
pub fn dot(&self, other: Vec2) -> f32 {
self.x * other.x + self.y * other.y
}
pub fn get_orthogonal(&self) -> Vec2 {
Vec2::new(self.y, -self.x)
}
pub fn magnitude(&self) -> f32 {
(self.x * self.x + self.y * self.y).sqrt()
}
pub fn dist_to(&self, other: &Vec2) -> f32 {
(*self - *other).magnitude()
}
}
impl Add for Vec2 {
type Output = Vec2;
fn add(self, other: Vec2) -> Vec2 {
Vec2 {
x: self.x + other.x,
y: self.y + other.y,
}
}
}
impl Sub for Vec2 {
type Output = Vec2;
fn sub(self, other: Vec2) -> Vec2 {
Vec2 {
x: self.x - other.x,
y: self.y - other.y,
}
}
}
impl From<[f32; 2]> for Vec2 {
fn from(v: [f32; 2]) -> Vec2 {
Vec2 { x: v[0], y: v[1] }
}
}
impl From<Vec2> for [f32; 2] {
fn from(v: Vec2) -> [f32; 2] {
[v.x, v.y]
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn vec_test() {
let vec_a = Vec2::new(0.0, 0.0);
let vec_b = Vec2::new(1.0, 1.0);
let dist = vec_a.dist_to(&vec_b);
assert!((dist - (2.0_f32).sqrt()).abs() < 0.00000000001);
}
}