cgl_rs/math/
vector.rs

1//! Vector math module. Includes vector structs and functions.
2
3
4/// A 2-dimensional vector with `x` and `y` components.
5#[derive(Debug, Copy, Clone, PartialEq)] #[repr(C)]
6pub struct Vector2 {
7    pub x: f32,
8    pub y: f32,
9}
10
11/// A 3-dimensional vector with `x`, `y` and `z` components.
12#[derive(Debug, Copy, Clone, PartialEq)] #[repr(C)]
13pub struct Vector3 {
14    pub x: f32,
15    pub y: f32,
16    pub z: f32,
17}
18
19/// A 4-dimensional vector with `x`, `y`, `z` and `w` components.
20#[derive(Debug, Copy, Clone, PartialEq)] #[repr(C)]
21pub struct Vector4 {
22    pub x: f32,
23    pub y: f32,
24    pub z: f32,
25    pub w: f32,
26}
27
28/// A 4-dimensional vector with `x`, `y`, `z` and `w` components, all of which are `i32`.
29#[derive(Debug, Copy, Clone, PartialEq)] #[repr(C)]
30pub struct IVector4 {
31    pub x: i32,
32    pub y: i32,
33    pub z: i32,
34    pub w: i32
35}
36
37/// Allows indexing into a `Vector2` by `usize` index.
38impl std::ops::Index<usize> for Vector2 {
39    type Output = f32;
40    
41    /// Returns a reference to the `f32` value at the given index.
42    ///
43    /// # Arguments
44    ///
45    /// * `index` - The index of the value to retrieve. Must be `0` or `1`.
46    ///
47    /// # Returns
48    ///
49    /// A reference to the `f32` value at the given index.
50    ///
51    /// # Panics
52    ///
53    /// Panics if the index is not `0` or `1`.
54    ///
55    /// # Examples
56    ///
57    /// ```
58    /// use cgl_rs::math::Vector2;
59    /// let vec = Vector2::new(1.0, 2.0);
60    /// assert_eq!(vec[0], 1.0);
61    /// assert_eq!(vec[1], 2.0);
62    /// ```
63    fn index(&self, index: usize) -> &f32 {
64        match index {
65            0 => &self.x,
66            1 => &self.y,
67            _ => panic!("Index out of bounds for Vector2"),
68        }
69        
70    }
71}
72
73/// Allows mutable indexing into a `Vector2` by `usize` index.
74impl std::ops::IndexMut<usize> for Vector2 {
75    
76    /// Returns a mutable reference to the `f32` value at the given index.
77    ///
78    /// # Arguments
79    ///
80    /// * `index` - The index of the value to retrieve. Must be `0` or `1`.
81    ///
82    /// # Returns
83    ///
84    /// A mutable reference to the `f32` value at the given index.
85    ///
86    /// # Panics
87    ///
88    /// Panics if the index is not `0` or `1`.
89    /// 
90    /// # Examples
91    /// 
92    /// ```
93    /// use cgl_rs::math::Vector2;
94    /// let mut vec = Vector2::new(1.0, 2.0);
95    /// vec[0] = 3.0;
96    /// assert_eq!(vec.x, 3.0);
97    /// ```
98    fn index_mut(&mut self, index: usize) -> &mut f32 {
99        match index {
100            0 => &mut self.x,
101            1 => &mut self.y,
102            _ => panic!("Index out of bounds for Vector2"),
103        }
104    }
105}
106
107impl std::fmt::Display for Vector2 {
108        
109        /// Formats the vector as a string.
110        /// 
111        /// # Arguments
112        /// 
113        /// * `f` - The formatter to use.
114        /// 
115        /// # Returns
116        /// 
117        /// A string representation of the vector.
118        /// 
119        /// # Examples
120        /// 
121        /// ```
122        /// use cgl_rs::math::Vector2;
123        /// let vec = Vector2::new(1.0, 2.0);
124        /// ```
125        fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
126            write!(f, "Vector2({}, {})", self.x, self.y)
127        }
128}
129
130crate::macros::impl_vector_binary_ops!(Vector2, 2);
131
132impl Vector2 {
133    
134    /// Creates a new `Vector2` with the given `x` and `y` components.
135    /// 
136    /// # Arguments
137    /// 
138    /// * `x` - The `x` component of the vector.
139    /// * `y` - The `y` component of the vector.
140    /// 
141    /// # Returns
142    /// 
143    /// A new `Vector2` with the given `x` and `y` components.
144    /// 
145    /// # Examples
146    /// 
147    /// ```
148    /// use cgl_rs::math::Vector2;
149    /// 
150    /// let vec = Vector2::new(1.0, 2.0);
151    /// ```
152    pub fn new(x: f32, y: f32) -> Vector2 {
153        Vector2 { x: x, y: y }
154    }
155    
156    /// Creates a new `Vector2` with `x` and `y` components set to `0.0`.
157    ///
158    /// # Returns
159    ///
160    /// A new `Vector2` with `x` and `y` components set to `0.0`.
161    ///
162    /// # Examples
163    ///
164    /// ```
165    /// use cgl_rs::math::Vector2;
166    ///
167    /// let vec = Vector2::zero();
168    /// ```
169    pub fn zero() -> Vector2 {
170        Vector2 { x: (0.0), y: (0.0) }
171    }
172    
173    /// Creates a new `Vector2` with `x` and `y` components set to `1.0`.
174    ///
175    /// # Returns
176    ///
177    /// A new `Vector2` with `x` and `y` components set to `1.0`.
178    ///
179    /// # Examples
180    ///
181    /// ```
182    /// use cgl_rs::math::Vector2;
183    ///
184    /// let vec = Vector2::one();
185    /// ```
186    pub fn one() -> Vector2 {
187        Vector2 { x: (1.0), y: (1.0) }
188    }
189
190
191    /// Calculates the dot product of this vector and another vector.
192    ///
193    /// # Arguments
194    ///
195    /// * `other` - The other vector to calculate the dot product with.
196    ///
197    /// # Returns
198    ///
199    /// The dot product of this vector and the other vector.
200    ///
201    /// # Examples
202    ///
203    /// ```
204    /// use cgl_rs::math::Vector2;
205    ///
206    /// let vec1 = Vector2::new(1.0, 2.0);
207    /// let vec2 = Vector2::new(3.0, 4.0);
208    /// let dot_product = vec1.dot(&vec2);
209    /// ```
210    pub fn dot(&self, other: &Vector2) -> f32 {
211        self.x * other.x + self.y * other.y
212    }
213
214    /// Calculates the cross product of this vector and another vector.
215    /// 
216    /// # Arguments
217    /// 
218    /// * `other` - The other vector to calculate the cross product with.
219    /// 
220    /// # Returns
221    /// 
222    /// The cross product of this vector and the other vector.
223    /// 
224    /// # Examples
225    /// 
226    /// ```
227    /// use cgl_rs::math::Vector2;
228    /// 
229    /// let vec1 = Vector2::new(1.0, 2.0);
230    /// let vec2 = Vector2::new(3.0, 4.0);
231    /// let cross_product = vec1.cross(&vec2);
232    /// ```
233    pub fn cross(&self, other: &Vector2) -> f32 {
234        self.x * other.y - self.y * other.x
235    }
236
237    /// Calculates the length of this vector.
238    ///
239    /// # Returns
240    ///
241    /// The length of this vector.
242    ///
243    /// # Examples
244    ///
245    /// ```
246    /// use cgl_rs::math::Vector2;
247    ///
248    /// let vec = Vector2::new(3.0, 4.0);
249    /// let length = vec.length();
250    /// ```
251    pub fn length(&self) -> f32 {
252        (self.x * self.x + self.y * self.y).sqrt()
253    }
254
255    /// Rotates this vector about the origin by the given angle (in radians).
256    ///
257    /// # Arguments
258    ///
259    /// * `angle` - The angle (in radians) to rotate this vector by.
260    ///
261    /// # Returns
262    ///
263    /// A new `Vector2` representing the result of rotating this vector about the origin by the given angle.
264    ///
265    /// # Examples
266    ///
267    /// ```
268    /// use cgl_rs::math::Vector2;
269    ///
270    /// let vec = Vector2::new(1.0, 0.0);
271    /// let rotated_vec = vec.rotate_about_origin(std::f32::consts::PI / 2.0);
272    /// ```
273    pub fn rotate_about_origin(&self, angle: f32) -> Vector2 {
274        let cos = angle.cos();
275        let sin = angle.sin();
276        Vector2::new(self.x * cos - self.y * sin, self.x * sin + self.y * cos)
277    }
278
279    /// Creates a new `Vector2` from the given angle (in radians).
280    ///
281    /// # Arguments
282    ///
283    /// * `angle` - The angle (in radians) to create the vector from.
284    ///
285    /// # Returns
286    ///
287    /// A new `Vector2` representing the given angle.
288    ///
289    /// # Examples
290    ///
291    /// ```
292    /// use cgl_rs::math::Vector2;
293    ///
294    /// let vec = Vector2::from_angle(std::f32::consts::PI / 4.0);
295    /// ```
296    pub fn from_angle(angle: f32) -> Vector2 {
297        Vector2::new(angle.cos(), angle.sin())
298    }
299
300    /// Calculates the angle (in radians) between this vector and the positive x-axis.
301    ///
302    /// # Returns
303    ///
304    /// The angle (in radians) between this vector and the positive x-axis.
305    ///
306    /// # Examples
307    ///
308    /// ```
309    /// use cgl_rs::math::Vector2;
310    ///
311    /// let vec = Vector2::new(1.0, 1.0);
312    /// let angle = vec.angle();
313    /// ```
314    pub fn angle(&self) -> f32 {
315        self.y.atan2(self.x)
316    }
317    
318    /// Calculates the angle (in radians) between this vector and another vector.
319    ///
320    /// # Arguments
321    ///
322    /// * `other` - The other vector to calculate the angle between.
323    ///
324    /// # Returns
325    ///
326    /// The angle (in radians) between this vector and the other vector.
327    ///
328    /// # Examples
329    ///
330    /// ```
331    /// use cgl_rs::math::Vector2;
332    ///
333    /// let vec1 = Vector2::new(1.0, 0.0);
334    /// let vec2 = Vector2::new(0.0, 1.0);
335    /// let angle = vec1.angle_between(&vec2);
336    /// ```
337    pub fn angle_between(&self, other: &Vector2) -> f32 {
338        let dot = self.dot(other);
339        let det = self.x * other.y - self.y * other.x;
340        det.atan2(dot)
341    }
342
343    /// Normalizes this vector in place.
344    ///
345    /// # Examples
346    ///
347    /// ```
348    /// use cgl_rs::math::Vector2;
349    ///
350    /// let mut vec = Vector2::new(3.0, 4.0);
351    /// vec.normalize();
352    /// ```
353    /// 
354    /// # See also
355    /// 
356    /// * [`normalized`](#method.normalized)
357    pub fn normalize(&mut self) {
358        let length = self.length();
359        self.x /= length;
360        self.y /= length;
361    }
362
363    /// Returns a new normalized `Vector2` representing this vector.
364    ///
365    /// # Returns
366    ///
367    /// A new `Vector2` representing this vector, normalized.
368    ///
369    /// # Examples
370    ///
371    /// ```
372    /// use cgl_rs::math::Vector2;
373    ///
374    /// let vec = Vector2::new(3.0, 4.0);
375    /// let normalized_vec = vec.normalized();
376    /// ```
377    /// 
378    /// # See also
379    /// 
380    /// * [`normalize`](#method.normalize)
381    pub fn normalized(&self) -> Vector2 {
382        let length = self.length();
383        Vector2::new(self.x / length, self.y / length)
384    }
385
386    /// Returns a new `Vector2` that is perpendicular to this vector.
387    ///
388    /// # Returns
389    ///
390    /// A new `Vector2` that is perpendicular to this vector.
391    ///
392    /// # Examples
393    ///
394    /// ```
395    /// use cgl_rs::math::Vector2;
396    ///
397    /// let vec = Vector2::new(1.0, 2.0);
398    /// let perp_vec = vec.perpendicular();
399    /// ```
400    ///
401    /// # See also
402    ///
403    /// * [`dot`](#method.dot)
404    /// * [`angle_between`](#method.angle_between)
405    pub fn perpendicular(&self) -> Vector2 {
406        Vector2::new(-self.y, self.x)
407    }
408
409    /// Returns the reflection of this vector off a surface with the given normal.
410    ///
411    /// # Arguments
412    ///
413    /// * `normal` - The normal of the surface being reflected off of.
414    ///
415    /// # Returns
416    ///
417    /// The reflection of this vector off the surface with the given normal.
418    ///
419    /// # Examples
420    ///
421    /// ```
422    /// use cgl_rs::math::Vector2;
423    ///
424    /// let vec = Vector2::new(1.0, 2.0);
425    /// let normal = Vector2::new(0.0, 1.0);
426    /// let reflected_vec = vec.reflect(&normal);
427    /// ```
428    pub fn reflect(&self, normal: &Vector2) -> Vector2 {
429        let dot = self.dot(normal);
430        Vector2::new(self.x - 2.0 * dot * normal.x, self.y - 2.0 * dot * normal.y)
431    }
432    
433}
434
435
436/// Allows indexing into a `Vector2`.
437impl std::ops::Index<usize> for Vector3 {
438    type Output = f32;
439
440    /// Returns a reference to the element at the given index.
441    ///
442    /// # Arguments
443    ///
444    /// * `index` - The index of the element to return.
445    ///
446    /// # Panics
447    ///
448    /// Panics if the index is out of bounds for a `Vector3`.
449    ///
450    /// # Examples
451    ///
452    /// ```
453    /// use cgl_rs::math::Vector3;
454    ///
455    /// let vec = Vector3::new(1.0, 2.0, 3.0);
456    /// assert_eq!(vec[0], 1.0);
457    /// assert_eq!(vec[1], 2.0);
458    /// assert_eq!(vec[2], 3.0);
459    /// ```
460    fn index(&self, index: usize) -> &f32 {
461        match index {
462            0 => &self.x,
463            1 => &self.y,
464            2 => &self.z,
465            _ => panic!("Index out of bounds for Vector3"),
466        }
467    }
468}
469
470/// Allows indexing into a `Vector3` mutably.
471impl std::ops::IndexMut<usize> for Vector3 {
472    /// Allows mutable indexing into a `Vector3`.
473    ///
474    /// # Arguments
475    ///
476    /// * `index` - The index of the element to return.
477    ///
478    /// # Panics
479    ///
480    /// Panics if the index is out of bounds for a `Vector3`.
481    ///
482    /// # Examples
483    ///
484    /// ```
485    /// use cgl_rs::math::Vector3;
486    ///
487    /// let mut vec = Vector3::new(1.0, 2.0, 3.0);
488    /// vec[0] = 4.0;
489    /// vec[1] = 5.0;
490    /// vec[2] = 6.0;
491    /// ```
492    fn index_mut(&mut self, index: usize) -> &mut f32 {
493        match index {
494            0 => &mut self.x,
495            1 => &mut self.y,
496            2 => &mut self.z,
497            _ => panic!("Index out of bounds for Vector3"),
498        }
499    }
500}
501
502crate::macros::impl_vector_binary_ops!(Vector3, 3);
503
504impl Vector3 {
505    /// Creates a new `Vector3` with the given `x`, `y`, and `z` components.
506    ///
507    /// # Arguments
508    ///
509    /// * `x` - The `x` component of the new vector.
510    /// * `y` - The `y` component of the new vector.
511    /// * `z` - The `z` component of the new vector.
512    ///
513    /// # Returns
514    ///
515    /// A new `Vector3` with the given `x`, `y`, and `z` components.
516    ///
517    /// # Examples
518    ///
519    /// ```
520    /// use cgl_rs::math::Vector3;
521    ///
522    /// let vec = Vector3::new(1.0, 2.0, 3.0);
523    /// ```
524    pub fn new(x: f32, y: f32, z: f32) -> Vector3 {
525        Vector3 { x, y, z }
526    }
527
528    /// Creates a new `Vector3` from a `Vector2` and a `z` component.
529    ///
530    /// # Arguments
531    ///
532    /// * `vec` - The `Vector2` to use for the `x` and `y` components of the new vector.
533    /// * `z` - The `z` component of the new vector.
534    ///
535    /// # Returns
536    ///
537    /// A new `Vector3` with the `x` and `y` components taken from `vec` and the `z` component set to `z`.
538    ///
539    /// # Examples
540    ///
541    /// ```
542    /// use cgl_rs::math::{Vector2, Vector3};
543    ///
544    /// let vec2 = Vector2::new(1.0, 2.0);
545    /// let vec3 = Vector3::from_vec2(vec2, 3.0);
546    /// assert_eq!(vec3.x, 1.0);
547    /// assert_eq!(vec3.y, 2.0);
548    /// assert_eq!(vec3.z, 3.0);
549    /// ```
550    pub fn from_vec2(vec: Vector2, z: f32) -> Vector3 {
551        Vector3::new(vec.x, vec.y, z)
552    }
553
554    /// Returns a new `Vector3` with all components set to zero.
555    ///
556    /// # Returns
557    ///
558    /// A new `Vector3` with all components set to zero.
559    ///
560    /// # Examples
561    ///
562    /// ```
563    /// use cgl_rs::math::Vector3;
564    ///
565    /// let vec = Vector3::zero();
566    /// assert_eq!(vec.x, 0.0);
567    /// assert_eq!(vec.y, 0.0);
568    /// assert_eq!(vec.z, 0.0);
569    /// ```
570    pub fn zero() -> Vector3 {
571        Vector3::new(0.0, 0.0, 0.0)
572    }
573
574    /// Returns a new `Vector3` with all components set to one.
575    ///
576    /// # Returns
577    ///
578    /// A new `Vector3` with all components set to one.
579    ///
580    /// # Examples
581    ///
582    /// ```
583    /// use cgl_rs::math::Vector3;
584    ///
585    /// let vec = Vector3::one();
586    /// assert_eq!(vec.x, 1.0);
587    /// assert_eq!(vec.y, 1.0);
588    /// assert_eq!(vec.z, 1.0);
589    /// ```
590    pub fn one() -> Vector3 {
591        Vector3::new(1.0, 1.0, 1.0)
592    }
593
594    /// Computes the dot product of two `Vector3`s.
595    ///
596    /// # Arguments
597    ///
598    /// * `other` - The other `Vector3` to compute the dot product with.
599    ///
600    /// # Returns
601    ///
602    /// The dot product of the two `Vector3`s.
603    ///
604    /// # Examples
605    ///
606    /// ```
607    /// use cgl_rs::math::Vector3;
608    ///
609    /// let vec1 = Vector3::new(1.0, 2.0, 3.0);
610    /// let vec2 = Vector3::new(4.0, 5.0, 6.0);
611    /// let dot_product = vec1.dot(vec2);
612    /// assert_eq!(dot_product, 32.0);
613    /// ```
614    pub fn dot(&self, other: Vector3) -> f32 {
615        self.x * other.x + self.y * other.y + self.z * other.z
616    }
617
618    /// Computes the cross product of two `Vector3`s.
619    ///
620    /// # Arguments
621    ///
622    /// * `other` - The other `Vector3` to compute the cross product with.
623    ///
624    /// # Returns
625    ///
626    /// The cross product of the two `Vector3`s.
627    ///
628    /// # Examples
629    ///
630    /// ```
631    /// use cgl_rs::math::Vector3;
632    ///
633    /// let vec1 = Vector3::new(1.0, 2.0, 3.0);
634    /// let vec2 = Vector3::new(4.0, 5.0, 6.0);
635    /// let cross_product = vec1.cross(vec2);
636    /// assert_eq!(cross_product.x, -3.0);
637    /// assert_eq!(cross_product.y, 6.0);
638    /// assert_eq!(cross_product.z, -3.0);
639    /// ```
640    pub fn cross(&self, other: Vector3) -> Vector3 {
641        Vector3::new(
642            self.y * other.z - self.z * other.y,
643            -(self.x * other.z - self.z * other.x),
644            self.x * other.y - self.y * other.x,
645        )
646    }
647
648    // Computes the length of the `Vector3`.
649    //
650    // # Returns
651    //
652    // The length of the `Vector3`.
653    //
654    // # Examples
655    //
656    // ```
657    // use cgl_rs::math::Vector3;
658    //
659    // let vec = Vector3::new(1.0, 2.0, 2.0);
660    // let length = vec.length();
661    // assert_eq!(length, 3.0);
662    // ```
663    pub fn length(&self) -> f32 {
664        (self.x * self.x + self.y * self.y + self.z * self.z).sqrt()
665    }
666
667    /// Normalizes the `Vector3` in place.
668    ///
669    /// # Examples
670    ///
671    /// ```
672    /// use cgl_rs::math::Vector3;
673    ///
674    /// let mut vec = Vector3::new(1.0, 2.0, 2.0);
675    /// vec.normalize();
676    /// assert_eq!(vec.length(), 1.0);
677    /// ```
678    pub fn normalize(&mut self) {
679        let length = self.length();
680        self.x /= length;
681        self.y /= length;
682        self.z /= length;
683    }
684
685    /// Returns a new `Vector3` that is the normalized version of this `Vector3`.
686    ///
687    /// # Returns
688    ///
689    /// A new `Vector3` that is the normalized version of this `Vector3`.
690    ///
691    /// # Examples
692    ///
693    /// ```
694    /// use cgl_rs::math::Vector3;
695    ///
696    /// let vec = Vector3::new(1.0, 2.0, 2.0);
697    /// let normalized_vec = vec.normalized();
698    /// assert_eq!(normalized_vec.length(), 1.0);
699    /// ```
700    pub fn normalized(&self) -> Vector3 {
701        let length = self.length();
702        Vector3::new(self.x / length, self.y / length, self.z / length)
703    }
704
705    /// Returns a new `Vector2` containing the `x` and `y` components of this `Vector3`.
706    ///
707    /// # Returns
708    ///
709    /// A new `Vector2` containing the `x` and `y` components of this `Vector3`.
710    ///
711    /// # Examples
712    ///
713    /// ```
714    /// use cgl_rs::math::{Vector2, Vector3};
715    ///
716    /// let vec = Vector3::new(1.0, 2.0, 3.0);
717    /// let vec2 = vec.xy();
718    /// assert_eq!(vec2.x, 1.0);
719    /// assert_eq!(vec2.y, 2.0);
720    /// ```
721    pub fn xy(&self) -> Vector2 {
722        Vector2::new(self.x, self.y)
723    }
724
725    /// Returns a new `Vector2` containing the `x` and `z` components of this `Vector3`.
726    ///
727    /// # Returns
728    ///
729    /// A new `Vector2` containing the `x` and `z` components of this `Vector3`.
730    ///
731    /// # Examples
732    ///
733    /// ```
734    /// use cgl_rs::math::{Vector2, Vector3};
735    ///
736    /// let vec = Vector3::new(1.0, 2.0, 3.0);
737    /// let vec2 = vec.xz();
738    /// assert_eq!(vec2.x, 1.0);
739    /// assert_eq!(vec2.y, 3.0);
740    /// ```
741    pub fn xz(&self) -> Vector2 {
742        Vector2::new(self.x, self.z)
743    }
744
745    /// Returns a new `Vector2` containing the `y` and `z` components of this `Vector3`.
746    ///
747    /// # Returns
748    ///
749    /// A new `Vector2` containing the `y` and `z` components of this `Vector3`.
750    ///
751    /// # Examples
752    ///
753    /// ```
754    /// use cgl_rs::math::{Vector2, Vector3};
755    ///
756    /// let vec = Vector3::new(1.0, 2.0, 3.0);
757    /// let vec2 = vec.yz();
758    /// assert_eq!(vec2.x, 2.0);
759    /// assert_eq!(vec2.y, 3.0);
760    /// ```
761    pub fn yz(&self) -> Vector2 {
762        Vector2::new(self.y, self.z)
763    }
764
765    /// Returns the angle between this `Vector3` and another `Vector3`.
766    ///
767    /// # Arguments
768    ///
769    /// * `other` - The other `Vector3` to calculate the angle with.
770    ///
771    /// # Returns
772    ///
773    /// The angle between this `Vector3` and `other` in radians.
774    ///
775    /// # Examples
776    ///
777    /// ```
778    /// use cgl_rs::math::Vector3;
779    ///
780    /// let vec1 = Vector3::new(1.0, 0.0, 0.0);
781    /// let vec2 = Vector3::new(0.0, 1.0, 0.0);
782    /// let angle = vec1.angle_between(vec2);
783    /// assert_eq!(angle, std::f32::consts::FRAC_PI_2);
784    /// ```
785    pub fn angle_between(&self, other: Vector3) -> f32 {
786        let dot = self.dot(other);
787        let length = self.length() * other.length();
788        dot.acos() / length
789    }
790
791    /// Calculates the reflection of this `Vector3` off a surface with the given `normal`.
792    ///
793    /// # Arguments
794    ///
795    /// * `normal` - The normal of the surface to reflect off of.
796    ///
797    /// # Returns
798    ///
799    /// The reflection of this `Vector3` off the surface with the given `normal`.
800    ///
801    /// # Examples
802    ///
803    /// ```
804    /// use cgl_rs::math::Vector3;
805    ///
806    /// let vec = Vector3::new(1.0, 1.0, 0.0);
807    /// let normal = Vector3::new(0.0, 1.0, 0.0);
808    /// let reflected = vec.reflect(normal);
809    /// assert_eq!(reflected, Vector3::new(1.0, -1.0, 0.0));
810    /// ```
811    pub fn reflect(&self, normal: Vector3) -> Vector3 {
812        *self - normal * 2.0 * self.dot(normal)
813    }
814
815    /// Rotates this `Vector3` about the given `axis` by the given `angle` in radians.
816    ///
817    /// # Arguments
818    ///
819    /// * `axis` - The axis to rotate about.
820    /// * `angle` - The angle to rotate by in radians.
821    ///
822    /// # Returns
823    ///
824    /// The rotated `Vector3`.
825    ///
826    /// # Examples
827    ///
828    /// ```
829    /// use cgl_rs::math::Vector3;
830    ///
831    /// let vec = Vector3::new(1.0, 0.0, 0.0);
832    /// let axis = Vector3::new(0.0, 0.0, 1.0);
833    /// let angle = std::f32::consts::FRAC_PI_2;
834    /// let rotated = vec.rotate_about_axis(axis, angle);
835    /// assert_eq!(rotated, Vector3::new(0.0, 1.0, 0.0));
836    /// ```
837    pub fn rotate_about_axis(&self, axis: Vector3, angle: f32) -> Vector3 {
838        let cos = angle.cos();
839        let sin = angle.sin();
840        let one_minus_cos = 1.0 - cos;
841
842        let mut x = self.x * (cos + axis.x * axis.x * one_minus_cos)
843            + self.y * (axis.x * axis.y * one_minus_cos - axis.z * sin)
844            + self.z * (axis.x * axis.z * one_minus_cos + axis.y * sin);
845        let mut y = self.x * (axis.y * axis.x * one_minus_cos + axis.z * sin)
846            + self.y * (cos + axis.y * axis.y * one_minus_cos)
847            + self.z * (axis.y * axis.z * one_minus_cos - axis.x * sin);
848        let mut z = self.x * (axis.z * axis.x * one_minus_cos - axis.y * sin)
849            + self.y * (axis.z * axis.y * one_minus_cos + axis.x * sin)
850            + self.z * (cos + axis.z * axis.z * one_minus_cos);
851
852        if x.abs() < 0.000001 {
853            x = 0.0;
854        }
855        if y.abs() < 0.000001 {
856            y = 0.0;
857        }
858        if z.abs() < 0.000001 {
859            z = 0.0;
860        }
861
862        Vector3::new(x, y, z)
863    }
864
865}
866
867
868impl std::ops::Index<usize> for Vector4 {
869    type Output = f32;
870
871    // Returns a reference to the element at the given `index` of this `Vector4`.
872        ///
873        /// # Arguments
874        ///
875        /// * `index` - The index of the element to retrieve.
876        ///
877        /// # Panics
878        ///
879        /// Panics if `index` is greater than or equal to 4.
880        ///
881        /// # Examples
882        ///
883        /// ```
884        /// use cgl_rs::math::Vector4;
885        ///
886        /// let vec = Vector4::new(1.0, 2.0, 3.0, 4.0);
887        /// assert_eq!(vec[0], 1.0);
888        /// assert_eq!(vec[1], 2.0);
889        /// assert_eq!(vec[2], 3.0);
890        /// assert_eq!(vec[3], 4.0);
891        /// ```
892        fn index(&self, index: usize) -> &Self::Output {
893            match index {
894                0 => &self.x,
895                1 => &self.y,
896                2 => &self.z,
897                3 => &self.w,
898                _ => panic!("Index out of bounds for Vector4"),
899            }
900        }
901}
902
903impl std::ops::IndexMut<usize> for Vector4 {
904    /// Returns a mutable reference to the element at the given `index` of this `Vector4`.
905    ///
906    /// # Arguments
907    ///
908    /// * `index` - The index of the element to retrieve.
909    ///
910    /// # Panics
911    ///
912    /// Panics if `index` is greater than or equal to 4.
913    ///
914    /// # Examples
915    ///
916    /// ```
917    /// use cgl_rs::math::Vector4;
918    ///
919    /// let mut vec = Vector4::new(1.0, 2.0, 3.0, 4.0);
920    /// vec[0] = 5.0;
921    /// assert_eq!(vec[0], 5.0);
922    /// ```
923    fn index_mut(&mut self, index: usize) -> &mut Self::Output {
924        match index {
925            0 => &mut self.x,
926            1 => &mut self.y,
927            2 => &mut self.z,
928            3 => &mut self.w,
929            _ => panic!("Index out of bounds for Vector4"),
930        }
931    }
932}
933
934crate::macros::impl_vector_binary_ops!(Vector4, 4);
935
936impl Vector4 {
937
938    /// Creates a new `Vector4` with the given `x`, `y`, `z`, and `w` components.
939    ///
940    /// # Arguments
941    ///
942    /// * `x` - The `x` component of the new `Vector4`.
943    /// * `y` - The `y` component of the new `Vector4`.
944    /// * `z` - The `z` component of the new `Vector4`.
945    /// * `w` - The `w` component of the new `Vector4`.
946    ///
947    /// # Examples
948    ///
949    /// ```
950    /// use cgl_rs::math::Vector4;
951    ///
952    /// let vec = Vector4::new(1.0, 2.0, 3.0, 4.0);
953    /// assert_eq!(vec.x, 1.0);
954    /// assert_eq!(vec.y, 2.0);
955    /// assert_eq!(vec.z, 3.0);
956    /// assert_eq!(vec.w, 4.0);
957    /// ```
958    pub fn new(x: f32, y: f32, z: f32, w: f32) -> Vector4 {
959        Vector4 { x, y, z, w }
960    }
961
962
963    /// Creates a new `Vector4` from a `Vector3` and a `w` component.
964    ///
965    /// # Arguments
966    ///
967    /// * `vec` - The `Vector3` to use as the `x`, `y`, and `z` components of the new `Vector4`.
968    /// * `w` - The `w` component of the new `Vector4`.
969    ///
970    /// # Examples
971    ///
972    /// ```
973    /// use cgl_rs::math::{Vector3, Vector4};
974    ///
975    /// let vec3 = Vector3::new(1.0, 2.0, 3.0);
976    /// let vec4 = Vector4::from_vec3(vec3, 4.0);
977    /// assert_eq!(vec4.x, 1.0);
978    /// assert_eq!(vec4.y, 2.0);
979    /// assert_eq!(vec4.z, 3.0);
980    /// assert_eq!(vec4.w, 4.0);
981    /// ```
982    pub fn from_vec3(vec: Vector3, w: f32) -> Vector4 {
983        Vector4::new(vec.x, vec.y, vec.z, w)
984    }
985
986    /// Creates a new `Vector4` from a `Vector2`, `z`, and `w` components.
987    ///
988    /// # Arguments
989    ///
990    /// * `vec` - The `Vector2` to use as the `x` and `y` components of the new `Vector4`.
991    /// * `z` - The `z` component of the new `Vector4`.
992    /// * `w` - The `w` component of the new `Vector4`.
993    ///
994    /// # Examples
995    ///
996    /// ```
997    /// use cgl_rs::math::{Vector2, Vector4};
998    ///
999    /// let vec2 = Vector2::new(1.0, 2.0);
1000    /// let vec4 = Vector4::from_vec2(vec2, 3.0, 4.0);
1001    /// assert_eq!(vec4.x, 1.0);
1002    /// assert_eq!(vec4.y, 2.0);
1003    /// assert_eq!(vec4.z, 3.0);
1004    /// assert_eq!(vec4.w, 4.0);
1005    /// ```
1006    pub fn from_vec2(vec: Vector2, z: f32, w: f32) -> Vector4 {
1007        Vector4::new(vec.x, vec.y, z, w)
1008    }
1009
1010
1011    /// Returns a new `Vector4` with all components set to `0.0`.
1012    ///
1013    /// # Examples
1014    ///
1015    /// ```
1016    /// use cgl_rs::math::Vector4;
1017    ///
1018    /// let vec = Vector4::zero();
1019    /// assert_eq!(vec.x, 0.0);
1020    /// assert_eq!(vec.y, 0.0);
1021    /// assert_eq!(vec.z, 0.0);
1022    /// assert_eq!(vec.w, 0.0);
1023    /// ```
1024    pub fn zero() -> Vector4 {
1025        Vector4::new(0.0, 0.0, 0.0, 0.0)
1026    }
1027
1028    /// Returns a new `Vector4` with all components set to `1.0`.
1029    ///
1030    /// # Examples
1031    ///
1032    /// ```
1033    /// use cgl_rs::math::Vector4;
1034    ///
1035    /// let vec = Vector4::one();
1036    /// assert_eq!(vec.x, 1.0);
1037    /// assert_eq!(vec.y, 1.0);
1038    /// assert_eq!(vec.z, 1.0);
1039    /// assert_eq!(vec.w, 1.0);
1040    /// ```
1041    pub fn one() -> Vector4 {
1042        Vector4::new(1.0, 1.0, 1.0, 1.0)
1043    }
1044
1045
1046    /// Extracts the `x`, `y`, and `z` components of the `Vector4` as a new `Vector3`.
1047    /// 
1048    /// # Examples
1049    ///
1050    /// ```
1051    /// use cgl_rs::math::{Vector3, Vector4};
1052    ///
1053    /// let vec4 = Vector4::new(1.0, 2.0, 3.0, 4.0);
1054    /// let vec3 = vec4.xyz();
1055    /// assert_eq!(vec3.x, 1.0);
1056    /// assert_eq!(vec3.y, 2.0);
1057    /// assert_eq!(vec3.z, 3.0);
1058    /// ```
1059    pub fn xyz(&self) -> Vector3 {
1060        Vector3::new(self.x, self.y, self.z)
1061    }
1062
1063
1064
1065}
1066
1067
1068impl std::ops::Index<usize> for IVector4 {
1069    type Output = i32;
1070
1071    // Returns a reference to the element at the given `index` of this `Vector4`.
1072        ///
1073        /// # Arguments
1074        ///
1075        /// * `index` - The index of the element to retrieve.
1076        ///
1077        /// # Panics
1078        ///
1079        /// Panics if `index` is greater than or equal to 4.
1080        ///
1081        /// # Examples
1082        ///
1083        /// ```
1084        /// use cgl_rs::math::IVector4;
1085        ///
1086        /// let vec = IVector4::new(1, 2, 3, 4);
1087        /// assert_eq!(vec[0], 1);
1088        /// assert_eq!(vec[1], 2);
1089        /// assert_eq!(vec[2], 3);
1090        /// assert_eq!(vec[3], 4);
1091        /// ```
1092        fn index(&self, index: usize) -> &Self::Output {
1093            match index {
1094                0 => &self.x,
1095                1 => &self.y,
1096                2 => &self.z,
1097                3 => &self.w,
1098                _ => panic!("Index out of bounds for IVector4"),
1099            }
1100        }
1101}
1102
1103impl std::ops::IndexMut<usize> for IVector4 {
1104    /// Returns a mutable reference to the element at the given `index` of this `Vector4`.
1105    ///
1106    /// # Arguments
1107    ///
1108    /// * `index` - The index of the element to retrieve.
1109    ///
1110    /// # Panics
1111    ///
1112    /// Panics if `index` is greater than or equal to 4.
1113    ///
1114    /// # Examples
1115    ///
1116    /// ```
1117    /// use cgl_rs::math::IVector4;
1118    ///
1119    /// let mut vec = IVector4::new(1, 2, 3, 4);
1120    /// vec[0] = 5;
1121    /// assert_eq!(vec[0], 5);
1122    /// ```
1123    fn index_mut(&mut self, index: usize) -> &mut Self::Output {
1124        match index {
1125            0 => &mut self.x,
1126            1 => &mut self.y,
1127            2 => &mut self.z,
1128            3 => &mut self.w,
1129            _ => panic!("Index out of bounds for IVector4"),
1130        }
1131    }
1132}
1133
1134
1135impl IVector4 {
1136    /// Creates a new `IVector4` with the given `x`, `y`, `z`, and `w` components.
1137    ///
1138    /// # Arguments
1139    ///
1140    /// * `x` - The `x` component of the vector.
1141    /// * `y` - The `y` component of the vector.
1142    /// * `z` - The `z` component of the vector.
1143    /// * `w` - The `w` component of the vector.
1144    ///
1145    /// # Examples
1146    ///
1147    /// ```
1148    /// use cgl_rs::math::IVector4;
1149    ///
1150    /// let vec = IVector4::new(1, 2, 3, 4);
1151    /// assert_eq!(vec.x, 1);
1152    /// assert_eq!(vec.y, 2);
1153    /// assert_eq!(vec.z, 3);
1154    /// assert_eq!(vec.w, 4);
1155    /// ```
1156    pub fn new(x: i32, y: i32, z: i32, w: i32) -> IVector4 {
1157        IVector4 { x, y, z, w }
1158    }
1159
1160    /// Returns a new `IVector4` with all components set to 0.
1161    ///
1162    /// # Examples
1163    ///
1164    /// ```
1165    /// use cgl_rs::math::IVector4;
1166    ///
1167    /// let vec = IVector4::zero();
1168    /// assert_eq!(vec.x, 0);
1169    /// assert_eq!(vec.y, 0);
1170    /// assert_eq!(vec.z, 0);
1171    /// assert_eq!(vec.w, 0);
1172    /// ```
1173    pub fn zero() -> IVector4 {
1174        IVector4::new(0, 0, 0, 0)
1175    }
1176}