simple_vector2d/
lib.rs

1#![warn(missing_docs)]
2//! Simple and generic implementation of 2D vectors
3//!
4//! Intended for use in 2D game engines
5
6extern crate num_traits;
7#[cfg(feature="rustc-serialize")]
8extern crate rustc_serialize;
9
10#[cfg(feature="serde_derive")]
11#[cfg_attr(feature="serde_derive", macro_use)]
12extern crate serde_derive;
13
14use num_traits::Float;
15
16/// Representation of a mathematical vector e.g. a position or velocity
17#[derive(Copy, Clone, Debug, PartialEq, Eq, Default)]
18#[cfg_attr(feature="rustc-serialize", derive(RustcDecodable, RustcEncodable))]
19#[cfg_attr(feature="serde_derive", derive(Serialize, Deserialize))]
20pub struct Vector2<T>(pub T, pub T);
21
22use std::ops::{Add, AddAssign, Sub, SubAssign, Mul, MulAssign, Div, DivAssign, Neg};
23use std::convert::From;
24
25/// Constants for common vectors
26pub mod consts{
27    use super::Vector2;
28
29    /// The zero vector
30    pub const ZERO_F32: Vector2<f32> = Vector2(0., 0.);
31    /// A unit vector pointing upwards
32    pub const UP_F32: Vector2<f32> = Vector2(0., 1.);
33    /// A unit vector pointing downwards
34    pub const DOWN_F32: Vector2<f32> = Vector2(0., -1.);
35    /// A unit vector pointing to the right
36    pub const RIGHT_F32: Vector2<f32> = Vector2(1., 0.);
37    /// A unit vector pointing to the left
38    pub const LEFT_F32: Vector2<f32> = Vector2(-1., 0.);
39
40    /// The zero vector
41    pub const ZERO_F64: Vector2<f64> = Vector2(0., 0.);
42    /// A unit vector pointing upwards
43    pub const UP_F64: Vector2<f64> = Vector2(0., 1.);
44    /// A unit vector pointing downwards
45    pub const DOWN_F64: Vector2<f64> = Vector2(0., -1.);
46    /// A unit vector pointing to the right
47    pub const RIGHT_F64: Vector2<f64> = Vector2(1., 0.);
48    /// A unit vector pointing to the left
49    pub const LEFT_F64: Vector2<f64> = Vector2(-1., 0.);
50}
51
52impl<T: Float> Vector2<T>{
53    /// Creates a new unit vector in a specific direction
54    pub fn unit_vector(direction: T) -> Self{
55        let (y, x) = direction.sin_cos();
56        Vector2(x, y)
57    }
58    /// Normalises the vector
59    pub fn normalise(self) -> Self{
60        self / self.length()
61    }
62    /// Returns the magnitude/length of the vector
63    pub fn length(self) -> T{
64        // This is apparently faster than using hypot
65        self.length_squared().sqrt()
66    }
67    /// Returns the magnitude/length of the vector squared
68    pub fn length_squared(self) -> T{
69        self.0.powi(2) + self.1.powi(2)
70    }
71    /// Returns direction the vector is pointing
72    pub fn direction(self) -> T{
73        self.1.atan2(self.0)
74    }
75    /// Returns direction towards another vector
76    pub fn direction_to(self, other: Self) -> T{
77        (other-self).direction()
78    }
79    /// Returns the distance betweens two vectors
80    pub fn distance_to(self, other: Self) -> T{
81        (other-self).length()
82    }
83    /// Returns the distance betweens two vectors
84    pub fn distance_to_squared(self, other: Self) -> T{
85        (other-self).length_squared()
86    }
87    /// Returns `true` if either component is `NaN`.
88    pub fn is_any_nan(&self) -> bool{
89        self.0.is_nan() || self.1.is_nan()
90    }
91    /// Returns `true` if either component is positive or negative infinity.
92    pub fn is_any_infinite(&self) -> bool{
93        self.0.is_infinite() || self.1.is_infinite()
94    }
95    /// Returns `true` if both components are neither infinite nor `NaN`.
96    pub fn is_all_finite(&self) -> bool{
97        self.0.is_finite() && self.1.is_finite()
98    }
99    /// Returns `true` if both components are neither zero, infinite, subnormal nor `NaN`.
100    pub fn is_all_normal(&self) -> bool{
101        self.0.is_normal() && self.1.is_normal()
102    }
103}
104
105macro_rules! impl_for {
106    ($($t:ty)*) => {$(
107        impl Mul<Vector2<$t>> for $t{
108            type Output = Vector2<$t>;
109
110            fn mul(self, rhs: Vector2<$t>) -> Vector2<$t>{
111                Vector2(self * rhs.0, self * rhs.1)
112            }
113        }
114        impl Div<Vector2<$t>> for $t{
115            type Output = Vector2<$t>;
116
117            fn div(self, rhs: Vector2<$t>) -> Vector2<$t>{
118                Vector2(self / rhs.0, self / rhs.1)
119            }
120        }
121    )*};
122}impl_for!{f32 f64}
123
124impl<T> Vector2<T> {
125    /// Returns the normal vector (aka. hat vector) of this vector i.e. a perpendicular vector
126    ///
127    /// Not to be confused with `normalise` which returns a unit vector
128    ///
129    /// Defined as (-y, x)
130    pub fn normal(self) -> Self
131    where T: Neg<Output=T> {
132        let Vector2(x, y) = self;
133        Vector2(-y, x)
134    }
135    /// Returns the dot product of two vectors
136    pub fn dot(self, other: Self) -> <<T as Mul>::Output as Add>::Output
137    where T: Mul, <T as Mul>::Output: Add{
138        self.0 * other.0 + self.1 * other.1
139    }
140    /// Returns the determinant of two vectors
141    pub fn det(self, other: Self) -> <<T as Mul>::Output as Sub>::Output
142    where T: Mul, <T as Mul>::Output: Sub {
143        self.0 * other.1 - self.1 * other.0
144    }
145}
146
147impl<T: Add> Add for Vector2<T>{
148    type Output = Vector2<T::Output>;
149
150    fn add(self, rhs: Self) -> Self::Output{
151        Vector2(self.0 + rhs.0, self.1 + rhs.1)
152    }
153}
154
155impl<T: Sub> Sub for Vector2<T>{
156    type Output = Vector2<T::Output>;
157
158    fn sub(self, rhs: Self) -> Self::Output{
159        Vector2(self.0 - rhs.0, self.1 - rhs.1)
160    }
161}
162
163impl<T: AddAssign> AddAssign for Vector2<T>{
164    fn add_assign(&mut self, rhs: Self){
165        self.0 += rhs.0;
166        self.1 += rhs.1;
167    }
168}
169
170impl<T: SubAssign> SubAssign for Vector2<T>{
171    fn sub_assign(&mut self, rhs: Self){
172        self.0 -= rhs.0;
173        self.1 -= rhs.1;
174    }
175}
176
177impl<T: MulAssign + Copy> MulAssign<T> for Vector2<T>{
178    fn mul_assign(&mut self, rhs: T){
179        self.0 *= rhs;
180        self.1 *= rhs;
181    }
182}
183
184impl<T: DivAssign + Copy> DivAssign<T> for Vector2<T>{
185    fn div_assign(&mut self, rhs: T){
186        self.0 /= rhs;
187        self.1 /= rhs;
188    }
189}
190
191impl<T: Mul + Copy> Mul<T> for Vector2<T>{
192    type Output = Vector2<T::Output>;
193
194    fn mul(self, rhs: T) -> Self::Output{
195        Vector2(self.0 * rhs, self.1 * rhs)
196    }
197}
198
199impl<T: Div + Copy> Div<T> for Vector2<T>{
200    type Output = Vector2<T::Output>;
201
202    fn div(self, rhs: T) -> Self::Output{
203        Vector2(self.0/rhs, self.1/rhs)
204    }
205}
206
207impl<T: Neg> Neg for Vector2<T>{
208    type Output = Vector2<T::Output>;
209
210    fn neg(self) -> Self::Output{
211        Vector2(-self.0, -self.1)
212    }
213}
214
215impl<T> Into<[T; 2]> for Vector2<T>{
216    #[inline]
217    fn into(self) -> [T; 2]{
218        [self.0, self.1]
219    }
220}
221
222impl<T: Copy> From<[T; 2]> for Vector2<T>{
223    #[inline]
224    fn from(array: [T; 2]) -> Self{
225        Vector2(array[0], array[1])
226    }
227}
228
229impl<T> Into<(T, T)> for Vector2<T>{
230    #[inline]
231    fn into(self) -> (T, T){
232        (self.0, self.1)
233    }
234}
235
236impl<T> From<(T, T)> for Vector2<T>{
237    #[inline]
238    fn from(tuple: (T, T)) -> Self{
239        Vector2(tuple.0, tuple.1)
240    }
241}