parry2d/math/
vector_ext.rs1use crate::math::{IVector, Int, Matrix, Real, Vector};
4
5#[cfg(not(feature = "std"))]
6use simba::scalar::ComplexField;
7
8pub trait VectorExt: Sized + Copy {
10 fn ith(i: usize, val: Real) -> Self;
12
13 fn angle(self, other: Self) -> Real;
15
16 fn kronecker(self, other: Self) -> Matrix;
18
19 fn vget(&self, i: usize) -> Real;
24
25 fn vset(&mut self, i: usize, val: Real);
30}
31
32impl VectorExt for Vector {
33 #[inline]
34 #[cfg(feature = "dim2")]
35 fn ith(i: usize, val: Real) -> Self {
36 match i {
37 0 => Self::new(val, 0.0),
38 1 => Self::new(0.0, val),
39 _ => Self::ZERO,
40 }
41 }
42
43 #[inline]
44 #[cfg(feature = "dim3")]
45 fn ith(i: usize, val: Real) -> Self {
46 match i {
47 0 => Self::new(val, 0.0, 0.0),
48 1 => Self::new(0.0, val, 0.0),
49 2 => Self::new(0.0, 0.0, val),
50 _ => Self::ZERO,
51 }
52 }
53
54 #[inline]
55 fn angle(self, other: Self) -> Real {
56 let dot = self.dot(other);
57 let len_self = self.length();
58 let len_other = other.length();
59 if len_self > 0.0 && len_other > 0.0 {
60 (dot / (len_self * len_other)).clamp(-1.0, 1.0).acos()
61 } else {
62 0.0
63 }
64 }
65
66 #[inline]
67 #[cfg(feature = "dim2")]
68 fn kronecker(self, other: Self) -> Matrix {
69 Matrix::from_cols(self * other.x, self * other.y)
70 }
71
72 #[inline]
73 #[cfg(feature = "dim3")]
74 fn kronecker(self, other: Self) -> Matrix {
75 Matrix::from_cols(self * other.x, self * other.y, self * other.z)
76 }
77
78 #[inline]
79 fn vget(&self, i: usize) -> Real {
80 #[cfg(target_arch = "spirv")]
81 return match i {
82 0 => self.x,
83 1 => self.y,
84 #[cfg(feature = "dim3")]
85 2 => self.z,
86 _ => panic!("Index out of bounds for 2D vector: {i}"),
87 };
88 #[cfg(not(target_arch = "spirv"))]
89 {
90 self[i]
91 }
92 }
93
94 #[inline]
95 fn vset(&mut self, i: usize, val: Real) {
96 #[cfg(target_arch = "spirv")]
97 match i {
98 0 => self.x = val,
99 1 => self.y = val,
100 #[cfg(feature = "dim3")]
101 2 => self.z = val,
102 _ => panic!("Index out of bounds for 2D vector: {i}"),
103 };
104 #[cfg(not(target_arch = "spirv"))]
105 {
106 self[i] = val;
107 }
108 }
109}
110
111pub trait IVectorExt: Sized + Copy {
115 fn ivget(&self, i: usize) -> Int;
117
118 fn ivset(&mut self, i: usize, val: Int);
120}
121
122impl IVectorExt for IVector {
123 #[inline]
124 fn ivget(&self, i: usize) -> Int {
125 #[cfg(target_arch = "spirv")]
126 return match i {
127 0 => self.x,
128 1 => self.y,
129 #[cfg(feature = "dim3")]
130 2 => self.z,
131 _ => panic!("Index out of bounds for 2D integer vector: {i}"),
132 };
133 #[cfg(not(target_arch = "spirv"))]
134 {
135 self[i]
136 }
137 }
138
139 #[inline]
140 fn ivset(&mut self, i: usize, val: Int) {
141 #[cfg(target_arch = "spirv")]
142 match i {
143 0 => self.x = val,
144 1 => self.y = val,
145 #[cfg(feature = "dim3")]
146 2 => self.z = val,
147 _ => panic!("Index out of bounds for 2D integer vector: {i}"),
148 }
149 #[cfg(not(target_arch = "spirv"))]
150 {
151 self[i] = val;
152 }
153 }
154}