j_webgl/algebra/
vector3.rs

1use std::ops::{Add, Mul};
2
3/// A vector in 3D space with dx, dy, dz components
4#[derive(Debug, Clone, Copy, PartialEq)]
5pub struct Vector3 {
6    dx: f32,
7    dy: f32,
8    dz: f32,
9}
10
11impl Vector3 {
12    /// Creates a new Vector3 with the given dx, dy, dz components
13    pub fn new(dx: f32, dy: f32, dz: f32) -> Self {
14        Vector3 { dx, dy, dz }
15    }
16
17    /// Returns a zero vector (dx=0, dy=0, dz=0)
18    pub fn zero() -> Self {
19        Vector3 { dx: 0.0, dy: 0.0, dz: 0.0 }
20    }
21
22    /// Returns a unit vector along the x-axis (dx=1, dy=0, dz=0)
23    pub fn x() -> Self {
24        Vector3 { dx: 1.0, dy: 0.0, dz: 0.0 }
25    }
26
27    /// Returns a unit vector along the y-axis (dx=0, dy=1, dz=0)
28    pub fn y() -> Self {
29        Vector3 { dx: 0.0, dy: 1.0, dz: 0.0 }
30    }
31
32    /// Returns a unit vector along the z-axis (dx=0, dy=0, dz=1)
33    pub fn z() -> Self {
34        Vector3 { dx: 0.0, dy: 0.0, dz: 1.0 }
35    }
36
37    /// Returns the dx component
38    pub fn dx(&self) -> f32 {
39        self.dx
40    }
41    
42    /// Returns the dy component
43    pub fn dy(&self) -> f32 {
44        self.dy
45    }
46    
47    /// Returns the dz component
48    pub fn dz(&self) -> f32 {
49        self.dz
50    }
51
52    /// Returns the norm (magnitude) of the vector
53    fn norm(&self) -> f32 {
54        (self.dx * self.dx + self.dy * self.dy + self.dz * self.dz).sqrt()
55    }
56
57    /// Returns a new normalized vector (unit vector with the same direction)
58    /// If the vector has zero length, returns a zero vector
59    pub fn normalize(&self) -> Self {
60        let n = self.norm();
61        if n > 0.0 {
62            Vector3 {
63                dx: self.dx / n,
64                dy: self.dy / n,
65                dz: self.dz / n,
66            }
67        } else {
68            Vector3::zero()
69        }
70    }
71
72    /// Computes the dot product of two vectors
73    pub fn dot(&self, other: &Vector3) -> f32 {
74        self.dx * other.dx + self.dy * other.dy + self.dz * other.dz
75    }
76
77    /// Computes the cross product of two vectors
78    pub fn cross(&self, other: &Vector3) -> Self {
79        Vector3 {
80            dx: self.dy * other.dz - self.dz * other.dy,
81            dy: self.dz * other.dx - self.dx * other.dz,
82            dz: self.dx * other.dy - self.dy * other.dx,
83        }
84    }
85}
86
87// Implementation for v1 = v2 + v3
88impl Add for &Vector3 {
89    type Output = Vector3;
90
91    fn add(self, other: Self) -> Vector3 {
92        Vector3 {
93            dx: self.dx + other.dx,
94            dy: self.dy + other.dy,
95            dz: self.dz + other.dz,
96        }
97    }
98}
99
100// Implementation for v1 = a * v2 (scalar multiplication from the left)
101impl Mul<&Vector3> for f32 {
102    type Output = Vector3;
103
104    fn mul(self, vector: &Vector3) -> Vector3 {
105        Vector3 {
106            dx: self * vector.dx,
107            dy: self * vector.dy,
108            dz: self * vector.dz,
109        }
110    }
111}
112
113// Implementation for v1 = v2 * a (scalar multiplication from the right)
114impl Mul<f32> for &Vector3 {
115    type Output = Vector3;
116
117    fn mul(self, scalar: f32) -> Vector3 {
118        Vector3 {
119            dx: self.dx * scalar,
120            dy: self.dy * scalar,
121            dz: self.dz * scalar,
122        }
123    }
124}