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}