ferroui_base/numerics/
vector2.rs1use std::fmt;
4use std::ops::{Add, AddAssign, Div, DivAssign, Mul, MulAssign, Neg, Sub, SubAssign};
5
6use super::single::{self, InvariantF32};
7use super::{Matrix3x2, Matrix4x4, Quaternion};
8use crate::Vector;
9
10#[derive(Clone, Copy, Debug, PartialEq, Default)]
12pub struct Vector2 {
13 pub x: f32,
15 pub y: f32,
17}
18
19impl Vector2 {
20 pub const ZERO: Vector2 = Vector2::new(0.0, 0.0);
22 pub const ONE: Vector2 = Vector2::new(1.0, 1.0);
24 pub const UNIT_X: Vector2 = Vector2::new(1.0, 0.0);
26 pub const UNIT_Y: Vector2 = Vector2::new(0.0, 1.0);
28
29 #[inline]
31 pub const fn new(x: f32, y: f32) -> Self {
32 Self { x, y }
33 }
34
35 #[inline]
37 pub const fn from_value(value: f32) -> Self {
38 Self::new(value, value)
39 }
40
41 #[inline]
44 pub fn abs(value: Vector2) -> Vector2 {
45 Vector2::new(value.x.abs(), value.y.abs())
46 }
47
48 #[inline]
51 pub fn clamp(value1: Vector2, min: Vector2, max: Vector2) -> Vector2 {
52 Vector2::min(Vector2::max(value1, min), max)
53 }
54
55 #[inline]
57 pub fn distance(value1: Vector2, value2: Vector2) -> f32 {
58 Vector2::distance_squared(value1, value2).sqrt()
59 }
60
61 #[inline]
63 pub fn distance_squared(value1: Vector2, value2: Vector2) -> f32 {
64 (value1 - value2).length_squared()
65 }
66
67 #[inline]
69 pub fn dot(value1: Vector2, value2: Vector2) -> f32 {
70 (value1.x * value2.x) + (value1.y * value2.y)
71 }
72
73 #[inline]
75 pub fn length(&self) -> f32 {
76 self.length_squared().sqrt()
77 }
78
79 #[inline]
81 pub fn length_squared(&self) -> f32 {
82 Vector2::dot(*self, *self)
83 }
84
85 #[inline]
87 pub fn lerp(value1: Vector2, value2: Vector2, amount: f32) -> Vector2 {
88 (value1 * (1.0 - amount)) + (value2 * amount)
89 }
90
91 #[inline]
94 pub fn max(value1: Vector2, value2: Vector2) -> Vector2 {
95 Vector2::new(single::max(value1.x, value2.x), single::max(value1.y, value2.y))
96 }
97
98 #[inline]
101 pub fn min(value1: Vector2, value2: Vector2) -> Vector2 {
102 Vector2::new(single::min(value1.x, value2.x), single::min(value1.y, value2.y))
103 }
104
105 #[inline]
108 pub fn normalize(value: Vector2) -> Vector2 {
109 value / value.length()
110 }
111
112 #[inline]
115 pub fn square_root(value: Vector2) -> Vector2 {
116 Vector2::new(value.x.sqrt(), value.y.sqrt())
117 }
118
119 #[inline]
121 pub fn transform(position: Vector2, matrix: Matrix3x2) -> Vector2 {
122 Vector2::new(
123 (position.x * matrix.m11) + (position.y * matrix.m21) + matrix.m31,
124 (position.x * matrix.m12) + (position.y * matrix.m22) + matrix.m32,
125 )
126 }
127
128 #[inline]
130 pub fn transform_matrix4x4(position: Vector2, matrix: Matrix4x4) -> Vector2 {
131 Vector2::new(
132 (position.x * matrix.m11) + (position.y * matrix.m21) + matrix.m41,
133 (position.x * matrix.m12) + (position.y * matrix.m22) + matrix.m42,
134 )
135 }
136
137 pub fn transform_quaternion(value: Vector2, rotation: Quaternion) -> Vector2 {
139 let x2 = rotation.x + rotation.x;
140 let y2 = rotation.y + rotation.y;
141 let z2 = rotation.z + rotation.z;
142
143 let wz2 = rotation.w * z2;
144 let xx2 = rotation.x * x2;
145 let xy2 = rotation.x * y2;
146 let yy2 = rotation.y * y2;
147 let zz2 = rotation.z * z2;
148
149 Vector2::new(
150 value.x * (1.0 - yy2 - zz2) + value.y * (xy2 - wz2),
151 value.x * (xy2 + wz2) + value.y * (1.0 - xx2 - zz2),
152 )
153 }
154
155 #[inline]
157 pub fn transform_normal(normal: Vector2, matrix: Matrix3x2) -> Vector2 {
158 Vector2::new(
159 (normal.x * matrix.m11) + (normal.y * matrix.m21),
160 (normal.x * matrix.m12) + (normal.y * matrix.m22),
161 )
162 }
163}
164
165impl From<Vector> for Vector2 {
167 #[inline]
168 fn from(value: Vector) -> Vector2 {
169 Vector2::new(value.x as f32, value.y as f32)
170 }
171}
172
173impl From<Vector2> for Vector {
175 #[inline]
176 fn from(value: Vector2) -> Vector {
177 Vector::new(value.x as f64, value.y as f64)
178 }
179}
180
181impl Add for Vector2 {
182 type Output = Vector2;
183 #[inline]
184 fn add(self, right: Vector2) -> Vector2 {
185 Vector2::new(self.x + right.x, self.y + right.y)
186 }
187}
188
189impl Sub for Vector2 {
190 type Output = Vector2;
191 #[inline]
192 fn sub(self, right: Vector2) -> Vector2 {
193 Vector2::new(self.x - right.x, self.y - right.y)
194 }
195}
196
197impl Mul for Vector2 {
198 type Output = Vector2;
199 #[inline]
200 fn mul(self, right: Vector2) -> Vector2 {
201 Vector2::new(self.x * right.x, self.y * right.y)
202 }
203}
204
205impl Mul<f32> for Vector2 {
206 type Output = Vector2;
207 #[inline]
208 fn mul(self, right: f32) -> Vector2 {
209 Vector2::new(self.x * right, self.y * right)
210 }
211}
212
213impl Mul<Vector2> for f32 {
214 type Output = Vector2;
215 #[inline]
216 fn mul(self, right: Vector2) -> Vector2 {
217 right * self
218 }
219}
220
221impl Div for Vector2 {
222 type Output = Vector2;
223 #[inline]
224 fn div(self, right: Vector2) -> Vector2 {
225 Vector2::new(self.x / right.x, self.y / right.y)
226 }
227}
228
229impl Div<f32> for Vector2 {
230 type Output = Vector2;
231 #[inline]
232 fn div(self, right: f32) -> Vector2 {
233 Vector2::new(self.x / right, self.y / right)
234 }
235}
236
237impl Neg for Vector2 {
238 type Output = Vector2;
239 #[inline]
240 fn neg(self) -> Vector2 {
241 Vector2::new(-self.x, -self.y)
242 }
243}
244
245impl AddAssign for Vector2 {
246 #[inline]
247 fn add_assign(&mut self, right: Vector2) {
248 *self = *self + right;
249 }
250}
251
252impl SubAssign for Vector2 {
253 #[inline]
254 fn sub_assign(&mut self, right: Vector2) {
255 *self = *self - right;
256 }
257}
258
259impl MulAssign for Vector2 {
260 #[inline]
261 fn mul_assign(&mut self, right: Vector2) {
262 *self = *self * right;
263 }
264}
265
266impl MulAssign<f32> for Vector2 {
267 #[inline]
268 fn mul_assign(&mut self, right: f32) {
269 *self = *self * right;
270 }
271}
272
273impl DivAssign for Vector2 {
274 #[inline]
275 fn div_assign(&mut self, right: Vector2) {
276 *self = *self / right;
277 }
278}
279
280impl DivAssign<f32> for Vector2 {
281 #[inline]
282 fn div_assign(&mut self, right: f32) {
283 *self = *self / right;
284 }
285}
286
287impl fmt::Display for Vector2 {
288 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
289 write!(f, "<{}, {}>", InvariantF32(self.x), InvariantF32(self.y))
290 }
291}