ruby_math/algebra/vec/
vec2d.rs

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}