use std::ops::{Add, Div, Mul, Neg, Sub};
#[derive(Clone, Copy, Debug, PartialEq)]
pub struct Vec2 {
pub x: f32,
pub y: f32,
}
impl Vec2 {
pub const ZERO: Vec2 = Vec2 { x: 0.0, y: 0.0 };
pub const fn new(x: f32, y: f32) -> Self {
Self { x, y }
}
pub fn dot(self, rhs: Vec2) -> f32 {
self.x * rhs.x + self.y * rhs.y
}
pub fn cross(self, rhs: Vec2) -> f32 {
self.x * rhs.y - self.y * rhs.x
}
pub fn length_squared(self) -> f32 {
self.dot(self)
}
pub fn length(self) -> f32 {
self.length_squared().sqrt()
}
pub fn normalize(self) -> Vec2 {
self / self.length()
}
pub fn perp(self) -> Vec2 {
Vec2::new(-self.y, self.x)
}
pub fn rotate(self, radians: f32) -> Vec2 {
let (s, c) = radians.sin_cos();
Vec2::new(self.x * c - self.y * s, self.x * s + self.y * c)
}
pub fn from_angle(radians: f32) -> Vec2 {
let (s, c) = radians.sin_cos();
Vec2::new(c, s)
}
}
impl Add<Vec2> for Vec2 {
type Output = Vec2;
fn add(self, rhs: Vec2) -> Vec2 {
Vec2::new(self.x + rhs.x, self.y + rhs.y)
}
}
impl Sub<Vec2> for Vec2 {
type Output = Vec2;
fn sub(self, rhs: Vec2) -> Vec2 {
Vec2::new(self.x - rhs.x, self.y - rhs.y)
}
}
impl Mul<f32> for Vec2 {
type Output = Vec2;
fn mul(self, rhs: f32) -> Vec2 {
Vec2::new(self.x * rhs, self.y * rhs)
}
}
impl Mul<Vec2> for Vec2 {
type Output = Vec2;
fn mul(self, rhs: Vec2) -> Vec2 {
Vec2::new(self.x * rhs.x, self.y * rhs.y)
}
}
impl Div<f32> for Vec2 {
type Output = Vec2;
fn div(self, rhs: f32) -> Vec2 {
Vec2::new(self.x / rhs, self.y / rhs)
}
}
impl Neg for Vec2 {
type Output = Vec2;
fn neg(self) -> Vec2 {
Vec2::new(-self.x, -self.y)
}
}
impl From<Vec2> for [f32; 2] {
fn from(v: Vec2) -> [f32; 2] {
[v.x, v.y]
}
}
impl From<[f32; 2]> for Vec2 {
fn from(v: [f32; 2]) -> Vec2 {
Vec2::new(v[0], v[1])
}
}