vex/
vector4.rs

1use crate::common;
2use crate::vector3::Vector3;
3
4use std::cmp;
5use std::convert::From;
6use std::f32::EPSILON;
7use std::fmt;
8use std::fmt::{Display, Formatter};
9
10use std::ops::{
11    Index,
12    IndexMut,
13    Neg,
14    Add,
15    AddAssign,
16    Sub,
17    SubAssign,
18    Mul,
19    MulAssign,
20    Div,
21    DivAssign,
22};
23
24#[repr(C, packed)]
25#[derive(Copy, Clone, Debug)]
26pub struct Vector4 {
27    pub x: f32,
28    pub y: f32,
29    pub z: f32,
30    pub w: f32,
31}
32
33impl Vector4 {
34    /// Creates a vector <0.0, 0.0, 0.0, 0.0>
35    ///
36    /// # Examples
37    /// ```
38    /// use vex::Vector4;
39    /// 
40    /// let actual = Vector4::new();
41    /// let expected = Vector4 { x: 0.0, y: 0.0, z: 0.0, w: 0.0 };
42    /// assert_eq!(actual, expected);
43    /// ```
44    #[inline]
45    pub fn new() -> Vector4 {
46        Vector4 {
47            x: 0.0,
48            y: 0.0,
49            z: 0.0,
50            w: 0.0,
51        }
52    }
53
54    /// Creates a vector <0.0, 0.0, 0.0, 0.0>
55    ///
56    /// # Examples
57    /// ```
58    /// use vex::Vector4;
59    /// 
60    /// let actual = Vector4::one();
61    /// let expected = Vector4 { x: 1.0, y: 1.0, z: 1.0, w: 1.0 };
62    /// assert_eq!(actual, expected);
63    /// ```
64    #[inline]
65    pub fn one() -> Vector4 {
66        Vector4 {
67            x: 1.0,
68            y: 1.0,
69            z: 1.0,
70            w: 1.0,
71        }
72    }
73
74    /// Creates a vector from the provided values
75    ///
76    /// # Examples
77    /// ```
78    /// use vex::Vector4;
79    /// 
80    /// let actual = Vector4::make(1.0, 2.0, 3.0, 4.0);
81    /// let expected = Vector4 { x: 1.0, y: 2.0, z: 3.0, w: 4.0 };
82    /// assert_eq!(actual, expected);
83    /// ```
84    #[inline]
85    pub fn make(x: f32, y: f32, z: f32, w: f32) -> Vector4 {
86        Vector4 { x, y, z, w }
87    }
88
89    /// Find the dot product between two vectors
90    ///
91    /// # Examples
92    /// ```
93    /// use vex::Vector4;
94    /// 
95    /// let a = Vector4::make(1.0, 0.0, 0.0, 0.0);
96    /// let b = Vector4::make(0.0, 0.0, 1.0, 0.0);
97    /// let actual = Vector4::dot(&a, &b);
98    /// let expected = 0.0;
99    /// assert_eq!(actual, expected);
100    /// ```
101    #[inline]
102    pub fn dot(a: &Vector4, b: &Vector4) -> f32 {
103        a.x * b.x + a.y * b.y + a.z * b.z + a.w * b.w
104    }
105
106    /// Find the minimum (component-wise) vector between two vectors
107    ///
108    /// # Examples
109    /// ```
110    /// use vex::Vector4;
111    /// 
112    /// let a = Vector4::make(1.0, 4.0, 5.0, 7.0);
113    /// let b = Vector4::make(2.0, 3.0, 6.0, 8.0);
114    /// let actual = Vector4::min(&a, &b);
115    /// let expected = Vector4::make(1.0, 3.0, 5.0, 7.0);
116    /// assert_eq!(actual, expected);
117    /// ```
118    #[inline]
119    pub fn min(a: &Vector4, b: &Vector4) -> Vector4 {
120        Vector4::make(a.x.min(b.x), a.y.min(b.y), a.z.min(b.z), a.w.min(b.w))
121    }
122
123    /// Find the maximum (component-wise) vector between two vectors
124    ///
125    /// # Examples
126    /// ```
127    /// use vex::Vector4;
128    /// 
129    /// let a = Vector4::make(1.0, 4.0, 5.0, 7.0);
130    /// let b = Vector4::make(2.0, 3.0, 6.0, 8.0);
131    /// let actual = Vector4::max(&a, &b);
132    /// let expected = Vector4::make(2.0, 4.0, 6.0, 8.0);
133    /// assert_eq!(actual, expected);
134    /// ```
135    #[inline]
136    pub fn max(a: &Vector4, b: &Vector4) -> Vector4 {
137        Vector4::make(a.x.max(b.x), a.y.max(b.y), a.z.max(b.z), a.w.max(b.w))
138    }
139
140    /// Find the clamped (component-wise) vector between two vectors
141    ///
142    /// # Examples
143    /// ```
144    /// use vex::Vector4;
145    /// 
146    /// let a = Vector4::make(1.0, 3.0, 5.0, 7.0);
147    /// let b = Vector4::make(2.0, 4.0, 6.0, 8.0);
148    /// let mut actual = Vector4::make(0.0, 5.0, 10.0, 20.0);
149    /// actual.clamp(&a, &b);
150    /// let expected = Vector4::make(1.0, 4.0, 6.0, 8.0);
151    /// assert_eq!(actual, expected);
152    /// ```
153    #[inline]
154    pub fn clamp(&mut self, a: &Vector4, b: &Vector4) {
155        let low = Self::min(a, b);
156        let high = Self::max(a, b);
157        let result = Self::max(&low, &Self::min(self, &high));
158        self.set(result.x, result.y, result.z, result.w);
159    }
160
161    /// Set the components of a vector
162    ///
163    /// # Examples
164    /// ```
165    /// use vex::Vector4;
166    /// 
167    /// let mut actual = Vector4::new();
168    /// actual.set(1.0, 2.0, 3.0, 4.0);
169    /// let expected = Vector4::make(1.0, 2.0, 3.0, 4.0);
170    /// assert_eq!(actual, expected);
171    /// ```
172    #[inline]
173    pub fn set(&mut self, x: f32, y: f32, z: f32, w: f32) {
174        self.x = x;
175        self.y = y;
176        self.z = z;
177        self.w = w;
178    }
179
180    /// Get the magnitude of the vector
181    ///
182    /// # Examples
183    /// ```
184    /// use vex::Vector4;
185    /// 
186    /// let actual = Vector4::make(1.0, 2.0, 3.0, 4.0).mag();
187    /// let expected = 5.47722557505;
188    /// assert_eq!(actual, expected);
189    /// ```
190    #[inline]
191    pub fn mag(&self) -> f32 {
192        self.mag_sq().sqrt()
193    }
194
195    /// Get the squared magnitude of the vector
196    ///
197    /// # Examples
198    /// ```
199    /// use vex::Vector4;
200    /// 
201    /// let actual = Vector4::make(1.0, 2.0, 3.0, 4.0).mag_sq();
202    /// let expected = 30.0;
203    /// assert_eq!(actual, expected);
204    /// ```
205    #[inline]
206    pub fn mag_sq(&self) -> f32 {
207        self.x * self.x + self.y * self.y + self.z * self.z + self.w * self.w
208    }
209
210    /// Normalize the vector
211    ///
212    /// # Examples
213    /// ```
214    /// use vex::Vector4;
215    /// 
216    /// let mut actual = Vector4::make(1.0, 2.0, 3.0, 4.0);
217    /// actual.norm();
218    /// let expected = Vector4::make(0.18257418, 0.36514837, 0.5477225, 0.73029673);
219    /// assert_eq!(actual, expected);
220    /// ```
221    #[inline]
222    pub fn norm(&mut self) -> f32 {
223        let length = self.mag();
224        if length > EPSILON {
225            self.x /= length;
226            self.y /= length;
227            self.z /= length;
228            self.w /= length;
229            length
230        } else {
231            0.0
232        }
233    }
234
235    /// Set the components of a vector to their absolute values
236    ///
237    /// # Examples
238    /// ```
239    /// use vex::Vector4;
240    /// 
241    /// let mut actual = Vector4::make(-1.0, -2.0, -3.0, -4.0);
242    /// actual.abs();
243    /// let expected = Vector4::make(1.0, 2.0, 3.0, 4.0);
244    /// assert_eq!(actual, expected);
245    /// ```
246    #[inline]
247    pub fn abs(&mut self) {
248        self.x = self.x.abs();
249        self.y = self.y.abs();
250        self.z = self.z.abs();
251        self.w = self.w.abs();
252    }
253
254    /// Determine whether or not all components of the vector are valid
255    ///
256    /// # Examples
257    /// ```
258    /// use vex::Vector4;
259    /// 
260    /// let actual = Vector4::make(1.0, 2.0, 3.0, 4.0);
261    /// assert!(actual.is_valid());
262    /// ```
263    #[inline]
264    pub fn is_valid(&self) -> bool {
265        for i in 0..4 {
266            if !common::is_valid(self[i]) {
267                return false;
268            }
269        }
270
271        true
272    }
273}
274
275impl From<Vector3> for Vector4 {
276    /// Creates a Vector4 from the components of a Vector3
277    ///
278    /// # Examples
279    /// ```
280    /// use vex::Vector3;
281    /// use vex::Vector4;
282    /// 
283    /// let input = Vector3::make(1.0, 2.0, 3.0);
284    /// let actual = Vector4::from(input);
285    /// let expected = Vector4 { x: 1.0, y: 2.0, z: 3.0, w: 0.0 };
286    /// assert_eq!(actual, expected);
287    /// ```
288    #[inline]
289    fn from(item: Vector3) -> Vector4 {
290        Vector4 {
291            x: item.x,
292            y: item.y,
293            z: item.z,
294            w: 0.0,
295        }
296    }
297}
298
299impl Index<u32> for Vector4 {
300    type Output = f32;
301
302    /// Looks up a component by index
303    ///
304    /// # Examples
305    /// ```
306    /// use vex::Vector4;
307    /// 
308    /// let mut v = Vector4::make(1.0, 2.0, 3.0, 4.0);
309    /// assert_eq!(v[0], 1.0);
310    /// assert_eq!(v[1], 2.0);
311    /// assert_eq!(v[2], 3.0);
312    /// assert_eq!(v[3], 4.0);
313    /// ```
314    #[inline]
315    fn index(&self, index: u32) -> &f32 {
316        unsafe {
317            match index {
318                0 => &self.x,
319                1 => &self.y,
320                2 => &self.z,
321                3 => &self.w,
322                _ => panic!("Invalid index for Vector4: {}", index),
323            }
324        }
325    }
326}
327
328impl IndexMut<u32> for Vector4 {
329    /// Mutate a component by index
330    ///
331    /// # Examples
332    /// ```
333    /// use vex::Vector4;
334    /// 
335    /// let mut v = Vector4::new();
336    /// v[0] = 4.0;
337    /// v[1] = 5.0;
338    /// v[2] = 6.0;
339    /// v[3] = 7.0;
340    /// assert_eq!(v[0], 4.0);
341    /// assert_eq!(v[1], 5.0);
342    /// assert_eq!(v[2], 6.0);
343    /// assert_eq!(v[3], 7.0);
344    /// ```
345    #[inline]
346    fn index_mut<'a>(&'a mut self, index: u32) -> &'a mut f32 {
347        unsafe {
348            match index {
349                0 => &mut self.x,
350                1 => &mut self.y,
351                2 => &mut self.z,
352                3 => &mut self.w,
353                _ => panic!("Invalid index for Vector4: {}", index),
354            }
355        }
356    }
357}
358
359impl Neg for Vector4 {
360    type Output = Vector4;
361
362    /// Negates all components in a vector
363    ///
364    /// # Examples
365    /// ```
366    /// use vex::Vector4;
367    /// 
368    /// let actual = -Vector4::make(1.0, 2.0, 3.0, 4.0);
369    /// let expected = Vector4::make(-1.0, -2.0, -3.0, -4.0);
370    /// assert_eq!(actual, expected);
371    /// ```
372    #[inline]
373    fn neg(self) -> Vector4 {
374        Vector4::make(-self.x, -self.y, -self.z, -self.w)
375    }
376}
377
378impl Add<f32> for Vector4 {
379    type Output = Vector4;
380
381    /// Find the resulting vector by adding a scalar to a vector's components
382    ///
383    /// # Examples
384    /// ```
385    /// use vex::Vector4;
386    /// 
387    /// let actual = Vector4::make(1.0, 2.0, 3.0, 4.0) + 1.0;
388    /// let expected = Vector4::make(2.0, 3.0, 4.0, 5.0);
389    /// assert_eq!(actual, expected);
390    /// ```
391    #[inline]
392    fn add(self, _rhs: f32) -> Vector4 {
393        Vector4::make(self.x + _rhs, self.y + _rhs, self.z + _rhs, self.w + _rhs)
394    }
395}
396
397impl Add<Vector4> for Vector4 {
398    type Output = Vector4;
399
400    /// Add two vectors
401    ///
402    /// # Examples
403    /// ```
404    /// use vex::Vector4;
405    /// 
406    /// let a = Vector4::make(1.0, 2.0, 3.0, 4.0);
407    /// let b = Vector4::make(5.0, 6.0, 7.0, 8.0);
408    /// let actual = a + b;
409    /// let expected = Vector4::make(6.0, 8.0, 10.0, 12.0);
410    /// assert_eq!(actual, expected);
411    /// ```
412    #[inline]
413    fn add(self, _rhs: Vector4) -> Vector4 {
414        Vector4::make(
415            self.x + _rhs.x,
416            self.y + _rhs.y,
417            self.z + _rhs.z,
418            self.w + _rhs.w,
419        )
420    }
421}
422
423impl AddAssign<f32> for Vector4 {
424    /// Increment a vector by a scalar
425    ///
426    /// # Examples
427    /// ```
428    /// use vex::Vector4;
429    /// 
430    /// let mut actual = Vector4::make(1.0, 2.0, 3.0, 4.0);
431    /// actual += 10.0;
432    /// let expected = Vector4::make(11.0, 12.0, 13.0, 14.0);
433    /// assert_eq!(actual, expected);
434    /// ```
435    #[inline]
436    fn add_assign(&mut self, _rhs: f32) {
437        self.x += _rhs;
438        self.y += _rhs;
439        self.z += _rhs;
440        self.w += _rhs;
441    }
442}
443
444impl AddAssign<Vector4> for Vector4 {
445    /// Increment a vector by another vector
446    ///
447    /// # Examples
448    /// ```
449    /// use vex::Vector4;
450    /// 
451    /// let mut actual = Vector4::make(1.0, 2.0, 3.0, 4.0);
452    /// actual += Vector4::make(1.0, 2.0, 3.0, 4.0);
453    /// let expected = Vector4::make(2.0, 4.0, 6.0, 8.0);
454    /// assert_eq!(actual, expected);
455    /// ```
456    #[inline]
457    fn add_assign(&mut self, _rhs: Vector4) {
458        self.x += _rhs.x;
459        self.y += _rhs.y;
460        self.z += _rhs.z;
461        self.w += _rhs.w;
462    }
463}
464
465impl Sub<f32> for Vector4 {
466    type Output = Vector4;
467
468    /// Find the resulting vector by subtracting a scalar from a vector's components
469    ///
470    /// # Examples
471    /// ```
472    /// use vex::Vector4;
473    /// 
474    /// let actual = Vector4::make(1.0, 2.0, 3.0, 4.0) - 10.0;
475    /// let expected = Vector4::make(-9.0, -8.0, -7.0, -6.0);
476    /// assert_eq!(actual, expected);
477    /// ```
478    #[inline]
479    fn sub(self, _rhs: f32) -> Vector4 {
480        Vector4::make(self.x - _rhs, self.y - _rhs, self.z - _rhs, self.w - _rhs)
481    }
482}
483
484impl Sub<Vector4> for Vector4 {
485    type Output = Vector4;
486
487    /// Subtract two vectors
488    ///
489    /// # Examples
490    /// ```
491    /// use vex::Vector4;
492    /// 
493    /// let a = Vector4::make(1.0, 2.0, 3.0, 4.0);
494    /// let b = Vector4::make(5.0, 4.0, 3.0, 2.0);
495    /// let actual = a - b;
496    /// let expected = Vector4::make(-4.0, -2.0, 0.0, 2.0);
497    /// assert_eq!(actual, expected);
498    /// ```
499    #[inline]
500    fn sub(self, _rhs: Vector4) -> Vector4 {
501        Vector4::make(
502            self.x - _rhs.x,
503            self.y - _rhs.y,
504            self.z - _rhs.z,
505            self.w - _rhs.w,
506        )
507    }
508}
509
510impl SubAssign<f32> for Vector4 {
511    /// Decrement a vector by a scalar
512    ///
513    /// # Examples
514    /// ```
515    /// use vex::Vector4;
516    /// 
517    /// let mut actual = Vector4::make(1.0, 2.0, 3.0, 4.0);
518    /// actual -= 1.0;
519    /// let expected = Vector4::make(0.0, 1.0, 2.0, 3.0);
520    /// assert_eq!(actual, expected);
521    /// ```
522    #[inline]
523    fn sub_assign(&mut self, _rhs: f32) {
524        self.x -= _rhs;
525        self.y -= _rhs;
526        self.z -= _rhs;
527        self.w -= _rhs;
528    }
529}
530
531impl SubAssign<Vector4> for Vector4 {
532    /// Decrement a vector by another vector
533    ///
534    /// # Examples
535    /// ```
536    /// use vex::Vector4;
537    /// 
538    /// let mut actual = Vector4::make(1.0, 2.0, 3.0, 4.0);
539    /// actual -= Vector4::make(1.0, 2.0, 3.0, 4.0);
540    /// assert_eq!(actual, Vector4::new());
541    /// ```
542    #[inline]
543    fn sub_assign(&mut self, _rhs: Vector4) {
544        self.x -= _rhs.x;
545        self.y -= _rhs.y;
546        self.z -= _rhs.z;
547        self.w -= _rhs.w;
548    }
549}
550
551impl Mul<f32> for Vector4 {
552    type Output = Vector4;
553
554    /// Find the resulting vector by multiplying a scalar to a vector's components
555    ///
556    /// # Examples
557    /// ```
558    /// use vex::Vector4;
559    /// 
560    /// let actual = Vector4::make(1.0, 2.0, 3.0, 4.0) * 2.0;
561    /// let expected = Vector4::make(2.0, 4.0, 6.0, 8.0);
562    /// assert_eq!(actual, expected);
563    /// ```
564    #[inline]
565    fn mul(self, _rhs: f32) -> Vector4 {
566        Vector4::make(self.x * _rhs, self.y * _rhs, self.z * _rhs, self.w * _rhs)
567    }
568}
569
570impl Mul<Vector4> for Vector4 {
571    type Output = Vector4;
572
573    /// Multiply two vectors
574    ///
575    /// # Examples
576    /// ```
577    /// use vex::Vector4;
578    /// 
579    /// let a = Vector4::make(1.0, 2.0, 3.0, 4.0);
580    /// let b = Vector4::make(5.0, 6.0, 7.0, 8.0);
581    /// let actual = a * b;
582    /// let expected = Vector4::make(5.0, 12.0, 21.0, 32.0);
583    /// assert_eq!(actual, expected);
584    /// ```
585    #[inline]
586    fn mul(self, _rhs: Vector4) -> Vector4 {
587        Vector4::make(
588            self.x * _rhs.x,
589            self.y * _rhs.y,
590            self.z * _rhs.z,
591            self.w * _rhs.w,
592        )
593    }
594}
595
596impl MulAssign<f32> for Vector4 {
597    /// Multiply a vector by a scalar
598    ///
599    /// # Examples
600    /// ```
601    /// use vex::Vector4;
602    /// 
603    /// let mut actual = Vector4::make(1.0, 2.0, 3.0, 4.0);
604    /// actual *= 2.0;
605    /// let expected = Vector4::make(2.0, 4.0, 6.0, 8.0);
606    /// assert_eq!(actual, expected);
607    /// ```
608    #[inline]
609    fn mul_assign(&mut self, _rhs: f32) {
610        self.x *= _rhs;
611        self.y *= _rhs;
612        self.z *= _rhs;
613        self.w *= _rhs;
614    }
615}
616
617impl MulAssign<Vector4> for Vector4 {
618    /// Multiply a vector by another vector
619    ///
620    /// # Examples
621    /// ```
622    /// use vex::Vector4;
623    /// 
624    /// let mut actual = Vector4::make(1.0, 2.0, 3.0, 4.0);
625    /// actual *= Vector4::make(2.0, 3.0, 6.0, 8.0);
626    /// let expected = Vector4::make(2.0, 6.0, 18.0, 32.0);
627    /// assert_eq!(actual, expected);
628    /// ```
629    #[inline]
630    fn mul_assign(&mut self, _rhs: Vector4) {
631        self.x *= _rhs.x;
632        self.y *= _rhs.y;
633        self.z *= _rhs.z;
634        self.w *= _rhs.w;
635    }
636}
637
638impl Div<f32> for Vector4 {
639    type Output = Vector4;
640
641    /// Find the resulting vector by dividing a scalar to a vector's components
642    ///
643    /// # Examples
644    /// ```
645    /// use vex::Vector4;
646    /// 
647    /// let actual = Vector4::make(1.0, 2.0, 3.0, 4.0) / 2.0;
648    /// let expected = Vector4::make(0.5, 1.0, 1.5, 2.0);
649    /// assert_eq!(actual, expected);
650    /// ```
651    #[inline]
652    fn div(self, _rhs: f32) -> Vector4 {
653        Vector4::make(self.x / _rhs, self.y / _rhs, self.z / _rhs, self.w / _rhs)
654    }
655}
656
657impl Div<Vector4> for Vector4 {
658    type Output = Vector4;
659
660    /// Divide two vectors
661    ///
662    /// # Examples
663    /// ```
664    /// use vex::Vector4;
665    /// 
666    /// let a = Vector4::make(2.0, 4.0, 6.0, 8.0);
667    /// let b = Vector4::make(1.0, 4.0, 12.0, 32.0);
668    /// let actual = a / b;
669    /// let expected = Vector4::make(2.0, 1.0, 0.5, 0.25);
670    /// assert_eq!(actual, expected);
671    /// ```
672    #[inline]
673    fn div(self, _rhs: Vector4) -> Vector4 {
674        Vector4::make(
675            self.x / _rhs.x,
676            self.y / _rhs.y,
677            self.z / _rhs.z,
678            self.w / _rhs.w,
679        )
680    }
681}
682
683impl DivAssign<f32> for Vector4 {
684    /// Divide a vector by a scalar
685    ///
686    /// # Examples
687    /// ```
688    /// use vex::Vector4;
689    /// 
690    /// let mut actual = Vector4::make(1.0, 2.0, 3.0, 4.0);
691    /// actual /= 2.0;
692    /// let expected = Vector4::make(0.5, 1.0, 1.5, 2.0);
693    /// assert_eq!(actual, expected);
694    /// ```
695    #[inline]
696    fn div_assign(&mut self, _rhs: f32) {
697        self.x /= _rhs;
698        self.y /= _rhs;
699        self.z /= _rhs;
700        self.w /= _rhs;
701    }
702}
703
704impl DivAssign<Vector4> for Vector4 {
705    /// Divide a vector by another vector
706    ///
707    /// # Examples
708    /// ```
709    /// use vex::Vector4;
710    /// 
711    /// let mut actual = Vector4::make(2.0, 4.0, 6.0, 8.0);
712    /// actual /= Vector4::make(1.0, 4.0, 12.0, 32.0);
713    /// let expected = Vector4::make(2.0, 1.0, 0.5, 0.25);
714    /// assert_eq!(actual, expected);
715    /// ```
716    #[inline]
717    fn div_assign(&mut self, _rhs: Vector4) {
718        self.x /= _rhs.x;
719        self.y /= _rhs.y;
720        self.z /= _rhs.z;
721        self.w /= _rhs.w;
722    }
723}
724
725impl cmp::PartialEq for Vector4 {
726    /// Determines if two vectors' components are equivalent
727    ///
728    /// # Examples
729    /// ```
730    /// use vex::Vector4;
731    /// 
732    /// assert!(Vector4::new() == Vector4::new());
733    /// ```
734    #[inline]
735    fn eq(&self, _rhs: &Vector4) -> bool {
736        for i in 0..4 {
737            if self[i] != _rhs[i] {
738                return false;
739            }
740        }
741
742        true
743    }
744}
745
746impl Display for Vector4 {
747    #[inline]
748    fn fmt(&self, f: &mut Formatter) -> fmt::Result {
749        unsafe { write!(f, "<{}  {}  {}  {}>", self.x, self.y, self.z, self.w) }
750    }
751}