use std::ops::{Add, Sub, Neg, Mul, Div, AddAssign, SubAssign, MulAssign, DivAssign};
#[derive(PartialEq, Copy, Clone, Debug)]
pub struct Vec2 {
pub x: f32,
pub y: f32,
}
impl Vec2 {
pub fn new(x: f32, y: f32) -> Vec2 {
Vec2 { x, y }
}
#[inline]
pub fn len(&self) -> f32 {
self.sqr_len().sqrt()
}
#[inline]
pub fn sqr_len(&self) -> f32 {
self.x * self.x + self.y * self.y
}
#[inline]
pub fn dot(&self, b: &Vec2) -> f32 {
self.x * b.x + self.y * b.y
}
#[inline]
pub fn normalized(self) -> Vec2 {
let len = self.len();
if len == 0.0 {
Vec2::ZERO
} else {
self / len
}
}
#[inline]
pub fn min(&self, other: &Vec2) -> Vec2 {
Vec2::new(self.x.min(other.x), self.y.min(other.y))
}
#[inline]
pub fn max(&self, other: &Vec2) -> Vec2 {
Vec2::new(self.x.max(other.x), self.y.max(other.y))
}
pub const ZERO: Vec2 = Vec2 { x: 0.0, y: 0.0 };
pub const UP: Vec2 = Vec2 { x: 0.0, y: 1.0 };
pub const RIGHT: Vec2 = Vec2 { x: 1.0, y: 0.0 };
pub const DOWN: Vec2 = Vec2 { x: 0.0, y: -1.0 };
pub const LEFT: Vec2 = Vec2 { x: -1.0, y: 0.0 };
pub const ONE: Vec2 = Vec2 { x: 1.0, y: 1.0 };
}
pub trait Cross<RHS = Self> {
type Output;
fn cross(self, other: RHS) -> Self::Output;
}
impl Cross for Vec2 {
type Output = f32;
fn cross(self, other: Vec2) -> f32 {
self.x * other.y - self.y * other.x
}
}
impl<'a> Cross<Vec2> for &'a Vec2 {
type Output = f32;
fn cross(self, other: Vec2) -> f32 {
self.x * other.y - self.y * other.x
}
}
impl<'b> Cross<&'b Vec2> for Vec2 {
type Output = f32;
fn cross(self, other: &'b Vec2) -> f32 {
self.x * other.y - self.y * other.x
}
}
impl<'a, 'b> Cross<&'b Vec2> for &'a Vec2 {
type Output = f32;
fn cross(self, other: &'b Vec2) -> f32 {
self.x * other.y - self.y * other.x
}
}
impl Cross<f32> for Vec2 {
type Output = Vec2;
fn cross(self, s: f32) -> Vec2 {
Vec2::new(s * self.y, -s * self.x)
}
}
impl<'a> Cross<f32> for &'a Vec2 {
type Output = Vec2;
fn cross(self, s: f32) -> Vec2 {
Vec2::new(s * self.y, -s * self.x)
}
}
impl<'b> Cross<&'b f32> for Vec2 {
type Output = Vec2;
fn cross(self, s: &'b f32) -> Vec2 {
Vec2::new(s * self.y, -s * self.x)
}
}
impl<'a, 'b> Cross<&'b f32> for &'a Vec2 {
type Output = Vec2;
fn cross(self, s: &'b f32) -> Vec2 {
Vec2::new(s * self.y, -s * self.x)
}
}
impl Cross<Vec2> for f32 {
type Output = Vec2;
fn cross(self, other: Vec2) -> Vec2 {
-other.cross(self)
}
}
impl<'a> Cross<Vec2> for &'a f32 {
type Output = Vec2;
fn cross(self, other: Vec2) -> Vec2 {
-other.cross(self)
}
}
impl<'b> Cross<&'b Vec2> for f32 {
type Output = Vec2;
fn cross(self, other: &'b Vec2) -> Vec2 {
-other.cross(self)
}
}
impl<'a, 'b> Cross<&'b Vec2> for &'a f32 {
type Output = Vec2;
fn cross(self, other: &'b Vec2) -> Vec2 {
-other.cross(self)
}
}
impl Neg for Vec2 {
type Output = Self;
fn neg(self) -> Self {
Vec2::new(-self.x, -self.y)
}
}
impl<'a> Neg for &'a Vec2 {
type Output = Vec2;
fn neg(self) -> Vec2 {
Vec2::new(-self.x, -self.y)
}
}
impl Add for Vec2 {
type Output = Vec2;
fn add(self, other: Vec2) -> Vec2 {
Vec2::new(self.x + other.x, self.y + other.y)
}
}
impl<'a> Add<Vec2> for &'a Vec2 {
type Output = Vec2;
fn add(self, other: Vec2) -> Vec2 {
Vec2::new(self.x + other.x, self.y + other.y)
}
}
impl<'b> Add<&'b Vec2> for Vec2 {
type Output = Vec2;
fn add(self, other: &'b Vec2) -> Vec2 {
Vec2::new(self.x + other.x, self.y + other.y)
}
}
impl<'a, 'b> Add<&'b Vec2> for &'a Vec2 {
type Output = Vec2;
fn add(self, other: &'b Vec2) -> Vec2 {
Vec2::new(self.x + other.x, self.y + other.y)
}
}
impl AddAssign for Vec2 {
fn add_assign(&mut self, other: Vec2) {
*self = Vec2 {
x: self.x + other.x,
y: self.y + other.y,
};
}
}
impl<'b> AddAssign<&'b Vec2> for Vec2 {
fn add_assign(&mut self, other: &'b Vec2) {
*self = 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::new(self.x - other.x, self.y - other.y)
}
}
impl<'a> Sub<Vec2> for &'a Vec2 {
type Output = Vec2;
fn sub(self, other: Vec2) -> Vec2 {
Vec2::new(self.x - other.x, self.y - other.y)
}
}
impl<'b> Sub<&'b Vec2> for Vec2 {
type Output = Vec2;
fn sub(self, other: &'b Vec2) -> Vec2 {
Vec2::new(self.x - other.x, self.y - other.y)
}
}
impl<'a, 'b> Sub<&'b Vec2> for &'a Vec2 {
type Output = Vec2;
fn sub(self, other: &'b Vec2) -> Vec2 {
Vec2::new(self.x - other.x, self.y - other.y)
}
}
impl SubAssign for Vec2 {
fn sub_assign(&mut self, other: Vec2) {
*self = Vec2 {
x: self.x - other.x,
y: self.y - other.y,
};
}
}
impl<'b> SubAssign<&'b Vec2> for Vec2 {
fn sub_assign(&mut self, other: &'b Vec2) {
*self = Vec2 {
x: self.x - other.x,
y: self.y - other.y,
};
}
}
impl Mul<f32> for Vec2 {
type Output = Vec2;
fn mul(self, s: f32) -> Vec2 {
Vec2::new(self.x * s, self.y * s)
}
}
impl<'a> Mul<f32> for &'a Vec2 {
type Output = Vec2;
fn mul(self, s: f32) -> Vec2 {
Vec2::new(self.x * s, self.y * s)
}
}
impl<'b> Mul<&'b f32> for Vec2 {
type Output = Vec2;
fn mul(self, s: &'b f32) -> Vec2 {
Vec2::new(self.x * s, self.y * s)
}
}
impl<'a, 'b> Mul<&'b f32> for &'a Vec2 {
type Output = Vec2;
fn mul(self, s: &'b f32) -> Vec2 {
Vec2::new(self.x * s, self.y * s)
}
}
impl Mul<Vec2> for f32 {
type Output = Vec2;
fn mul(self, v: Vec2) -> Vec2 {
Vec2::new(self * v.x, self * v.y)
}
}
impl<'a> Mul<Vec2> for &'a f32 {
type Output = Vec2;
fn mul(self, v: Vec2) -> Vec2 {
Vec2::new(self * v.x, self * v.y)
}
}
impl<'b> Mul<&'b Vec2> for f32 {
type Output = Vec2;
fn mul(self, v: &'b Vec2) -> Vec2 {
Vec2::new(self * v.x, self * v.y)
}
}
impl<'a, 'b> Mul<&'b Vec2> for &'a f32 {
type Output = Vec2;
fn mul(self, v: &'b Vec2) -> Vec2 {
Vec2::new(self * v.x, self * v.y)
}
}
impl MulAssign<f32> for Vec2 {
fn mul_assign(&mut self, s: f32) {
*self = Vec2 {
x: self.x * s,
y: self.y * s,
};
}
}
impl<'b> MulAssign<&'b f32> for Vec2 {
fn mul_assign(&mut self, s: &'b f32) {
*self = Vec2 {
x: self.x * s,
y: self.y * s,
};
}
}
impl Div<f32> for Vec2 {
type Output = Vec2;
fn div(self, s: f32) -> Vec2 {
self * (1.0 / s)
}
}
impl<'a> Div<f32> for &'a Vec2 {
type Output = Vec2;
fn div(self, s: f32) -> Vec2 {
self * (1.0 / s)
}
}
impl<'b> Div<&'b f32> for Vec2 {
type Output = Vec2;
fn div(self, s: &'b f32) -> Vec2 {
self * (1.0 / s)
}
}
impl<'a, 'b> Div<&'b f32> for &'a Vec2 {
type Output = Vec2;
fn div(self, s: &'b f32) -> Vec2 {
self * (1.0 / s)
}
}
impl DivAssign<f32> for Vec2 {
fn div_assign(&mut self, s: f32) {
*self *= 1.0 / s;
}
}
impl<'b> DivAssign<&'b f32> for Vec2 {
fn div_assign(&mut self, s: &'b f32) {
*self *= 1.0 / s;
}
}