Skip to main content

ezcgmath/
vector.rs

1use crate::Scalar;
2use crate::matrix::{Matrix3x3, Matrix4x4};
3use crate::quaternion::Quaternion;
4
5/// A 2-dimensional vector
6#[repr(C)]
7#[derive(Debug, Default, PartialEq, Copy, Clone)]
8pub struct Vector2 {
9    pub x: Scalar,
10    pub y: Scalar,
11}
12
13impl Vector2 {
14    /// Creates a new instance of a Vector4 with values (x, y).
15    pub const fn new(x: Scalar, y: Scalar) -> Self {
16        Vector2 { x, y }
17    }
18
19    /// Returns a vector of (1.0, 0.0, 0.0).
20    pub const fn unit_x() -> Self {
21        Vector2 { x: 1.0, y: 0.0 }
22    }
23
24    /// Returns a vector of (0.0, 1.0).
25    pub const fn unit_y() -> Self {
26        Vector2 { x: 0.0, y: 1.0 }
27    }
28
29    /// Returns the dot product of the vector with the vector 'rhs'.
30    pub fn dot(&self, rhs: &Vector2) -> Scalar {
31        self.x * rhs.x + self.y * rhs.y
32    }
33
34    /// The length of the vector.
35    pub fn length(&mut self) -> Scalar {
36        (self.x + self.y).sqrt()
37    }
38
39    /// Normalizes the vector to a length of one.
40    pub fn normalize(&mut self) {
41        let len = self.length();
42        self.x /= len;
43        self.y /= len;
44    }
45}
46impl_add_self!(Vector2, x, y);
47impl_sub_self!(Vector2, x, y);
48impl_mul_scalar!(Vector2, x, y);
49impl_div_scalar!(Vector2, x, y);
50impl_negate_self!(Vector2, x, y);
51impl_approx!(Vector2, x, y);
52
53/// A 3-dimensional vector
54#[repr(C)]
55#[derive(Debug, Default, PartialEq, Copy, Clone)]
56pub struct Vector3 {
57    pub x: Scalar,
58    pub y: Scalar,
59    pub z: Scalar,
60}
61
62impl Vector3 {
63    /// Creates a new instance of a Vector3 with values (x, y, z).
64    pub const fn new(x: Scalar, y: Scalar, z: Scalar) -> Self {
65        Vector3 { x, y, z }
66    }
67
68    /// Returns a vector of (1.0, 0.0, 0.0).
69    pub const fn unit_x() -> Self {
70        Vector3 {
71            x: 1.0,
72            y: 0.0,
73            z: 0.0,
74        }
75    }
76
77    /// Returns a vector of (0.0, 1.0, 0.0).
78    pub const fn unit_y() -> Self {
79        Vector3 {
80            x: 0.0,
81            y: 1.0,
82            z: 0.0,
83        }
84    }
85
86    /// Returns a vector of (0.0, 0.0, 1.0).
87    pub const fn unit_z() -> Self {
88        Vector3 {
89            x: 0.0,
90            y: 0.0,
91            z: 1.0,
92        }
93    }
94
95    /// Returns the dot product of the vector with the vector 'rhs'.
96    pub fn dot(&self, rhs: &Vector3) -> Scalar {
97        self.x * rhs.x + self.y * rhs.y + self.z * rhs.z
98    }
99
100    /// Returns the cross product of the vector with the vector 'rhs'.
101    pub fn cross(&self, rhs: &Vector3) -> Vector3 {
102        let mut result = Vector3::default();
103        result.x = self.y * rhs.z - self.z * rhs.y;
104        result.y = self.z * rhs.x - self.x * rhs.z;
105        result.z = self.x * rhs.y - self.y * rhs.x;
106        result
107    }
108
109    /// The length of the vector.
110    pub fn length(&mut self) -> Scalar {
111        (self.x.powf(2.0) + self.y.powf(2.0) + self.z.powf(2.0)).sqrt()
112    }
113
114    /// Normalizes the vector to a length of one.
115    pub fn normalize(&mut self) {
116        let len = self.length();
117        self.x /= len;
118        self.y /= len;
119        self.z /= len;
120    }
121}
122impl_add_self!(Vector3, x, y, z);
123impl_sub_self!(Vector3, x, y, z);
124impl_mul_scalar!(Vector3, x, y, z);
125impl_div_scalar!(Vector3, x, y, z);
126impl_negate_self!(Vector3, x, y, z);
127impl_approx!(Vector3, x, y, z);
128
129impl std::ops::Mul<Matrix3x3> for Vector3 {
130    type Output = Vector3;
131
132    fn mul(self, rhs: Matrix3x3) -> Vector3 {
133        Vector3 {
134            x: self.x * rhs.c00 + self.y * rhs.c01 + self.z * rhs.c02,
135            y: self.x * rhs.c10 + self.y * rhs.c11 + self.z * rhs.c12,
136            z: self.x * rhs.c20 + self.y * rhs.c21 + self.z * rhs.c22,
137        }
138    }
139}
140
141impl std::ops::MulAssign<Matrix3x3> for Vector3 {
142    fn mul_assign(&mut self, rhs: Matrix3x3) {
143        let x = self.x * rhs.c00 + self.y * rhs.c01 + self.z * rhs.c02;
144        let y = self.x * rhs.c10 + self.y * rhs.c11 + self.z * rhs.c12;
145        let z = self.x * rhs.c20 + self.y * rhs.c21 + self.z * rhs.c22;
146        self.x = x;
147        self.y = y;
148        self.z = z;
149    }
150}
151
152impl std::ops::Mul<Matrix4x4> for Vector3 {
153    type Output = Vector3;
154
155    fn mul(self, rhs: Matrix4x4) -> Vector3 {
156        (Vector4::from(self) * rhs).into()
157    }
158}
159
160impl std::ops::MulAssign<Matrix4x4> for Vector3 {
161    fn mul_assign(&mut self, rhs: Matrix4x4) {
162        let result: Vector3 = (Vector4::from(*self) * rhs).into();
163        self.x = result.x;
164        self.y = result.y;
165        self.z = result.z;
166    }
167}
168
169impl std::ops::Mul<Quaternion> for Vector3 {
170    type Output = Vector3;
171
172    fn mul(self, rhs: Quaternion) -> Vector3 {
173        (Vector4::from(self) * Matrix4x4::from(rhs)).into()
174    }
175}
176
177impl std::ops::MulAssign<Quaternion> for Vector3 {
178    fn mul_assign(&mut self, rhs: Quaternion) {
179        let result: Vector3 = (Vector4::from(*self) * Matrix4x4::from(rhs)).into();
180        self.x = result.x;
181        self.y = result.y;
182        self.z = result.z;
183    }
184}
185
186impl From<Vector4> for Vector3 {
187    fn from(vec4: Vector4) -> Self {
188        Vector3 {
189            x: vec4.x / vec4.w,
190            y: vec4.y / vec4.w,
191            z: vec4.z / vec4.w,
192        }
193    }
194}
195
196/// A 4-dimensional vector
197#[repr(C)]
198#[derive(Debug, Default, PartialEq, Copy, Clone)]
199pub struct Vector4 {
200    pub x: Scalar,
201    pub y: Scalar,
202    pub z: Scalar,
203    pub w: Scalar,
204}
205
206impl Vector4 {
207    /// Creates a new instance of a Vector4 with values (x, y, z, w).
208    pub const fn new(x: Scalar, y: Scalar, z: Scalar, w: Scalar) -> Self {
209        Vector4 { x, y, z, w }
210    }
211
212    /// Returns the dot product of the vector with the vector 'rhs'.
213    pub fn dot(&self, rhs: &Vector4) -> Scalar {
214        self.x * rhs.x + self.y * rhs.y + self.z * rhs.z + self.w * rhs.w
215    }
216}
217impl_add_self!(Vector4, x, y, z, w);
218impl_sub_self!(Vector4, x, y, z, w);
219impl_mul_scalar!(Vector4, x, y, z, w);
220impl_div_scalar!(Vector4, x, y, z, w);
221impl_negate_self!(Vector4, x, y, z, w);
222impl_approx!(Vector4, x, y, z, w);
223
224impl std::ops::Mul<Matrix4x4> for Vector4 {
225    type Output = Vector4;
226
227    fn mul(self, rhs: Matrix4x4) -> Vector4 {
228        Vector4 {
229            x: self.x * rhs.c00 + self.y * rhs.c01 + self.z * rhs.c02 + self.w * rhs.c03,
230            y: self.x * rhs.c10 + self.y * rhs.c11 + self.z * rhs.c12 + self.w * rhs.c13,
231            z: self.x * rhs.c20 + self.y * rhs.c21 + self.z * rhs.c22 + self.w * rhs.c23,
232            w: self.x * rhs.c30 + self.y * rhs.c31 + self.z * rhs.c32 + self.w * rhs.c33,
233        }
234    }
235}
236
237impl std::ops::MulAssign<Matrix4x4> for Vector4 {
238    fn mul_assign(&mut self, rhs: Matrix4x4) {
239        let x = self.x * rhs.c00 + self.y * rhs.c01 + self.z * rhs.c02 + self.w * rhs.c03;
240        let y = self.x * rhs.c10 + self.y * rhs.c11 + self.z * rhs.c12 + self.w * rhs.c13;
241        let z = self.x * rhs.c20 + self.y * rhs.c21 + self.z * rhs.c22 + self.w * rhs.c23;
242        let w = self.x * rhs.c30 + self.y * rhs.c31 + self.z * rhs.c32 + self.w * rhs.c33;
243        self.x = x;
244        self.y = y;
245        self.z = z;
246        self.w = w;
247    }
248}
249
250impl From<Vector3> for Vector4 {
251    fn from(vec3: Vector3) -> Self {
252        Vector4 {
253            x: vec3.x,
254            y: vec3.y,
255            z: vec3.z,
256            w: 1.0,
257        }
258    }
259}