use std::ops::{Add, AddAssign, Sub, SubAssign, Neg, Mul, MulAssign, Div, DivAssign};
#[derive(Copy, Clone, Debug, Eq, PartialEq)]
pub struct Vector2<U> {
x: U,
y: U
}
impl<U> Vector2<U> {
pub fn new(x: U, y: U) -> Self {
Vector2 { x, y }
}
}
impl<U, V> Add for Vector2<U>
where
U: Add<Output = V>
{
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 for Vector2<U>
where
U: AddAssign
{
fn add_assign(&mut self, rhs: Self) {
self.x += rhs.x;
self.y += rhs.y;
}
}
impl<U, V> Sub for Vector2<U>
where
U: Sub<Output = V>
{
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 for Vector2<U>
where
U: SubAssign
{
fn sub_assign(&mut self, rhs: Self) {
self.x -= rhs.x;
self.y -= rhs.y;
}
}
impl<U, V> Neg for Vector2<U>
where
U: Neg<Output = V>
{
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: Mul<Output = V> + Clone
{
type Output = Vector2<V>;
fn mul(self, rhs: U) -> Self::Output {
Vector2 {
x: self.x*rhs.clone(),
y: self.y*rhs.clone()
}
}
}
impl<U> MulAssign<U> for Vector2<U>
where
U: MulAssign + Clone
{
fn mul_assign(&mut self, rhs: U) {
self.x *= rhs.clone();
self.y *= rhs.clone();
}
}
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<U> for Vector2<U>
where
U: DivAssign + Clone
{
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, V, W> Vector2<U>
where
U: Mul<Output = V> + Clone,
V: Add<Output = W>
{
pub fn length_squared(&self) -> W {
self.x.clone()*self.x.clone() + self.y.clone()*self.y.clone()
}
}
impl Vector2<f32> {
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)
}
}
impl Vector2<f64> {
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)
}
}
impl<U> Vector2<U>
where
U: Clone + Default
{
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
}
}
}