state_space_tween/
vector.rs

1use flo_curves::Coordinate;
2use num_traits::Float;
3use std::ops::{Add, Mul, Sub};
4
5/// A fully-generic N-dimensional vector, where no implementation details are known.
6#[derive(Debug, PartialEq, Clone, Copy)]
7pub(crate) struct VectorND<Prim, const SIZE: usize>(pub [Prim; SIZE])
8where
9    Prim: Float + Into<f64>;
10
11impl<Prim, const SIZE: usize> From<&[Prim]> for VectorND<Prim, SIZE>
12where
13    Prim: Float + Into<f64>,
14{
15    fn from(values: &[Prim]) -> Self {
16        assert_eq!(values.len(), SIZE);
17        Self::from_components(
18            values
19                .iter()
20                .map(|x| (*x).into())
21                .collect::<Vec<f64>>()
22                .as_slice(),
23        )
24    }
25}
26
27impl<Prim, const SIZE: usize> Into<[Prim; SIZE]> for VectorND<Prim, SIZE>
28where
29    Prim: Float + Into<f64>,
30{
31    fn into(self) -> [Prim; SIZE] {
32        self.0
33    }
34}
35
36impl<Prim, const SIZE: usize> Add for VectorND<Prim, SIZE>
37where
38    Prim: Float + Into<f64>,
39{
40    type Output = Self;
41
42    fn add(self, rhs: Self) -> Self::Output {
43        Self::from_components(
44            self.0
45                .iter()
46                .zip(rhs.0.iter())
47                .map(|(a, b)| (*a + *b).into())
48                .collect::<Vec<f64>>()
49                .as_slice(),
50        )
51    }
52}
53impl<Prim, const SIZE: usize> Mul for VectorND<Prim, SIZE>
54where
55    Prim: Float + Into<f64>,
56{
57    type Output = Self;
58
59    fn mul(self, rhs: Self) -> Self::Output {
60        Self::from_components(
61            self.0
62                .iter()
63                .zip(rhs.0.iter())
64                .map(|(a, b)| (*a * (*b)).into())
65                .collect::<Vec<f64>>()
66                .as_slice(),
67        )
68    }
69}
70impl<Prim, const SIZE: usize> Mul<f64> for VectorND<Prim, SIZE>
71where
72    Prim: Float + Into<f64>,
73{
74    type Output = Self;
75
76    fn mul(self, rhs: f64) -> Self::Output {
77        Self::from_components(
78            self.0
79                .iter()
80                .map(|a| rhs * (*a).into())
81                .collect::<Vec<f64>>()
82                .as_slice(),
83        )
84    }
85}
86
87impl<Prim, const SIZE: usize> Sub for VectorND<Prim, SIZE>
88where
89    Prim: Float + Into<f64>,
90{
91    type Output = Self;
92
93    fn sub(self, rhs: Self) -> Self::Output {
94        Self::from_components(
95            self.0
96                .iter()
97                .zip(rhs.0.iter())
98                .map(|(a, b)| (*a - *b).into())
99                .collect::<Vec<f64>>()
100                .as_slice(),
101        )
102    }
103}
104
105impl<Prim, const SIZE: usize> Coordinate for VectorND<Prim, SIZE>
106where
107    Prim: Float + Into<f64>,
108{
109    fn from_components(components: &[f64]) -> Self {
110        // Allocate an array to copy the components over
111        let mut components_array = [Prim::zero(); SIZE];
112
113        // Copy the components over the array
114        for (i, component) in components.iter().enumerate() {
115            if i < SIZE {
116                components_array[i] = Prim::from(*component).unwrap();
117            }
118        }
119
120        Self(components_array)
121    }
122
123    fn origin() -> Self {
124        Self([Prim::zero(); SIZE])
125    }
126
127    fn len() -> usize {
128        SIZE
129    }
130
131    fn get(&self, index: usize) -> f64 {
132        self.0[index].to_f64().unwrap()
133    }
134
135    fn from_biggest_components(p1: Self, p2: Self) -> Self {
136        let mut biggest = p1;
137        let mut smallest = p2;
138
139        if p1.0[0] < p2.0[0] {
140            biggest = p2;
141            smallest = p1;
142        }
143
144        for i in 1..SIZE {
145            if biggest.0[i] < smallest.0[i] {
146                biggest = smallest;
147                smallest = p2;
148            }
149        }
150
151        biggest
152    }
153
154    fn from_smallest_components(p1: Self, p2: Self) -> Self {
155        let mut smallest = p1;
156        let mut biggest = p2;
157
158        if p1.0[0] > p2.0[0] {
159            smallest = p2;
160            biggest = p1;
161        }
162
163        for i in 1..SIZE {
164            if smallest.0[i] > biggest.0[i] {
165                smallest = biggest;
166                biggest = p2;
167            }
168        }
169
170        smallest
171    }
172}