use std::ops::{Add, Sub, Mul, Neg, AddAssign, SubAssign, MulAssign};
use geom::card::Card;
#[derive(PartialEq, Copy, Clone, Debug, Default)]
pub struct Vec2 {
pub x: f64,
pub y: f64
}
impl Vec2 {
#[inline]
pub fn new(x: f64, y: f64) -> Vec2 {
Vec2 { x: x, y: y }
}
#[inline]
pub fn zero() -> Vec2 {
Vec2::default()
}
pub fn len_sq(&self) -> f64 {
self.x * self.x + self.y * self.y
}
pub fn len(&self) -> f64 {
self.len_sq().sqrt()
}
pub fn normalize(&self) -> Option<Vec2> {
let len = self.len();
if len == 0.0 {
None
} else {
Some(Vec2::new(self.x / len, self.y / len))
}
}
pub fn dist_sq(&self, other: &Vec2) -> f64 {
(*self - *other).len_sq()
}
pub fn dist(&self, other: &Vec2) -> f64 {
(*self - *other).len()
}
pub fn lerp(&self, other: Vec2, ratio: f64) -> Vec2 {
(1.0 - ratio) * *self + ratio * other
}
pub fn rotate(&self, angle: f64) -> Vec2 {
let sin = angle.sin();
let cos = angle.cos();
Vec2::new(cos * self.x - sin * self.y, sin * self.x + cos * self.y)
}
}
impl Mul<Vec2> for f64 {
type Output = Vec2;
fn mul(self, rhs: Vec2) -> Vec2 {
Vec2::new(self * rhs.x, self * rhs.y)
}
}
impl Mul<f64> for Vec2 {
type Output = Vec2;
fn mul(self, rhs: f64) -> Vec2 {
Vec2::new(self.x * rhs, self.y * rhs)
}
}
impl MulAssign<f64> for Vec2 {
fn mul_assign(&mut self, rhs: f64) {
self.x *= rhs;
self.y *= rhs;
}
}
impl Mul<Vec2> for Vec2 {
type Output = f64;
fn mul(self, rhs: Vec2) -> f64 {
self.x*rhs.x + self.y*rhs.y
}
}
impl Add for Vec2 {
type Output = Vec2;
fn add(self, rhs: Vec2) -> Vec2 {
Vec2::new(self.x + rhs.x, self.y + rhs.y)
}
}
impl AddAssign for Vec2 {
fn add_assign(&mut self, rhs: Vec2) {
self.x += rhs.x;
self.y += rhs.y;
}
}
impl Sub for Vec2 {
type Output = Vec2;
fn sub(self, rhs: Vec2) -> Vec2 {
Vec2::new(self.x - rhs.x, self.y - rhs.y)
}
}
impl SubAssign for Vec2 {
fn sub_assign(&mut self, rhs: Vec2) {
self.x -= rhs.x;
self.y -= rhs.y;
}
}
impl Neg for Vec2 {
type Output = Vec2;
fn neg(self) -> Vec2 {
Vec2::new(-self.x, -self.y)
}
}
impl From<Card> for Vec2 {
fn from(card: Card) -> Vec2 {
match card {
Card::MinusX => v2(-1.0, 0.0),
Card::MinusY => v2(0.0, -1.0),
Card::PlusX => v2(1.0, 0.0),
Card::PlusY => v2(0.0, 1.0),
}
}
}
#[inline]
pub fn v2(x: f64, y: f64) -> Vec2 {
Vec2::new(x, y)
}
#[derive(PartialEq, Copy, Clone, Debug)]
pub struct DirVec2 {
dir: Vec2,
len: f64
}
impl DirVec2 {
pub fn new(dir: Vec2, len: f64) -> DirVec2 {
DirVec2 { dir: dir.normalize().unwrap(), len: len }
}
#[inline]
pub fn dir(&self) -> Vec2 {
self.dir
}
#[inline]
pub fn len(&self) -> f64 {
self.len
}
pub fn flip(&self) -> DirVec2 {
DirVec2 { dir: -self.dir, len: self.len }
}
}
impl From<DirVec2> for Vec2 {
fn from(dir_vec: DirVec2) -> Vec2 {
Vec2::new(dir_vec.dir().x * dir_vec.len(), dir_vec.dir().y * dir_vec.len())
}
}