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<U> {
pub x: U,
pub y: U
}
impl<U> Vector2<U> {
pub const fn new(x: U, y: U) -> Self {
Vector2 { x, y }
}
}
impl<U: Add<Output = V>, V> Add for Vector2<U> {
type Output = Vector2<V>;
fn add(self, rhs: Self) -> Self::Output {
Vector2 {
x: self.x+rhs.x,
y: self.y+rhs.y
}
}
}
impl<U: AddAssign> AddAssign for Vector2<U> {
fn add_assign(&mut self, rhs: Self) {
self.x += rhs.x;
self.y += rhs.y;
}
}
impl<U: Sub<Output = V>, V> Sub for Vector2<U> {
type Output = Vector2<V>;
fn sub(self, rhs: Self) -> Self::Output {
Vector2 {
x: self.x-rhs.x,
y: self.y-rhs.y
}
}
}
impl<U: SubAssign> SubAssign for Vector2<U> {
fn sub_assign(&mut self, rhs: Self) {
self.x -= rhs.x;
self.y -= rhs.y;
}
}
impl<U: Neg<Output = V>, V> Neg for Vector2<U> {
type Output = Vector2<V>;
fn neg(self) -> Self::Output {
Vector2 {
x: -self.x,
y: -self.y
}
}
}
impl<U, V> Mul<U> for Vector2<U>
where
U: Clone + Copy + Mul<Output = V>
{
type Output = Vector2<V>;
fn mul(self, rhs: U) -> Self::Output {
Vector2 {
x: self.x*rhs,
y: self.y*rhs
}
}
}
impl<U: Clone + Copy + MulAssign> MulAssign<U> for Vector2<U> {
fn mul_assign(&mut self, rhs: U) {
self.x *= rhs;
self.y *= rhs;
}
}
impl<U, V> Div<U> for Vector2<U>
where
U: Div<Output = V> + Clone
{
type Output = Vector2<V>;
fn div(self, rhs: U) -> Self::Output {
Vector2 {
x: self.x/rhs.clone(),
y: self.y/rhs.clone()
}
}
}
impl<U: DivAssign + Clone> DivAssign<U> for Vector2<U> {
fn div_assign(&mut self, rhs: U) {
self.x /= rhs.clone();
self.y /= rhs.clone();
}
}
impl<U> Mul<Vector2<U>> for Vector2<U>
where
U: Mul<Output = U> + Add<Output = U>
{
type Output = U;
fn mul(self, rhs: Vector2<U>) -> Self::Output {
self.x*rhs.x + self.y*rhs.y
}
}
impl<U, W> Vector2<U>
where
Vector2<U>: Clone + Copy + Mul<Vector2<U>, Output = W>
{
pub fn length_squared(self) -> W {
self * self
}
}
impl Vector2<f32> {
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()
}
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<f64> {
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()
}
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<U: Clone + Default> Vector2<U> {
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<U: Clone + Copy + Neg<Output = U>> Vector2<U> {
pub fn normal(&self) -> Self {
Vector2 {
x: -self.y,
y: self.x
}
}
}
impl<U: Clone + Copy> From<[U; 2]> for Vector2<U> {
fn from(value: [U; 2]) -> Self {
Vector2::new(value[0], value[1])
}
}
impl<U: Clone + Copy> From<(U, U)> for Vector2<U> {
fn from(value: (U, U)) -> Self {
Vector2::new(value.0, value.1)
}
}
impl<U> Vector2<U> {
fn from_vec2<V: From<U>>(src: Vector2<U>) -> Vector2<V> {
Vector2::<V>::new(src.x.into(), src.y.into())
}
fn into_vec2<V: Into<U>>(src: Vector2<V>) -> Vector2<U> {
Vector2::<U>::new(src.x.into(), src.y.into())
}
}
impl<U: Zero + PartialEq> Zero for Vector2<U> {
fn zero() -> Self {
Vector2::new(U::zero(), U::zero())
}
fn is_zero(&self) -> bool {
*self == Self::zero()
}
}
impl Sum for Vector2<f32> {
fn sum<I: Iterator<Item = Self>>(iter: I) -> Self {
iter.fold(Vector2::new(0., 0.), |acc, v| acc+v)
}
}
impl Sum for Vector2<f64> {
fn sum<I: Iterator<Item = Self>>(iter: I) -> Self {
iter.fold(Vector2::new(0., 0.), |acc, v| acc+v)
}
}