Skip to main content

stormath/spatial_vector/
mod.rs

1// Copyright (C) 2024, NTNU
2// Author: Jarle Vinje Kramer <jarlekramer@gmail.com; jarle.a.kramer@ntnu.no>
3// License: GPL v3.0 (see separate file LICENSE or https://www.gnu.org/licenses/gpl-3.0.html)
4
5//! Functionality related to vectors representing spatial quantities, e.g., position, velocity and
6//! acceleration.
7//! 
8//! The data structure does not assume anything about the number of dimensions, meaning it can be 
9//! used both for 2D and 3D vectors.
10
11pub mod operators;
12pub mod serde_implementations;
13pub mod vector_math;
14pub mod transformations;
15pub mod geometry_functions;
16pub mod iterators;
17
18// Length of the vector
19pub const VECTOR_LENGTH: usize = 3;
20
21#[cfg(feature = "padded_spatial_vectors")]
22pub const DATA_SIZE: usize = 4;
23
24#[cfg(not(feature = "padded_spatial_vectors"))]
25pub const DATA_SIZE: usize = 3;
26
27use crate::type_aliases::Float;
28
29#[derive(Copy, Clone, Debug, PartialEq)]
30/// A 2D or 3D vector with typical geometric functions implemented
31pub struct SpatialVector(pub [Float; DATA_SIZE]);
32
33/// Convert from a 3-element array to a Vec3
34impl From<[Float; VECTOR_LENGTH]> for SpatialVector {
35    fn from(array: [Float; VECTOR_LENGTH]) -> Self {
36        let mut data = [0.0; DATA_SIZE];
37
38        for i in 0..VECTOR_LENGTH {
39            data[i] = array[i];
40        }
41
42        Self(data)
43    }
44}
45
46/// Convert from a Vec3 to a 3-element array
47impl From<SpatialVector> for [Float; VECTOR_LENGTH] {
48    fn from(vector: SpatialVector) -> [Float; VECTOR_LENGTH] {
49        let mut out = [0.0; VECTOR_LENGTH];
50
51        for i in 0..VECTOR_LENGTH {
52            out[i] = vector.0[i]
53        }
54
55        out
56    }
57}
58
59impl SpatialVector {
60    pub fn new(x: Float, y: Float, z: Float) -> Self {
61        let mut data = [0.0; DATA_SIZE];
62        data[0] = x;
63        data[1] = y;
64        data[2] = z;
65
66        Self(data)
67    }
68
69    pub fn unit_x() -> Self {
70        let mut data = [0.0; DATA_SIZE];
71
72        data[0] = 1.0;
73
74        Self(data)
75    }
76
77    pub fn unit_y() -> Self {
78        let mut data = [0.0; DATA_SIZE];
79
80        data[1] = 1.0;
81
82        Self(data)
83    }
84
85    pub fn unit_z() -> Self {
86        let mut data = [0.0; DATA_SIZE];
87
88        data[2] = 1.0;
89
90        Self(data)
91    }
92
93    pub fn replace_nans_with_zeros(&mut self) {
94        for i in 0..DATA_SIZE {
95            if self.0[i].is_nan() {
96                self.0[i] = 0.0;
97            }
98        }
99    }
100}
101
102impl Default for SpatialVector {
103    fn default() -> Self {
104        Self([0.0; DATA_SIZE])
105    }
106}
107
108impl std::fmt::Display for SpatialVector {
109    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
110        write!(f, "{:?}", self.0)
111    }
112}