#![warn(missing_docs)]
extern crate num_traits;
#[cfg(feature="rustc-serialize")]
extern crate rustc_serialize;
#[cfg(feature="serde_derive")]
#[cfg_attr(feature="serde_derive", macro_use)]
extern crate serde_derive;
use num_traits::Float;
#[derive(Copy, Clone, Debug, PartialEq, Eq, Default)]
#[cfg_attr(feature="rustc-serialize", derive(RustcDecodable, RustcEncodable))]
#[cfg_attr(feature="serde_derive", derive(Serialize, Deserialize))]
pub struct Vector2<T>(pub T, pub T);
use std::ops::{Add, AddAssign, Sub, SubAssign, Mul, MulAssign, Div, DivAssign, Neg};
use std::convert::From;
pub mod consts{
use super::Vector2;
pub const ZERO_F32: Vector2<f32> = Vector2(0., 0.);
pub const UP_F32: Vector2<f32> = Vector2(0., 1.);
pub const DOWN_F32: Vector2<f32> = Vector2(0., -1.);
pub const RIGHT_F32: Vector2<f32> = Vector2(1., 0.);
pub const LEFT_F32: Vector2<f32> = Vector2(-1., 0.);
pub const ZERO_F64: Vector2<f64> = Vector2(0., 0.);
pub const UP_F64: Vector2<f64> = Vector2(0., 1.);
pub const DOWN_F64: Vector2<f64> = Vector2(0., -1.);
pub const RIGHT_F64: Vector2<f64> = Vector2(1., 0.);
pub const LEFT_F64: Vector2<f64> = Vector2(-1., 0.);
}
impl<T: Float> Vector2<T>{
pub fn unit_vector(direction: T) -> Self{
let (y, x) = direction.sin_cos();
Vector2(x, y)
}
pub fn normalise(self) -> Self{
self / self.length()
}
pub fn length(self) -> T{
self.length_squared().sqrt()
}
pub fn length_squared(self) -> T{
self.0.powi(2) + self.1.powi(2)
}
pub fn direction(self) -> T{
self.1.atan2(self.0)
}
pub fn direction_to(self, other: Self) -> T{
(other-self).direction()
}
pub fn distance_to(self, other: Self) -> T{
(other-self).length()
}
pub fn distance_to_squared(self, other: Self) -> T{
(other-self).length_squared()
}
pub fn is_any_nan(&self) -> bool{
self.0.is_nan() || self.1.is_nan()
}
pub fn is_any_infinite(&self) -> bool{
self.0.is_infinite() || self.1.is_infinite()
}
pub fn is_all_finite(&self) -> bool{
self.0.is_finite() && self.1.is_finite()
}
pub fn is_all_normal(&self) -> bool{
self.0.is_normal() && self.1.is_normal()
}
}
macro_rules! impl_for {
($($t:ty)*) => {$(
impl Mul<Vector2<$t>> for $t{
type Output = Vector2<$t>;
fn mul(self, rhs: Vector2<$t>) -> Vector2<$t>{
Vector2(self * rhs.0, self * rhs.1)
}
}
impl Div<Vector2<$t>> for $t{
type Output = Vector2<$t>;
fn div(self, rhs: Vector2<$t>) -> Vector2<$t>{
Vector2(self / rhs.0, self / rhs.1)
}
}
)*};
}impl_for!{f32 f64}
impl<T> Vector2<T> {
pub fn normal(self) -> Self
where T: Neg<Output=T> {
let Vector2(x, y) = self;
Vector2(-y, x)
}
pub fn dot(self, other: Self) -> <<T as Mul>::Output as Add>::Output
where T: Mul, <T as Mul>::Output: Add{
self.0 * other.0 + self.1 * other.1
}
pub fn det(self, other: Self) -> <<T as Mul>::Output as Sub>::Output
where T: Mul, <T as Mul>::Output: Sub {
self.0 * other.1 - self.1 * other.0
}
}
impl<T: Add> Add for Vector2<T>{
type Output = Vector2<T::Output>;
fn add(self, rhs: Self) -> Self::Output{
Vector2(self.0 + rhs.0, self.1 + rhs.1)
}
}
impl<T: Sub> Sub for Vector2<T>{
type Output = Vector2<T::Output>;
fn sub(self, rhs: Self) -> Self::Output{
Vector2(self.0 - rhs.0, self.1 - rhs.1)
}
}
impl<T: AddAssign> AddAssign for Vector2<T>{
fn add_assign(&mut self, rhs: Self){
self.0 += rhs.0;
self.1 += rhs.1;
}
}
impl<T: SubAssign> SubAssign for Vector2<T>{
fn sub_assign(&mut self, rhs: Self){
self.0 -= rhs.0;
self.1 -= rhs.1;
}
}
impl<T: MulAssign + Copy> MulAssign<T> for Vector2<T>{
fn mul_assign(&mut self, rhs: T){
self.0 *= rhs;
self.1 *= rhs;
}
}
impl<T: DivAssign + Copy> DivAssign<T> for Vector2<T>{
fn div_assign(&mut self, rhs: T){
self.0 /= rhs;
self.1 /= rhs;
}
}
impl<T: Mul + Copy> Mul<T> for Vector2<T>{
type Output = Vector2<T::Output>;
fn mul(self, rhs: T) -> Self::Output{
Vector2(self.0 * rhs, self.1 * rhs)
}
}
impl<T: Div + Copy> Div<T> for Vector2<T>{
type Output = Vector2<T::Output>;
fn div(self, rhs: T) -> Self::Output{
Vector2(self.0/rhs, self.1/rhs)
}
}
impl<T: Neg> Neg for Vector2<T>{
type Output = Vector2<T::Output>;
fn neg(self) -> Self::Output{
Vector2(-self.0, -self.1)
}
}
impl<T> Into<[T; 2]> for Vector2<T>{
#[inline]
fn into(self) -> [T; 2]{
[self.0, self.1]
}
}
impl<T: Copy> From<[T; 2]> for Vector2<T>{
#[inline]
fn from(array: [T; 2]) -> Self{
Vector2(array[0], array[1])
}
}
impl<T> Into<(T, T)> for Vector2<T>{
#[inline]
fn into(self) -> (T, T){
(self.0, self.1)
}
}
impl<T> From<(T, T)> for Vector2<T>{
#[inline]
fn from(tuple: (T, T)) -> Self{
Vector2(tuple.0, tuple.1)
}
}