use std::{ops::{Add, AddAssign, Sub, SubAssign, Neg, Mul, MulAssign, Div, DivAssign}, iter::Sum}; use num_traits::Zero; #[derive(Copy, Clone, Debug, Eq, PartialEq, Default)] pub struct Vector2 { pub x: U, pub y: U } impl Vector2 { pub const fn new(x: U, y: U) -> Self { Vector2 { x, y } } } impl, V> Add for Vector2 { type Output = Vector2; fn add(self, rhs: Self) -> Self::Output { Vector2 { x: self.x+rhs.x, y: self.y+rhs.y } } } impl AddAssign for Vector2 { fn add_assign(&mut self, rhs: Self) { self.x += rhs.x; self.y += rhs.y; } } impl, V> Sub for Vector2 { type Output = Vector2; fn sub(self, rhs: Self) -> Self::Output { Vector2 { x: self.x-rhs.x, y: self.y-rhs.y } } } impl SubAssign for Vector2 { fn sub_assign(&mut self, rhs: Self) { self.x -= rhs.x; self.y -= rhs.y; } } impl, V> Neg for Vector2 { type Output = Vector2; fn neg(self) -> Self::Output { Vector2 { x: -self.x, y: -self.y } } } impl Mul for Vector2 where U: Clone + Copy + Mul { type Output = Vector2; fn mul(self, rhs: U) -> Self::Output { Vector2 { x: self.x*rhs, y: self.y*rhs } } } impl MulAssign for Vector2 { fn mul_assign(&mut self, rhs: U) { self.x *= rhs; self.y *= rhs; } } impl Div for Vector2 where U: Div + Clone { type Output = Vector2; fn div(self, rhs: U) -> Self::Output { Vector2 { x: self.x/rhs.clone(), y: self.y/rhs.clone() } } } impl DivAssign for Vector2 { fn div_assign(&mut self, rhs: U) { self.x /= rhs.clone(); self.y /= rhs.clone(); } } impl Mul> for Vector2 where U: Mul + Add { type Output = U; fn mul(self, rhs: Vector2) -> Self::Output { self.x*rhs.x + self.y*rhs.y } } impl Vector2 where Vector2: Clone + Copy + Mul, Output = W> { pub fn length_squared(self) -> W { self * self } } impl Vector2 { pub fn from_angle(angle: f32, magnitude: f32) -> Self { Vector2::new( magnitude * angle.cos(), magnitude * angle.sin() ) } pub fn length(self) -> f32 { f32::sqrt(self.length_squared()) } pub fn distance(self, other: Self) -> f32 { (self - other).length() } // If the length of the vector is zero, returns the vector itself. pub fn normalized(self) -> Self { let length = self.length(); if length == 0. { self } else { self / length } } pub fn normalize(&mut self) -> &mut Self { *self = self.normalized(); self } pub fn angle(self) -> f32 { f32::atan2(self.y, self.x) } pub fn angle_from(self, other: Self) -> f32 { (self * other / (self.length() * other.length())).acos() } } impl Vector2 { pub fn from_angle(angle: f64, magnitude: f64) -> Self { Vector2::new( magnitude * angle.cos(), magnitude * angle.sin() ) } pub fn length(&self) -> f64 { f64::sqrt(self.length_squared()) } pub fn distance(self, other: Self) -> f64 { (self - other).length() } // If the length of the vector is zero, returns the vector itself. pub fn normalized(&self) -> Self { let length = self.length(); if length == 0. { *self } else { *self / length } } pub fn normalize(&mut self) -> &mut Self { *self = self.normalized(); self } pub fn angle(&self) -> f64 { f64::atan2(self.y, self.x) } pub fn angle_between(&self, other: &Self) -> f64 { (*self * *other / (self.length() * other.length())).acos() } } impl Vector2 { pub fn horizontal(&self) -> Self { Vector2 { x: self.x.clone(), y: U::default() } } pub fn vertical(&self) -> Self { Vector2 { x: U::default(), y: self.y.clone() } } } impl> Vector2 { pub fn normal(&self) -> Self { Vector2 { x: -self.y, y: self.x } } } impl From<[U; 2]> for Vector2 { fn from(value: [U; 2]) -> Self { Vector2::new(value[0], value[1]) } } impl From<(U, U)> for Vector2 { fn from(value: (U, U)) -> Self { Vector2::new(value.0, value.1) } } impl Vector2 { fn from_vec2>(src: Vector2) -> Vector2 { Vector2::::new(src.x.into(), src.y.into()) } fn into_vec2>(src: Vector2) -> Vector2 { Vector2::::new(src.x.into(), src.y.into()) } } impl Zero for Vector2 { fn zero() -> Self { Vector2::new(U::zero(), U::zero()) } fn is_zero(&self) -> bool { *self == Self::zero() } } impl Sum for Vector2 { fn sum>(iter: I) -> Self { iter.fold(Vector2::new(0., 0.), |acc, v| acc+v) } } impl Sum for Vector2 { fn sum>(iter: I) -> Self { iter.fold(Vector2::new(0., 0.), |acc, v| acc+v) } }