nova_math/vector/
vector2.rs

1/*
2 *
3 * This file is a part of NovaEngine
4 * https://gitlab.com/MindSpunk/NovaEngine
5 *
6 *
7 * MIT License
8 *
9 * Copyright (c) 2018 Nathan Voglsam
10 *
11 * Permission is hereby granted, free of charge, to any person obtaining a copy
12 * of this software and associated documentation files (the "Software"), to deal
13 * in the Software without restriction, including without limitation the rights
14 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
15 * copies of the Software, and to permit persons to whom the Software is
16 * furnished to do so, subject to the following conditions:
17 *
18 * The above copyright notice and this permission notice shall be included in all
19 * copies or substantial portions of the Software.
20 *
21 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
22 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
23 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
24 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
25 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
26 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
27 * SOFTWARE.
28 */
29
30use crate::traits::{DotProduct, Length, LengthSquared, Lerp, Normalize, NormalizeAssign, Real};
31use crate::vector::TVec3;
32use crate::vector::TVec4;
33use core::fmt::{Display, Error, Formatter};
34use core::ops::{
35    Add, AddAssign, Div, DivAssign, Index, IndexMut, Mul, MulAssign, Neg, Sub, SubAssign,
36};
37
38//==================================================================================================
39///
40/// A generic 2 component vector
41///
42#[repr(align(16))]
43#[derive(Copy, Clone, Debug)]
44pub struct TVec2<T: Real> {
45    pub(crate) data: [T; 2],
46}
47
48///
49/// Const fn for constructing a TVec2 in a const context
50///
51pub const fn vector_2_f32(x: f32, y: f32) -> TVec2<f32> {
52    TVec2::<f32> { data: [x, y] }
53}
54
55///
56/// Const fn for constructing a TVec2 in a const context
57///
58pub const fn vector_2_f64(x: f64, y: f64) -> TVec2<f64> {
59    TVec2::<f64> { data: [x, y] }
60}
61
62impl<T: Real> TVec2<T> {
63    ///
64    /// Construct a new Vec2
65    ///
66    #[inline]
67    pub fn new(x: T, y: T) -> Self {
68        TVec2 { data: [x, y] }
69    }
70
71    ///
72    /// Return a vector with all zeroes
73    ///
74    #[inline]
75    pub fn zero() -> Self {
76        Self::new(T::zero(), T::zero())
77    }
78
79    ///
80    /// Return a vector with all ones
81    ///
82    #[inline]
83    pub fn one() -> Self {
84        Self::new(T::one(), T::one())
85    }
86
87    ///
88    /// Return a unit vector that points in the up direction
89    ///
90    #[inline]
91    pub fn up() -> Self {
92        Self::new(T::zero(), T::one())
93    }
94
95    ///
96    /// Return a unit vector that points in the down direction
97    ///
98    #[inline]
99    pub fn down() -> Self {
100        Self::new(T::zero(), -T::one())
101    }
102
103    ///
104    /// Return a unit vector that points in the right direction
105    ///
106    #[inline]
107    pub fn right() -> Self {
108        Self::new(T::one(), T::zero())
109    }
110
111    ///
112    /// Return a unit vector that points in the left direction
113    ///
114    #[inline]
115    pub fn left() -> Self {
116        Self::new(-T::one(), T::zero())
117    }
118}
119
120impl<T: Real> Display for TVec2<T> {
121    fn fmt(&self, f: &mut Formatter) -> Result<(), Error> {
122        write!(
123            f,
124            "[ {:precision$} {:precision$} ]",
125            self.data[0],
126            self.data[1],
127            precision = f.precision().unwrap_or(f.width().unwrap_or(4)),
128        )
129    }
130}
131
132impl<T: Real> From<T> for TVec2<T> {
133    ///
134    /// Take a value as the x component of a Vec2 and leave the y component as 0
135    ///
136    #[inline]
137    fn from(other: T) -> Self {
138        Self::new(other, T::zero())
139    }
140}
141
142impl<T: Real> From<TVec3<T>> for TVec2<T> {
143    ///
144    /// Take the xy components of a Vec3 and produce a Vec2
145    ///
146    #[inline]
147    fn from(other: TVec3<T>) -> Self {
148        Self::new(other.data[0], other.data[1])
149    }
150}
151
152impl<T: Real> From<TVec4<T>> for TVec2<T> {
153    ///
154    /// Take the xy components of a Vec4 and produce a Vec2
155    ///
156    #[inline]
157    fn from(other: TVec4<T>) -> Self {
158        Self::new(other.data[0], other.data[1])
159    }
160}
161
162impl<T: Real> From<[T; 2]> for TVec2<T> {
163    ///
164    /// Take the array as a vector
165    ///
166    #[inline]
167    fn from(other: [T; 2]) -> Self {
168        Self { data: other }
169    }
170}
171
172impl<T: Real> Into<[T; 2]> for TVec2<T> {
173    #[inline]
174    fn into(self) -> [T; 2] {
175        self.data
176    }
177}
178
179impl<T: Real> From<(T, T)> for TVec2<T> {
180    ///
181    /// Take the array as a vector
182    ///
183    #[inline]
184    fn from(other: (T, T)) -> Self {
185        Self {
186            data: [other.0, other.1],
187        }
188    }
189}
190
191impl<T: Real> Into<(T, T)> for TVec2<T> {
192    #[inline]
193    fn into(self) -> (T, T) {
194        (self.data[0], self.data[1])
195    }
196}
197
198impl<T: Real> Index<usize> for TVec2<T> {
199    type Output = T;
200
201    #[inline]
202    fn index(&self, index: usize) -> &Self::Output {
203        &self.data[index]
204    }
205}
206
207impl<T: Real> IndexMut<usize> for TVec2<T> {
208    #[inline]
209    fn index_mut(&mut self, index: usize) -> &mut Self::Output {
210        &mut self.data[index]
211    }
212}
213
214//
215// VEC2 <-> VEC2 MATH TRAIT IMPLS
216//
217
218impl<T: Real> Add<TVec2<T>> for TVec2<T> {
219    type Output = TVec2<T>;
220
221    #[inline]
222    fn add(mut self, rhs: TVec2<T>) -> Self::Output {
223        self.data[0] += rhs.data[0];
224        self.data[1] += rhs.data[1];
225        self
226    }
227}
228
229impl<T: Real> AddAssign<TVec2<T>> for TVec2<T> {
230    #[inline]
231    fn add_assign(&mut self, rhs: TVec2<T>) {
232        self.data[0] += rhs.data[0];
233        self.data[1] += rhs.data[1];
234    }
235}
236
237impl<T: Real> Sub<TVec2<T>> for TVec2<T> {
238    type Output = TVec2<T>;
239
240    #[inline]
241    fn sub(mut self, rhs: TVec2<T>) -> Self::Output {
242        self.data[0] -= rhs.data[0];
243        self.data[1] -= rhs.data[1];
244        self
245    }
246}
247
248impl<T: Real> SubAssign<TVec2<T>> for TVec2<T> {
249    #[inline]
250    fn sub_assign(&mut self, rhs: TVec2<T>) {
251        self.data[0] -= rhs.data[0];
252        self.data[1] -= rhs.data[1];
253    }
254}
255
256impl<T: Real> Mul<TVec2<T>> for TVec2<T> {
257    type Output = TVec2<T>;
258
259    #[inline]
260    fn mul(mut self, rhs: TVec2<T>) -> Self::Output {
261        self.data[0] *= rhs.data[0];
262        self.data[1] *= rhs.data[1];
263        self
264    }
265}
266
267impl<T: Real> MulAssign<TVec2<T>> for TVec2<T> {
268    #[inline]
269    fn mul_assign(&mut self, rhs: TVec2<T>) {
270        self.data[0] *= rhs.data[0];
271        self.data[1] *= rhs.data[1];
272    }
273}
274
275impl<T: Real> Div<TVec2<T>> for TVec2<T> {
276    type Output = TVec2<T>;
277
278    #[inline]
279    fn div(mut self, rhs: TVec2<T>) -> Self::Output {
280        self.data[0] /= rhs.data[0];
281        self.data[1] /= rhs.data[1];
282        self
283    }
284}
285
286impl<T: Real> DivAssign<TVec2<T>> for TVec2<T> {
287    #[inline]
288    fn div_assign(&mut self, rhs: TVec2<T>) {
289        self.data[0] /= rhs.data[0];
290        self.data[1] /= rhs.data[1];
291    }
292}
293
294//
295// VEC2 <-> FLOAT MATH TRAITS IMPLS
296//
297
298impl<T: Real> Add<T> for TVec2<T> {
299    type Output = TVec2<T>;
300
301    #[inline]
302    fn add(mut self, rhs: T) -> Self::Output {
303        self.data[0] += rhs;
304        self.data[1] += rhs;
305        self
306    }
307}
308
309impl<T: Real> AddAssign<T> for TVec2<T> {
310    #[inline]
311    fn add_assign(&mut self, rhs: T) {
312        self.data[0] += rhs;
313        self.data[1] += rhs;
314    }
315}
316
317impl<T: Real> Sub<T> for TVec2<T> {
318    type Output = TVec2<T>;
319
320    #[inline]
321    fn sub(mut self, rhs: T) -> Self::Output {
322        self.data[0] -= rhs;
323        self.data[1] -= rhs;
324        self
325    }
326}
327
328impl<T: Real> SubAssign<T> for TVec2<T> {
329    #[inline]
330    fn sub_assign(&mut self, rhs: T) {
331        self.data[0] -= rhs;
332        self.data[1] -= rhs;
333    }
334}
335
336impl<T: Real> Mul<T> for TVec2<T> {
337    type Output = TVec2<T>;
338
339    #[inline]
340    fn mul(mut self, rhs: T) -> Self::Output {
341        self.data[0] *= rhs;
342        self.data[1] *= rhs;
343        self
344    }
345}
346
347impl<T: Real> MulAssign<T> for TVec2<T> {
348    #[inline]
349    fn mul_assign(&mut self, rhs: T) {
350        self.data[0] *= rhs;
351        self.data[1] *= rhs;
352    }
353}
354
355impl<T: Real> Div<T> for TVec2<T> {
356    type Output = TVec2<T>;
357
358    #[inline]
359    fn div(mut self, rhs: T) -> Self::Output {
360        self.data[0] /= rhs;
361        self.data[1] /= rhs;
362        self
363    }
364}
365
366impl<T: Real> DivAssign<T> for TVec2<T> {
367    #[inline]
368    fn div_assign(&mut self, rhs: T) {
369        self.data[0] /= rhs;
370        self.data[1] /= rhs;
371    }
372}
373
374impl<T: Real> Neg for TVec2<T> {
375    type Output = Self;
376
377    #[inline]
378    fn neg(mut self) -> Self::Output {
379        self.data[0] = -self.data[0];
380        self.data[1] = -self.data[1];
381        self
382    }
383}
384
385impl<T: Real> Lerp<T> for TVec2<T> {
386    #[inline]
387    fn lerp(&self, b: &Self, factor: T) -> Self {
388        *self + ((*self - *b) * factor)
389    }
390}
391
392impl<T: Real> Length for TVec2<T> {
393    type Output = T;
394
395    #[inline]
396    fn length(&self) -> Self::Output {
397        self.length_squared().sqrt()
398    }
399}
400
401impl<T: Real> LengthSquared for TVec2<T> {
402    type Output = T;
403
404    #[inline]
405    fn length_squared(&self) -> Self::Output {
406        self.dot(self)
407    }
408}
409
410impl<T: Real> Normalize for TVec2<T> {
411    #[inline]
412    fn normalize(mut self) -> Self {
413        self.normalize_assign();
414        self
415    }
416}
417
418impl<T: Real> NormalizeAssign for TVec2<T> {
419    #[inline]
420    fn normalize_assign(&mut self) {
421        let len = self.length();
422        *self *= T::one() / len;
423    }
424}
425
426impl<T: Real> DotProduct<T> for TVec2<T> {
427    #[inline]
428    fn dot(&self, rhs: &Self) -> T {
429        (self.data[0] * rhs.data[0]) + (self.data[1] * rhs.data[1])
430    }
431}
432
433impl<T: Real> PartialEq<TVec2<T>> for TVec2<T> {
434    #[inline]
435    fn eq(&self, other: &TVec2<T>) -> bool {
436        self.data[0] == other.data[0] && self.data[1] == other.data[1]
437    }
438
439    #[inline]
440    fn ne(&self, other: &TVec2<T>) -> bool {
441        self.data[0] != other.data[0] || self.data[1] != other.data[1]
442    }
443}