1#![allow(dead_code)]
2
3use std::{
4 fmt::Display,
5 ops::{Add, AddAssign, Div, DivAssign, Index, IndexMut, Mul, MulAssign, Neg, Sub, SubAssign},
6};
7
8use super::{vec2f, Vec2f, Vec3d, Vec4d};
9
10#[derive(Clone, Copy, PartialEq, Debug)]
11pub struct Vec2d {
12 x: f64,
13 y: f64,
14}
15
16pub fn vec2d(x: f64, y: f64) -> Vec2d {
17 Vec2d::new(x, y)
18}
19
20impl Display for Vec2d {
21 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
22 write!(f, "Vec2d(x: {}, y: {})", self.x, self.y)
23 }
24}
25
26impl Default for Vec2d {
27 fn default() -> Self {
28 Self::new(0.0, 0.0)
29 }
30}
31
32impl Add<Vec2d> for Vec2d {
33 type Output = Vec2d;
34
35 fn add(self, rhs: Vec2d) -> Self::Output {
36 Vec2d::new(self.x + rhs.x, self.y + rhs.y)
37 }
38}
39
40impl Add<f64> for Vec2d {
41 type Output = Vec2d;
42
43 fn add(self, rhs: f64) -> Self::Output {
44 Vec2d::new(self.x + rhs, self.y + rhs)
45 }
46}
47
48impl Add<Vec2d> for f64 {
49 type Output = Vec2d;
50
51 fn add(self, rhs: Vec2d) -> Self::Output {
52 Vec2d::new(self + rhs.x, self + rhs.y)
53 }
54}
55
56impl AddAssign<Vec2d> for Vec2d {
57 fn add_assign(&mut self, rhs: Vec2d) {
58 self.x += rhs.x;
59 self.y += rhs.y;
60 }
61}
62
63impl AddAssign<f64> for Vec2d {
64 fn add_assign(&mut self, rhs: f64) {
65 self.x += rhs;
66 self.y += rhs;
67 }
68}
69
70impl Sub<Vec2d> for Vec2d {
71 type Output = Vec2d;
72
73 fn sub(self, rhs: Vec2d) -> Self::Output {
74 Vec2d::new(self.x - rhs.x, self.y - rhs.y)
75 }
76}
77
78impl Sub<f64> for Vec2d {
79 type Output = Vec2d;
80
81 fn sub(self, rhs: f64) -> Self::Output {
82 Vec2d::new(self.x - rhs, self.y - rhs)
83 }
84}
85
86impl Sub<Vec2d> for f64 {
87 type Output = Vec2d;
88
89 fn sub(self, rhs: Vec2d) -> Self::Output {
90 Vec2d::new(self - rhs.x, self - rhs.y)
91 }
92}
93
94impl SubAssign<Vec2d> for Vec2d {
95 fn sub_assign(&mut self, rhs: Vec2d) {
96 self.x -= rhs.x;
97 self.y -= rhs.y;
98 }
99}
100
101impl SubAssign<f64> for Vec2d {
102 fn sub_assign(&mut self, rhs: f64) {
103 self.x -= rhs;
104 self.y -= rhs;
105 }
106}
107
108impl Mul<Vec2d> for Vec2d {
109 type Output = Vec2d;
110
111 fn mul(self, rhs: Vec2d) -> Self::Output {
112 Vec2d::new(self.x * rhs.x, self.y * rhs.y)
113 }
114}
115
116impl Mul<f64> for Vec2d {
117 type Output = Vec2d;
118
119 fn mul(self, rhs: f64) -> Self::Output {
120 Vec2d::new(self.x * rhs, self.y * rhs)
121 }
122}
123
124impl Mul<Vec2d> for f64 {
125 type Output = Vec2d;
126
127 fn mul(self, rhs: Vec2d) -> Self::Output {
128 Vec2d::new(self * rhs.x, self * rhs.y)
129 }
130}
131
132impl MulAssign<Vec2d> for Vec2d {
133 fn mul_assign(&mut self, rhs: Vec2d) {
134 self.x *= rhs.x;
135 self.y *= rhs.y;
136 }
137}
138
139impl MulAssign<f64> for Vec2d {
140 fn mul_assign(&mut self, rhs: f64) {
141 self.x *= rhs;
142 self.y *= rhs;
143 }
144}
145
146impl Div<Vec2d> for Vec2d {
147 type Output = Vec2d;
148
149 fn div(self, rhs: Vec2d) -> Self::Output {
150 Vec2d::new(self.x / rhs.x, self.y / rhs.y)
151 }
152}
153
154impl Div<f64> for Vec2d {
155 type Output = Vec2d;
156
157 fn div(self, rhs: f64) -> Self::Output {
158 Vec2d::new(self.x / rhs, self.y / rhs)
159 }
160}
161
162impl Div<Vec2d> for f64 {
163 type Output = Vec2d;
164
165 fn div(self, rhs: Vec2d) -> Self::Output {
166 Vec2d::new(self / rhs.x, self / rhs.y)
167 }
168}
169
170impl DivAssign<Vec2d> for Vec2d {
171 fn div_assign(&mut self, rhs: Vec2d) {
172 self.x /= rhs.x;
173 self.y /= rhs.y;
174 }
175}
176
177impl DivAssign<f64> for Vec2d {
178 fn div_assign(&mut self, rhs: f64) {
179 self.x /= rhs;
180 self.y /= rhs;
181 }
182}
183
184impl Neg for Vec2d {
185 type Output = Vec2d;
186
187 fn neg(self) -> Self::Output {
188 Self::new(-self.x, -self.y)
189 }
190}
191
192impl Index<usize> for Vec2d {
193 type Output = f64;
194
195 fn index(&self, index: usize) -> &Self::Output {
196 match index {
197 0 => &self.x,
198 1 => &self.y,
199 _ => panic!("`rmath::algebra::Vec2d::index`: index out of bounds."),
200 }
201 }
202}
203
204impl IndexMut<usize> for Vec2d {
205 fn index_mut(&mut self, index: usize) -> &mut Self::Output {
206 match index {
207 0 => &mut self.x,
208 1 => &mut self.y,
209 _ => panic!("`rmath::algebra::Vec2d::index_mut`: index out of bounds."),
210 }
211 }
212}
213
214impl From<f64> for Vec2d {
215 fn from(v: f64) -> Self {
216 Self::new(v, v)
217 }
218}
219
220impl From<(f64, f64)> for Vec2d {
221 fn from(v: (f64, f64)) -> Self {
222 let (x, y) = v;
223 Self::new(x, y)
224 }
225}
226
227impl From<Vec3d> for Vec2d {
228 fn from(v: Vec3d) -> Self {
229 v.xy()
230 }
231}
232
233impl From<Vec4d> for Vec2d {
234 fn from(v: Vec4d) -> Self {
235 v.xy()
236 }
237}
238
239impl Vec2d {
240 pub fn new(x: f64, y: f64) -> Self {
241 Self { x, y }
242 }
243
244 pub fn one() -> Self {
245 Self::new(1.0, 1.0)
246 }
247
248 pub fn zero() -> Self {
249 Self::new(0.0, 0.0)
250 }
251}
252
253impl Vec2d {
254 pub fn floor(self) -> Self {
255 Self::new(self.x.floor(), self.y.floor())
256 }
257
258 pub fn ceil(self) -> Self {
259 Self::new(self.x.ceil(), self.y.ceil())
260 }
261
262 pub fn round(self) -> Self {
263 Self::new(self.x.round(), self.y.round())
264 }
265
266 pub fn trunc(self) -> Self {
267 Self::new(self.x.trunc(), self.y.trunc())
268 }
269
270 pub fn fract(self) -> Self {
271 Self::new(self.x.fract(), self.y.fract())
272 }
273
274 pub fn abs(self) -> Self {
275 Self::new(self.x.abs(), self.y.abs())
276 }
277
278 pub fn signum(self) -> Self {
279 Self::new(self.x.signum(), self.y.signum())
280 }
281
282 pub fn powf(self, n: f64) -> Self {
283 Self::new(self.x.powf(n), self.y.powf(n))
284 }
285
286 pub fn sqrt(self) -> Self {
287 Self::new(self.x.sqrt(), self.y.sqrt())
288 }
289
290 pub fn exp(self) -> Self {
291 Self::new(self.x.exp(), self.y.exp())
292 }
293
294 pub fn exp2(self) -> Self {
295 Self::new(self.x.exp2(), self.y.exp2())
296 }
297
298 pub fn ln(self) -> Self {
299 Self::new(self.x.ln(), self.y.ln())
300 }
301
302 pub fn log(self, base: f64) -> Self {
303 Self::new(self.x.log(base), self.y.log(base))
304 }
305
306 pub fn log2(self) -> Self {
307 Self::new(self.x.log2(), self.y.log2())
308 }
309
310 pub fn log10(self) -> Self {
311 Self::new(self.x.log10(), self.y.log10())
312 }
313
314 pub fn cbrt(self) -> Self {
315 Self::new(self.x.cbrt(), self.y.cbrt())
316 }
317
318 pub fn sin(self) -> Self {
319 Self::new(self.x.sin(), self.y.sin())
320 }
321
322 pub fn cos(self) -> Self {
323 Self::new(self.x.cos(), self.y.cos())
324 }
325
326 pub fn tan(self) -> Self {
327 Self::new(self.x.tan(), self.y.tan())
328 }
329
330 pub fn sin_cos(self) -> (Self, Self) {
331 (self.sin(), self.cos())
332 }
333
334 pub fn lerp(self, rhs: Self, s: f64) -> Self {
335 self + (rhs - self) * s
336 }
337
338 pub fn lerp_vec(self, rhs: Self, s: Self) -> Self {
339 self + (rhs - self) * s
340 }
341
342 pub fn is_nan(self) -> bool {
343 self.x.is_nan() || self.y.is_nan()
344 }
345
346 pub fn is_infinite(self) -> bool {
347 self.x.is_infinite() || self.y.is_infinite()
348 }
349
350 pub fn is_finite(self) -> bool {
351 self.x.is_finite() && self.y.is_finite()
352 }
353
354 pub fn recip(self) -> Self {
355 Self::new(self.x.recip(), self.y.recip())
356 }
357
358 pub fn max(self, rhs: Self) -> Self {
359 Self::new(self.x.max(rhs.x), self.y.max(rhs.y))
360 }
361
362 pub fn min(self, rhs: Self) -> Self {
363 Self::new(self.x.min(rhs.x), self.y.min(rhs.y))
364 }
365
366 pub fn clamp(self, min: Self, max: Self) -> Self {
367 ruby_assert!(min.x <= max.x);
368 ruby_assert!(min.y <= max.y);
369
370 self.min(max).max(min)
371 }
372
373 pub fn saturate(self) -> Self {
374 self.clamp(Self::zero(), Self::one())
375 }
376
377 pub fn min_element(self) -> f64 {
378 self.x.min(self.y)
379 }
380
381 pub fn max_element(self) -> f64 {
382 self.x.max(self.y)
383 }
384}
385
386impl Vec2d {
387 pub fn dot(self, rhs: Self) -> f64 {
388 self.x * rhs.x + self.y * rhs.y
389 }
390
391 pub fn cross(self, rhs: Self) -> f64 {
392 self.x * rhs.y - self.y * rhs.x
393 }
394
395 pub fn length(self) -> f64 {
396 self.dot(self).sqrt()
397 }
398
399 pub fn length_squared(self) -> f64 {
400 self.dot(self)
401 }
402
403 pub fn length_recip(self) -> f64 {
404 self.length().recip()
405 }
406
407 pub fn distance(self, rhs: Self) -> f64 {
408 (rhs - self).length()
409 }
410
411 pub fn distance_squared(self, rhs: Self) -> f64 {
412 (rhs - self).length_squared()
413 }
414
415 pub fn normalize(self) -> Self {
416 let normalized = self * self.length_recip();
417 ruby_assert!(normalized.is_finite());
418 normalized
419 }
420
421 pub fn try_normalize(self) -> Option<Self> {
422 let recip = self.length_recip();
423 if recip.is_finite() && recip > 0.0 {
424 Some(self * recip)
425 } else {
426 None
427 }
428 }
429
430 pub fn normalize_or_zero(self) -> Self {
431 let recip = self.length_recip();
432 if recip.is_finite() && recip > 0.0 {
433 self * recip
434 } else {
435 Self::zero()
436 }
437 }
438
439 pub fn is_normalized(self) -> bool {
440 (self.length_squared() - 1.0f64).abs() < f64::EPSILON
441 }
442
443 pub fn angle_between(self, rhs: Self) -> f64 {
444 let angle = self
445 .dot(rhs)
446 .div(self.length_squared().mul(rhs.length_squared()).sqrt())
447 .acos();
448 if self.cross(rhs) < 0.0 {
449 -angle
450 } else {
451 angle
452 }
453 }
454}
455
456impl Vec2d {
457 pub fn to_array(self) -> [f64; 2] {
458 [self.x, self.y]
459 }
460
461 pub fn to_tuple(self) -> (f64, f64) {
462 (self.x, self.y)
463 }
464
465 pub fn to_vec2f(self) -> Vec2f {
466 vec2f(self.x as f32, self.y as f32)
467 }
468}
469
470impl Vec2d {
471 pub fn x(self) -> f64 {
472 self.x
473 }
474
475 pub fn y(self) -> f64 {
476 self.y
477 }
478
479 pub fn xx(self) -> Self {
480 Self::new(self.x, self.x)
481 }
482
483 pub fn xy(self) -> Self {
484 Self::new(self.x, self.y)
485 }
486
487 pub fn yx(self) -> Self {
488 Self::new(self.y, self.x)
489 }
490
491 pub fn yy(self) -> Self {
492 Self::new(self.y, self.y)
493 }
494
495 pub fn xxx(self) -> Vec3d {
496 Vec3d::new(self.x, self.x, self.x)
497 }
498
499 pub fn xxy(self) -> Vec3d {
500 Vec3d::new(self.x, self.x, self.y)
501 }
502
503 pub fn xyx(self) -> Vec3d {
504 Vec3d::new(self.x, self.y, self.x)
505 }
506
507 pub fn xyy(self) -> Vec3d {
508 Vec3d::new(self.x, self.y, self.y)
509 }
510
511 pub fn yxx(self) -> Vec3d {
512 Vec3d::new(self.y, self.x, self.x)
513 }
514
515 pub fn yxy(self) -> Vec3d {
516 Vec3d::new(self.y, self.x, self.y)
517 }
518
519 pub fn yyx(self) -> Vec3d {
520 Vec3d::new(self.y, self.y, self.x)
521 }
522
523 pub fn yyy(self) -> Vec3d {
524 Vec3d::new(self.y, self.y, self.y)
525 }
526
527 pub fn xxxx(self) -> Vec4d {
528 Vec4d::new(self.x, self.x, self.x, self.x)
529 }
530
531 pub fn xxxy(self) -> Vec4d {
532 Vec4d::new(self.x, self.x, self.x, self.y)
533 }
534
535 pub fn xxyx(self) -> Vec4d {
536 Vec4d::new(self.x, self.x, self.y, self.x)
537 }
538
539 pub fn xxyy(self) -> Vec4d {
540 Vec4d::new(self.x, self.x, self.y, self.y)
541 }
542
543 pub fn yxxx(self) -> Vec4d {
544 Vec4d::new(self.y, self.x, self.x, self.x)
545 }
546
547 pub fn yxxy(self) -> Vec4d {
548 Vec4d::new(self.y, self.x, self.x, self.y)
549 }
550
551 pub fn yxyx(self) -> Vec4d {
552 Vec4d::new(self.y, self.x, self.y, self.x)
553 }
554
555 pub fn yxyy(self) -> Vec4d {
556 Vec4d::new(self.y, self.x, self.y, self.y)
557 }
558}