1use std::{fmt, ops};
2
3use super::{
4 coordinates::{Uv, Xyz, T},
5 Scalar,
6};
7
8#[derive(Clone, Copy, Eq, PartialEq, Hash, Ord, PartialOrd)]
13#[repr(C)]
14pub struct Vector<const D: usize> {
15 pub components: [Scalar; D],
17}
18
19impl<const D: usize> Vector<D> {
20 pub fn from_component(scalar: impl Into<Scalar>) -> Self {
22 Self {
23 components: [scalar.into(); D],
24 }
25 }
26
27 pub fn to_na(self) -> nalgebra::SVector<f64, D> {
29 self.components.map(Scalar::into_f64).into()
30 }
31
32 pub fn to_t(self) -> Vector<1> {
34 Vector {
35 components: [self.components[0]],
36 }
37 }
38
39 pub fn to_uv(self) -> Vector<2> {
47 let zero = Scalar::ZERO;
48
49 let components = match self.components.as_slice() {
50 [] => [zero, zero],
51 &[t] => [t, zero],
52 &[u, v, ..] => [u, v],
53 };
54
55 Vector { components }
56 }
57
58 pub fn to_xyz(self) -> Vector<3> {
66 let zero = Scalar::ZERO;
67
68 let components = match self.components.as_slice() {
69 [] => [zero, zero, zero],
70 &[t] => [t, zero, zero],
71 &[u, v] => [u, v, zero],
72 &[x, y, z, ..] => [x, y, z],
73 };
74
75 Vector { components }
76 }
77
78 pub fn magnitude(&self) -> Scalar {
80 self.to_na().magnitude().into()
81 }
82
83 pub fn normalize(&self) -> Self {
85 self.to_na().normalize().into()
86 }
87
88 pub fn dot(&self, other: &Self) -> Scalar {
90 self.to_na().dot(&other.to_na()).into()
91 }
92
93 pub fn scalar_projection_onto(&self, other: &Self) -> Scalar {
95 if other.magnitude() == Scalar::ZERO {
96 return Scalar::ZERO;
97 }
98
99 self.dot(&other.normalize())
100 }
101}
102
103impl Vector<1> {
104 pub fn unit_t() -> Self {
106 Self::from([1.])
107 }
108}
109
110impl Vector<2> {
111 pub fn unit_u() -> Self {
113 Self::from([1., 0.])
114 }
115
116 pub fn unit_v() -> Self {
118 Self::from([0., 1.])
119 }
120
121 pub fn cross2d(&self, other: &Self) -> Scalar {
123 (self.u * other.v) - (self.v * other.u)
124 }
125
126 pub fn is_between(&self, others: [impl Into<Self>; 2]) -> bool {
128 let [a, b] = others.map(Into::into);
129 a.cross2d(self) * b.cross2d(self) < Scalar::ZERO
130 }
131}
132
133impl Vector<3> {
134 pub fn unit_x() -> Self {
136 Self::from([1., 0., 0.])
137 }
138
139 pub fn unit_y() -> Self {
141 Self::from([0., 1., 0.])
142 }
143
144 pub fn unit_z() -> Self {
146 Self::from([0., 0., 1.])
147 }
148
149 pub fn cross(&self, other: &Self) -> Self {
151 self.to_na().cross(&other.to_na()).into()
152 }
153
154 pub fn xy(&self) -> Vector<2> {
156 Vector::from([self.x, self.y])
157 }
158}
159
160impl ops::Deref for Vector<1> {
161 type Target = T;
162
163 fn deref(&self) -> &Self::Target {
164 let ptr = self.components.as_ptr() as *const Self::Target;
165
166 unsafe { &*ptr }
169 }
170}
171
172impl ops::Deref for Vector<2> {
173 type Target = Uv;
174
175 fn deref(&self) -> &Self::Target {
176 let ptr = self.components.as_ptr() as *const Self::Target;
177
178 unsafe { &*ptr }
181 }
182}
183
184impl ops::Deref for Vector<3> {
185 type Target = Xyz;
186
187 fn deref(&self) -> &Self::Target {
188 let ptr = self.components.as_ptr() as *const Self::Target;
189
190 unsafe { &*ptr }
193 }
194}
195
196impl ops::DerefMut for Vector<1> {
197 fn deref_mut(&mut self) -> &mut Self::Target {
198 let ptr = self.components.as_mut_ptr() as *mut Self::Target;
199
200 unsafe { &mut *ptr }
203 }
204}
205
206impl ops::DerefMut for Vector<2> {
207 fn deref_mut(&mut self) -> &mut Self::Target {
208 let ptr = self.components.as_mut_ptr() as *mut Self::Target;
209
210 unsafe { &mut *ptr }
213 }
214}
215
216impl ops::DerefMut for Vector<3> {
217 fn deref_mut(&mut self) -> &mut Self::Target {
218 let ptr = self.components.as_mut_ptr() as *mut Self::Target;
219
220 unsafe { &mut *ptr }
223 }
224}
225
226impl<const D: usize> Default for Vector<D> {
227 fn default() -> Self {
228 let components = [Scalar::default(); D];
229 Self { components }
230 }
231}
232
233impl<S: Into<Scalar>, const D: usize> From<[S; D]> for Vector<D> {
234 fn from(components: [S; D]) -> Self {
235 Self {
236 components: components.map(Into::into),
237 }
238 }
239}
240
241impl<const D: usize> From<nalgebra::SVector<f64, D>> for Vector<D> {
242 fn from(vector: nalgebra::SVector<f64, D>) -> Self {
243 let components: [f64; D] = vector.into();
244 Vector::from(components)
245 }
246}
247
248impl<const D: usize> From<Vector<D>> for [f32; D] {
249 fn from(vector: Vector<D>) -> Self {
250 vector.components.map(|scalar| scalar.into_f32())
251 }
252}
253
254impl<const D: usize> From<Vector<D>> for [f64; D] {
255 fn from(vector: Vector<D>) -> Self {
256 vector.components.map(|scalar| scalar.into_f64())
257 }
258}
259
260impl<const D: usize> From<Vector<D>> for [Scalar; D] {
261 fn from(vector: Vector<D>) -> Self {
262 vector.components
263 }
264}
265
266impl<const D: usize> From<Vector<D>> for nalgebra::SVector<f64, D> {
267 fn from(vector: Vector<D>) -> Self {
268 vector.to_na()
269 }
270}
271
272impl<const D: usize> ops::Neg for Vector<D> {
273 type Output = Self;
274
275 fn neg(self) -> Self::Output {
276 self.to_na().neg().into()
277 }
278}
279
280impl<V, const D: usize> ops::Add<V> for Vector<D>
281where
282 V: Into<Self>,
283{
284 type Output = Self;
285
286 fn add(self, rhs: V) -> Self::Output {
287 self.to_na().add(rhs.into().to_na()).into()
288 }
289}
290
291impl<V, const D: usize> ops::Sub<V> for Vector<D>
292where
293 V: Into<Self>,
294{
295 type Output = Self;
296
297 fn sub(self, rhs: V) -> Self::Output {
298 self.to_na().sub(rhs.into().to_na()).into()
299 }
300}
301
302impl<S, const D: usize> ops::Mul<S> for Vector<D>
303where
304 S: Into<Scalar>,
305{
306 type Output = Self;
307
308 fn mul(self, rhs: S) -> Self::Output {
309 self.to_na().mul(rhs.into().into_f64()).into()
310 }
311}
312
313impl<S, const D: usize> ops::MulAssign<S> for Vector<D>
314where
315 S: Into<Scalar>,
316{
317 fn mul_assign(&mut self, rhs: S) {
318 *self = *self * rhs;
319 }
320}
321
322impl<S, const D: usize> ops::Div<S> for Vector<D>
323where
324 S: Into<Scalar>,
325{
326 type Output = Self;
327
328 fn div(self, rhs: S) -> Self::Output {
329 self.to_na().div(rhs.into().into_f64()).into()
330 }
331}
332
333impl<const D: usize> fmt::Debug for Vector<D> {
334 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
335 self.components.fmt(f)
336 }
337}
338
339impl<const D: usize> approx::AbsDiffEq for Vector<D> {
340 type Epsilon = <Scalar as approx::AbsDiffEq>::Epsilon;
341
342 fn default_epsilon() -> Self::Epsilon {
343 Scalar::default_epsilon()
344 }
345
346 fn abs_diff_eq(&self, other: &Self, epsilon: Self::Epsilon) -> bool {
347 self.components.abs_diff_eq(&other.components, epsilon)
348 }
349}
350
351#[cfg(test)]
352mod tests {
353 use crate::{Scalar, Vector};
354
355 #[test]
356 fn to_uv() {
357 let d0: [f64; 0] = [];
358 assert_eq!(Vector::from(d0).to_uv(), Vector::from([0., 0.]));
359 assert_eq!(Vector::from([1.]).to_uv(), Vector::from([1., 0.]));
360 assert_eq!(Vector::from([1., 2.]).to_uv(), Vector::from([1., 2.]));
361 assert_eq!(Vector::from([1., 2., 3.]).to_uv(), Vector::from([1., 2.]),);
362 }
363
364 #[test]
365 fn to_xyz() {
366 let d0: [f64; 0] = [];
367 assert_eq!(Vector::from(d0).to_xyz(), Vector::from([0., 0., 0.]));
368 assert_eq!(Vector::from([1.]).to_xyz(), Vector::from([1., 0., 0.]));
369 assert_eq!(Vector::from([1., 2.]).to_xyz(), Vector::from([1., 2., 0.]));
370 assert_eq!(
371 Vector::from([1., 2., 3.]).to_xyz(),
372 Vector::from([1., 2., 3.]),
373 );
374 }
375
376 #[test]
377 fn scalar_projection_onto() {
378 let v = Vector::from([1., 2., 3.]);
379
380 let x = Vector::unit_x() * 3.;
381 let y = Vector::unit_y() * 2.;
382 let z = Vector::unit_z() * 1.;
383
384 assert_eq!(v.scalar_projection_onto(&x), Scalar::from(1.));
385 assert_eq!(v.scalar_projection_onto(&y), Scalar::from(2.));
386 assert_eq!(v.scalar_projection_onto(&z), Scalar::from(3.));
387
388 assert_eq!(
390 Vector::unit_x()
391 .scalar_projection_onto(&Vector::from([0., 0., 0.])),
392 Scalar::ZERO
393 );
394 }
395
396 #[test]
397 fn is_between() {
398 let v = Vector::from([1., 1.]);
399
400 assert!(v.is_between([[1., 0.], [0., 1.]]));
401 assert!(!v.is_between([[1., 0.], [0., -1.]]));
402 assert!(!v.is_between([[-1., 0.], [0., 1.]]));
403 }
404}