state_space_tween/
vector.rs1use flo_curves::Coordinate;
2use num_traits::Float;
3use std::ops::{Add, Mul, Sub};
4
5#[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 let mut components_array = [Prim::zero(); SIZE];
112
113 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}