radiant_utils/math/
vec2.rs

1use prelude::*;
2use super::{Vec3, Vector, Angle, Rect, Point2};
3
4/// A 2-dimensional vector.
5#[derive(Copy, Clone)]
6#[cfg_attr(feature = "serialize-serde", derive(Deserialize, Serialize))]
7pub struct Vec2<T = f32>(pub T, pub T);
8
9impl<T> Vec2<T> where T: Float {
10    /// Creates a new instances.
11    pub fn new() -> Self {
12        Vec2::<T>(T::zero(), T::zero())
13    }
14    /// Returns the length of the vector
15    pub fn len(self: &Self) -> T {
16        (self.0*self.0 + self.1*self.1).sqrt()
17    }
18    /// Returns the dot-product of the vectors.
19    pub fn dot(self: &Self, other: &Self) -> T {
20        self.0 * other.0 + self.1 * other.1
21    }
22    /// Returns the direction of the vector in radians.
23    #[deprecated(since = "0.2.2", note = "use Angle::from().to_radians() instead")]
24    pub fn to_radians(self: &Self) -> T {
25        self.1.atan2(self.0)
26    }
27    /// Returns the direction of the vector in degrees.
28    #[deprecated(since = "0.2.2", note = "use Angle::from().to_degrees() instead")]
29    pub fn to_degrees(self: &Self) -> T {
30        Angle::from(*self).to_degrees()
31    }
32    /// Returns the direction of the vector as an angle instance.
33    #[deprecated(since = "0.2.2", note = "use Angle::from() instead")]
34    pub fn to_angle(self: &Self) -> Angle<T> {
35        Angle::from(*self)
36    }
37    /// Creates a unit-vector from the angle given in radians.
38    #[deprecated(since = "0.2.2", note = "use Vec2::from(Angle::from_radians()) instead")]
39    pub fn from_radians(radians: T) -> Self {
40        Vec2::<T>(radians.cos(), radians.sin())
41    }
42    /// Creates a unit-vector from the angle given in degrees.
43    #[deprecated(since = "0.2.2", note = "use Vec2::from(Angle::from_degrees()) instead")]
44    pub fn from_degrees(degrees: T) -> Self {
45        Self::from(Angle::from_degrees(degrees))
46    }
47    /// Creates a unit-vector from given angle.
48    #[deprecated(since = "0.2.2", note = "use Vec2::from() instead")]
49    pub fn from_angle(angle: Angle<T>) -> Self {
50        Self::from(angle)
51    }
52    /// Normalizes the vector.
53    pub fn normalize(mut self: Self) -> Self {
54        let len = self.len();
55        if len > T::zero() {
56            self.0 = self.0 / len;
57            self.1 = self.1 / len;
58        }
59        self
60    }
61    /// The left pointing normal of the vector.
62    pub fn left(mut self: Self) -> Self {
63        let x = self.0;
64        self.0 = -self.1;
65        self.1 = x;
66        self
67    }
68    /// The right pointing normal of the vector.
69    pub fn right(mut self: Self) -> Self {
70        let x = self.0;
71        self.0 = self.1;
72        self.1 = -x;
73        self
74    }
75    /// Extends the vector by given length.
76    pub fn extend(mut self: Self, extension_len: T) -> Self {
77        let base_len = self.len();
78        if base_len > T::zero() {
79            let new_len = base_len + extension_len;
80            let factor = new_len / base_len;
81            self.0 = self.0 * factor;
82            self.1 = self.1 * factor;
83        }
84        self
85    }
86    /// Rotates the vector by given angle.
87    pub fn rotate(self: Self, angle: Angle<T>) -> Self {
88        let cos = angle.0.cos();
89        let sin = angle.0.sin();
90        Vec2(
91            cos * self.0 - sin * self.1,
92            sin * self.0 + cos * self.1
93        )
94    }
95    /// Returns outbound vector for this point and given bounding box. Subtracting
96    /// it from this point will result in a point on the bounding box.
97    pub fn outbound(self: &Self, bounding: Rect<T>) -> Option<Self> {
98        let min = bounding.0;
99        let max = bounding.1;
100        let outside = Vec2(
101            if self.0 < min.0 { self.0 - min.0 } else if self.0 > max.0 { self.0 - max.0 } else { T::zero() },
102            if self.1 < min.1 { self.1 - min.1 } else if self.1 > max.1 { self.1 - max.1 } else { T::zero() }
103        );
104        if (outside.0 != T::zero()) || (outside.1 != T::zero()) { Some(outside) } else { None }
105    }
106    /// Returns true if the vecor is a zero-vector.
107    pub fn is_zero(self: &Self) -> bool {
108        self.0 == T::zero() && self.1 == T::zero()
109    }
110    /// Returns distance to other point.
111    pub fn distance(self: &Self, other: &Self) -> T{
112        let dv = *self - *other;
113        (dv.0 * dv.0 + dv.1 * dv.1).sqrt()
114    }
115}
116
117impl<T> Vector<T> for Vec2<T> where T: Copy {
118    fn as_vec3(&self, neutral: T) -> Vec3<T> {
119        Vec3::<T>(self.0, self.1, neutral)
120    }
121}
122
123// from angle
124
125impl<T> From<Angle<T>> for Vec2<T> where T: Float {
126    fn from(angle: Angle<T>) -> Vec2<T> {
127        Vec2::<T>(angle.0.cos(), angle.0.sin())
128    }
129}
130
131// from/to array
132
133impl<T> From<[ T; 2 ]> for Vec2<T> where T: Copy {
134    fn from(source: [ T; 2 ]) -> Self {
135        Vec2(source[0], source[1])
136    }
137}
138
139impl From<Vec2<f32>> for [ f32; 2 ] {
140    fn from(source: Vec2<f32>) -> Self {
141        [ source.0, source.1 ]
142    }
143}
144
145impl From<Vec2<f64>> for [ f64; 2 ] {
146    fn from(source: Vec2<f64>) -> Self {
147        [ source.0, source.1 ]
148    }
149}
150
151// from/to tuple struct
152
153impl<T> From<Point2<T>> for Vec2<T> {
154    fn from(source: Point2<T>) -> Self {
155        Vec2(source.0, source.1)
156    }
157}
158
159impl From<Vec2<f32>> for Point2<f32> {
160    fn from(source: Vec2<f32>) -> Self {
161        (source.0, source.1)
162    }
163}
164
165impl From<Vec2<f64>> for Point2<f64> {
166    fn from(source: Vec2<f64>) -> Self {
167        (source.0, source.1)
168    }
169}
170
171// Default
172
173impl<T> Default for Vec2<T> where T: Float {
174    fn default() -> Self {
175        Vec2(T::zero(), T::zero())
176    }
177}
178
179// operators
180
181impl<T> Neg for Vec2<T> where T: Float {
182    type Output = Vec2<T>;
183    fn neg(self) -> Vec2<T> {
184        Vec2::<T>(-self.0, -self.1)
185    }
186}
187
188impl<T> Add for Vec2<T> where T: Float {
189    type Output = Vec2<T>;
190    fn add(self, other: Vec2<T>) -> Vec2<T> {
191        Vec2::<T>(self.0 + other.0, self.1 + other.1)
192    }
193}
194
195impl<T> AddAssign for Vec2<T> where T: Float {
196    fn add_assign(self: &mut Self, other: Vec2<T>) {
197        *self = Vec2::<T> (
198            self.0 + other.0,
199            self.1 + other.1
200        )
201    }
202}
203
204impl<T> Sub for Vec2<T> where T: Float {
205    type Output = Vec2<T>;
206    fn sub(self, other: Vec2<T>) -> Vec2<T> {
207        Vec2::<T>(self.0 - other.0, self.1 - other.1)
208    }
209}
210
211impl<T> SubAssign for Vec2<T> where T: Float {
212    fn sub_assign(self: &mut Self, other: Vec2<T>) {
213        *self = Vec2::<T> (
214            self.0 - other.0,
215            self.1 - other.1
216        )
217    }
218}
219
220impl<T> Mul<Vec2<T>> for Vec2<T> where T: Float {
221    type Output = Vec2<T>;
222    /// Multiplies individual vector components with those of the given vector.
223    fn mul(self, other: Vec2<T>) -> Vec2<T> {
224        Vec2::<T>(self.0 * other.0, self.1 * other.1)
225    }
226}
227
228impl<T> MulAssign<Vec2<T>> for Vec2<T> where T: Float {
229    /// Mutates the vector by multiplying its components with those of the given vector.
230    fn mul_assign(&mut self, other: Vec2<T>) {
231        *self = Vec2::<T>(self.0 * other.0, self.1 * other.1)
232    }
233}
234
235impl<T> Mul<T> for Vec2<T> where T: Float {
236    type Output = Vec2<T>;
237    /// Multiplies the vector with given scalar operand.
238    fn mul(self, other: T) -> Vec2<T> {
239        Vec2::<T>(self.0 * other, self.1 * other)
240    }
241}
242
243impl<T> MulAssign<T> for Vec2<T> where T: Float {
244    /// Mutates the vector by multiplying it with the scalar operand.
245    fn mul_assign(&mut self, other: T) {
246        *self = Vec2::<T>(self.0 * other, self.1 * other)
247    }
248}
249
250impl<T> Div<Vec2<T>> for Vec2<T> where T: Float {
251    type Output = Vec2<T>;
252    /// Divides individual vector components with those of the given vector.
253    fn div(self, other: Vec2<T>) -> Vec2<T> {
254        Vec2::<T>(self.0 / other.0, self.1 / other.1)
255    }
256}
257
258impl<T> DivAssign<Vec2<T>> for Vec2<T> where T: Float {
259    /// Mutates the vector by dividing its components with those of the given vector.
260    fn div_assign(&mut self, other: Vec2<T>) {
261        *self = Vec2::<T>(self.0 / other.0, self.1 / other.1)
262    }
263}
264
265impl<T> Div<T> for Vec2<T> where T: Float {
266    type Output = Vec2<T>;
267    /// Divides the vector by given scalar operand.
268    fn div(self, other: T) -> Vec2<T> {
269        Vec2::<T>(self.0 / other, self.1 / other)
270    }
271}
272
273impl<T> DivAssign<T> for Vec2<T> where T: Float {
274    /// Mutates the vector by dividing it by given scalar.
275    fn div_assign(&mut self, other: T) {
276        *self = Vec2::<T>(self.0 / other, self.1 / other)
277    }
278}
279
280impl Mul<Vec2<f32>> for f32 {
281    type Output = Vec2<f32>;
282    fn mul(self, other: Vec2<f32>) -> Vec2<f32> {
283        Vec2::<f32>(self * other.0, self * other.1)
284    }
285}
286
287impl Mul<Vec2<f64>> for f64 {
288    type Output = Vec2<f64>;
289    fn mul(self, other: Vec2<f64>) -> Vec2<f64> {
290        Vec2::<f64>(self * other.0, self * other.1)
291    }
292}
293
294// as radiant uniform
295
296#[cfg(feature = "uniforms")]
297use radiant_rs::{Uniform, AsUniform};
298
299#[cfg(feature = "uniforms")]
300impl AsUniform for Vec2<f32> {
301    fn as_uniform(&self) -> Uniform {
302        Uniform::Vec2([ self.0, self.1 ])
303    }
304}
305
306#[cfg(feature = "uniforms")]
307impl AsUniform for Vec2<f64> {
308    fn as_uniform(&self) -> Uniform {
309        Uniform::DoubleVec2([ self.0, self.1 ])
310    }
311}
312
313// debug print
314
315impl<T> Debug for Vec2<T> where T: Debug {
316    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
317        write!(f, "Vec2({:?}, {:?})", self.0, self.1)
318    }
319}