static_math/
vector2.rs

1//-------------------------------------------------------------------------
2// @file vector2.rs
3//
4// @date 06/01/20 22:37:02
5// @author Martin Noblia
6// @email mnoblia@disroot.org
7//
8// @brief
9//
10// @detail
11//
12// Licence MIT:
13// Copyright <2020> <Martin Noblia>
14//
15// Permission is hereby granted, free of charge, to any person obtaining a copy
16// of this software and associated documentation files (the "Software"), to deal
17// in the Software without restriction, including without limitation the rights
18// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
19// copies of the Software, and to permit persons to whom the Software is
20// furnished to do so, subject to the following conditions:
21//
22// The above copyright notice and this permission notice shall be included in
23// all copies or substantial portions of the Software.  THE SOFTWARE IS PROVIDED
24// "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT
25// LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
26// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
27// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
28// ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
29// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
30//-------------------------------------------------------------------------
31use core::fmt;
32use num::{Float, Zero, Num, Signed};
33use core::ops::{Deref, DerefMut};
34use core::ops::{Add, Sub, Div, Mul, SubAssign, AddAssign, Neg};
35
36use crate::errors::VectorErrors;
37use crate::slices_methods::{norm_inf, norm_l};
38use crate::matrix2x2::*;
39
40//-------------------------------------------------------------------------
41//                        code
42//-------------------------------------------------------------------------
43#[derive(Copy, Clone, Debug, PartialEq)]
44pub struct V2<T>([T; 2]);
45
46impl<T> V2<T> {
47    /// create a new V2 from a static array
48    pub const fn new(input: [T; 2]) -> Self {
49        Self(input)
50    }
51
52    /// create a new V2 from raw numbers
53    pub const fn new_from(a: T, b: T) -> Self {
54        Self::new([a, b])
55    }
56}
57
58impl<T: Num + Copy> V2<T> {
59    /// create a V2 with all elements zero
60    pub fn zeros() -> Self {
61        <Self as Zero>::zero()
62    }
63
64    /// create a V2 with all elements one
65    pub fn ones() -> Self {
66        let one = T::one();
67        Self::new([one, one])
68    }
69
70}
71
72impl<T: Num + Copy + core::cmp::PartialOrd> V2<T> {
73    pub fn norm_inf(&self) -> T {
74        norm_inf(&**self)
75    }
76}
77
78impl<T: Num + Copy + Signed + core::iter::Sum> V2<T> {
79    pub fn norm_l(&self) -> T {
80        norm_l(&**self)
81    }
82}
83
84impl<T: Num + Copy + Signed> Neg for V2<T> {
85    type Output = Self;
86
87    #[inline]
88    fn neg(self) -> Self {
89        Self::new_from(-self[0], -self[1])
90    }
91}
92
93impl<T: Float> V2<T> {
94
95    /// calculate the euclidean norm of the V2
96    pub fn norm2(&self) -> T {
97        T::sqrt(self[0] * self[0] + self[1] * self[1])
98    }
99
100    /// normalize the current V2 and return a new one
101    pub fn normalize(&self) -> Result<Self, VectorErrors> {
102        let n = self.norm2();
103        if n != T::zero() {
104            // this method return a new fresh and clean vector :)
105            let mut result = Self::zeros();
106            for i in 0..self.len() {
107                result[i] = self[i] / n;
108            }
109            Ok(result)
110        } else {
111            Err(VectorErrors::Norm2IsZero)
112        }
113    }
114}
115
116impl<T: Num + Copy> Mul for V2<T> {
117    type Output = T;
118
119    #[inline]
120    fn mul(self, rhs: Self) -> T {
121        self[0] * rhs[0] + self[1] * rhs[1]
122    }
123}
124
125// TODO(elsuizo:2020-05-01): missing constant * V2
126// V2 * constant
127impl<T: Num + Copy> Mul<T> for V2<T> {
128    type Output = V2<T>;
129
130    #[inline]
131    fn mul(self, rhs: T) -> V2<T> {
132        Self::new_from(self[0] * rhs, self[1] * rhs)
133    }
134}
135
136// V2 / const
137impl<T: Num + Copy> Div<T> for V2<T> {
138    type Output = Self;
139
140    #[inline]
141    fn div(self, rhs: T) -> Self::Output {
142        Self::new_from(self[0] / rhs, self[1] / rhs)
143    }
144}
145
146// FIXME(elsuizo:2020-06-19): this code dont compile i dont known why
147//impl<T: Num + Copy> Mul<V2<T>> for T {
148//    type Output = V2<T>;
149//
150//    fn mul(self, rhs: V2<T>) -> V2<T> {
151//        let a0 = self * rhs[0];
152//        let a1 = self * rhs[1];
153//        V2::new([a0, a1])
154//    }
155//}
156
157impl Mul<V2<f32>> for f32 {
158    type Output = V2<f32>;
159
160    #[inline]
161    fn mul(self, rhs: V2<f32>) -> V2<f32> {
162        V2::new_from(self * rhs[0], self * rhs[1])
163    }
164}
165
166// V2 * M22
167impl<T: Num + Copy> Mul<M22<T>> for V2<T> {
168    type Output = V2<T>;
169
170    #[inline]
171    fn mul(self, rhs: M22<T>) -> V2<T> {
172        Self::new_from(self[0] * rhs[(0, 0)] + self[1] * rhs[(1, 0)],
173                     self[0] * rhs[(0, 1)] + self[1] * rhs[(1, 1)])
174    }
175}
176
177// V2 - V2
178impl<T: Num + Copy> Sub for V2<T> {
179    type Output = Self;
180
181    #[inline]
182    fn sub(self, rhs: Self) -> Self {
183        Self::new_from(self[0] - rhs[0], self[1] - rhs[1])
184    }
185}
186
187// V2 -= V2
188impl<T: Num + Copy> SubAssign for V2<T> {
189    #[inline]
190    fn sub_assign(&mut self, other: Self) {
191        *self = *self - other
192    }
193}
194
195// V2 + V2
196impl<T: Num + Copy> Add for V2<T> {
197    type Output = Self;
198    #[inline]
199    fn add(self, rhs: Self) -> Self {
200        Self::new_from(self[0] + rhs[0], self[1] + rhs[1])
201    }
202}
203
204// V2 += V2
205impl<T: Num + Copy> AddAssign for V2<T> {
206    fn add_assign(&mut self, other: Self) {
207        *self = *self + other
208    }
209}
210
211// Zero trait
212impl<T: Num + Copy> Zero for V2<T> {
213    #[inline]
214    fn zero() -> V2<T> {
215        Self::new_from(T::zero(), T::zero())
216    }
217
218    fn is_zero(&self) -> bool {
219        *self == V2::zero()
220    }
221}
222
223impl<T> Deref for V2<T> {
224    type Target = [T; 2];
225    #[inline]
226    fn deref(&self) -> &Self::Target {
227        &self.0
228    }
229}
230
231impl<T> DerefMut for V2<T> {
232    #[inline]
233    fn deref_mut(&mut self) -> &mut Self::Target {
234        &mut self.0
235    }
236}
237
238//-------------------------------------------------------------------------
239//                        Display impl
240//-------------------------------------------------------------------------
241impl<T: Num + fmt::Display> fmt::Display for V2<T> {
242    fn fmt(&self, dest: &mut fmt::Formatter) -> fmt::Result {
243        writeln!(dest, "[{0:^3.2} {1:^3.2}]", self[0], self[1])
244    }
245}
246
247//-------------------------------------------------------------------------
248//                        tests
249//-------------------------------------------------------------------------
250#[cfg(test)]
251mod vector2_test {
252
253    use crate::vector2::V2;
254
255    #[test]
256    fn create_vector2_test() {
257        let v = V2::new([1.0, 2.0]);
258        assert_eq!(v[0], 1.0);
259        assert_eq!(v[1], 2.0);
260    }
261
262    #[test]
263    fn zero_vector2_test() {
264        let result: V2<f64> = V2::zeros();
265        let expected = V2::new([0.0, 0.0]);
266        assert_eq!(
267            &result[..],
268            &expected[..],
269            "\nExpected\n{:?}\nfound\n{:?}",
270            &result[..],
271            &expected[..]
272        );
273    }
274
275    #[test]
276    fn product_test() {
277        let v1 = V2::new([1.0, 2.0]);
278        let v2 = V2::new([3.0, 4.0]);
279        let result = v1 * v2;
280        let expected = 11.0;
281        assert_eq!(result, expected);
282    }
283
284    #[test]
285    fn add_test() {
286        let v1 = V2::new([1.0, 2.0]);
287        let v2 = V2::new([3.0, 4.0]);
288        let result = v1 + v2;
289        let expected = V2::new([4.0, 6.0]);
290        assert_eq!(
291            &result[..],
292            &expected[..],
293            "\nExpected\n{:?}\nfound\n{:?}",
294            &result[..],
295            &expected[..]
296        );
297    }
298
299    #[test]
300    fn sub_test() {
301        let v1 = V2::new([1.0, 2.0]);
302        let v2 = V2::new([2.0, 3.0]);
303        let expected = V2::new([-1.0, -1.0]);
304        let result = v1 - v2;
305
306        assert_eq!(
307            &result[..],
308            &expected[..],
309            "\nExpected\n{:?}\nfound\n{:?}",
310            &result[..],
311            &expected[..]
312        );
313    }
314
315    #[test]
316    fn mul_const_rhs() {
317        let v1 = V2::new_from(1.0, 2.0);
318        let result = 2.0 * v1;
319        let expected = V2::new_from(2.0, 4.0);
320        assert_eq!(
321            &result[..],
322            &expected[..],
323            "\nExpected\n{:?}\nfound\n{:?}",
324            &result[..],
325            &expected[..]
326        );
327
328    }
329
330    #[test]
331    fn mul_const() {
332        let v1 = V2::new_from(1.0, 2.0);
333        let result = v1 * 10.0;
334        let expected = V2::new_from(10.0, 20.0);
335        assert_eq!(
336            &result[..],
337            &expected[..],
338            "\nExpected\n{:?}\nfound\n{:?}",
339            &result[..],
340            &expected[..]
341        );
342    }
343
344    #[test]
345    fn norm2_test() {
346        let v1 = V2::new_from(1.0, 2.0);
347        let expected = 2.23606797749979;
348        let result = v1.norm2();
349        assert_eq!(result, expected);
350    }
351
352    #[test]
353    fn normalize_test() {
354        let result = V2::new([1.0, 1.0]).normalize().unwrap();
355        let expected = V2::new([0.7071067811865475, 0.7071067811865475]);
356        assert_eq!(
357            &result[..],
358            &expected[..],
359            "\nExpected\n{:?}\nfound\n{:?}",
360            &result[..],
361            &expected[..]
362        );
363    }
364
365    #[test]
366    fn sub_assigment_test() {
367        let mut result = V2::new_from(1.0, 3.0);
368        let v2 = V2::new_from(3.0, 3.0);
369        let expected = V2::new_from(-2.0, 0.0);
370        result -= v2;
371        assert_eq!(
372            &result[..],
373            &expected[..],
374            "\nExpected\n{:?}\nfound\n{:?}",
375            &result[..],
376            &expected[..]
377        );
378    }
379
380    #[test]
381    fn add_assigment_test() {
382        let mut result = V2::new_from(1.0, 3.0);
383        let v2 = V2::new_from(3.0, 3.0);
384        let expected = V2::new_from(4.0, 6.0);
385        result += v2;
386        assert_eq!(
387            &result[..],
388            &expected[..],
389            "\nExpected\n{:?}\nfound\n{:?}",
390            &result[..],
391            &expected[..]
392        );
393    }
394
395    #[test]
396    fn norm_inf_test() {
397        let v = V2::new_from(1, 10);
398        let result = v.norm_inf();
399        let expected = 10;
400        assert_eq!(result, expected);
401    }
402
403    #[test]
404    fn norm_l_test() {
405        let v = V2::new_from(-1, 1);
406        let result = v.norm_l();
407        let expected = 2;
408        assert_eq!(result, expected);
409    }
410}