euler/
vec.rs

1use approx::ApproxEq;
2use cgmath;
3use std::{fmt, mem, ops};
4
5/// Single-precision 2D vector.
6#[derive(Clone, Copy, Debug, Default, PartialEq)]
7#[repr(C)]
8pub struct Vec2 {
9    pub x: f32,
10    pub y: f32,
11}
12
13impl Vec2 {
14    /// Full constructor.
15    pub fn new(x: f32, y: f32) -> Self {
16        Vec2 { x, y }
17    }
18
19    /// Zero constructor.
20    pub fn zero() -> Self {
21        Default::default()
22    }
23}
24
25impl From<f32> for Vec2 {
26    fn from(arg: f32) -> Self {
27        Self::new(arg, arg)
28    }
29}
30
31impl From<f64> for Vec2 {
32    fn from(arg: f64) -> Self {
33        Self::from(arg as f32)
34    }
35}
36
37impl From<DVec2> for Vec2 {
38    fn from(arg: DVec2) -> Self {
39        Self::new(arg.x as f32, arg.y as f32)
40    }
41}
42
43impl fmt::Display for Vec2 {
44    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
45        write!(f, "{:?}", (self.x, self.y))
46    }
47}
48
49/// Single-precision 3D vector.
50#[derive(Clone, Copy, Debug, Default, PartialEq)]
51#[repr(C)]
52pub struct Vec3 {
53    pub x: f32,
54    pub y: f32,
55    pub z: f32,
56}
57
58impl Vec3 {
59    /// Full constructor.
60    pub fn new(x: f32, y: f32, z: f32) -> Self {
61        Vec3 { x, y, z }
62    }
63
64    /// Zero constructor.
65    pub fn zero() -> Self {
66        Default::default()
67    }
68
69    /// Returns the XY components of the vector.
70    pub fn xy(self) -> Vec2 {
71        Vec2::new(self.x, self.y)
72    }
73}
74
75impl From<f32> for Vec3 {
76    fn from(arg: f32) -> Self {
77        Self::new(arg, arg, arg)
78    }
79}
80
81impl From<f64> for Vec3 {
82    fn from(arg: f64) -> Self {
83        Self::from(arg as f32)
84    }
85}
86
87impl From<DVec3> for Vec3 {
88    fn from(arg: DVec3) -> Self {
89        Self::new(arg.x as f32, arg.y as f32, arg.z as f32)
90    }
91}
92
93impl<T: Into<Vec2>> From<(T, f32)> for Vec3 {
94    fn from(arg: (T, f32)) -> Self {
95        let (v, z) = (arg.0.into(), arg.1);
96        Self::new(v.x, v.y, z)
97    }
98}
99
100impl fmt::Display for Vec3 {
101    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
102        write!(f, "{:?}", (self.x, self.y, self.z))
103    }
104}
105
106/// Single-precision 4D vector.
107#[derive(Clone, Copy, Debug, Default, PartialEq)]
108#[repr(C)]
109pub struct Vec4 {
110    pub x: f32,
111    pub y: f32,
112    pub z: f32,
113    pub w: f32,
114}
115
116impl Vec4 {
117    /// Full constructor.
118    pub fn new(x: f32, y: f32, z: f32, w: f32) -> Self {
119        Vec4 { x, y, z, w }
120    }
121
122    /// Zero constructor.
123    pub fn zero() -> Self {
124        Default::default()
125    }
126
127    /// Returns the XY components of the vector.
128    pub fn xy(self) -> Vec2 {
129        Vec2::new(self.x, self.y)
130    }
131
132    /// Returns the XYZ components of the vector.
133    pub fn xyz(self) -> Vec3 {
134        Vec3::new(self.x, self.y, self.z)
135    }
136}
137
138impl From<f32> for Vec4 {
139    fn from(arg: f32) -> Self {
140        Self::new(arg, arg, arg, arg)
141    }
142}
143
144impl From<f64> for Vec4 {
145    fn from(arg: f64) -> Self {
146        Self::from(arg as f32)
147    }
148}
149
150impl From<DVec4> for Vec4 {
151    fn from(arg: DVec4) -> Self {
152        Self::new(arg.x as f32, arg.y as f32, arg.z as f32, arg.w as f32)
153    }
154}
155
156impl<T: Into<Vec2>> From<(T, f32, f32)> for Vec4 {
157    fn from(arg: (T, f32, f32)) -> Self {
158        let (v, z, w) = (arg.0.into(), arg.1, arg.2);
159        Self::new(v.x, v.y, z, w)
160    }
161}
162
163impl<T: Into<Vec3>> From<(T, f32)> for Vec4 {
164    fn from(arg: (T, f32)) -> Self {
165        let (v, w) = (arg.0.into(), arg.1);
166        Self::new(v.x, v.y, v.z, w)
167    }
168}
169
170impl fmt::Display for Vec4 {
171    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
172        write!(f, "{:?}", (self.x, self.y, self.z, self.w))
173    }
174}
175
176/// Double-precision 2D vector.
177#[derive(Clone, Copy, Debug, Default, PartialEq)]
178#[repr(C)]
179pub struct DVec2 {
180    pub x: f64,
181    pub y: f64,
182}
183
184impl DVec2 {
185    /// Full constructor.
186    pub fn new(x: f64, y: f64) -> Self {
187        DVec2 { x, y }
188    }
189
190    /// Zero constructor.
191    pub fn zero() -> Self {
192        Default::default()
193    }
194}
195
196impl From<f32> for DVec2 {
197    fn from(arg: f32) -> Self {
198        Self::from(arg as f64)
199    }
200}
201
202impl From<f64> for DVec2 {
203    fn from(arg: f64) -> Self {
204        Self::new(arg, arg)
205    }
206}
207
208impl From<Vec2> for DVec2 {
209    fn from(arg: Vec2) -> Self {
210        Self::new(arg.x as f64, arg.y as f64)
211    }
212}
213
214impl fmt::Display for DVec2 {
215    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
216        write!(f, "{:?}", (self.x, self.y))
217    }
218}
219
220/// Double-precision 3D vector.
221#[derive(Clone, Copy, Debug, Default, PartialEq)]
222#[repr(C)]
223pub struct DVec3 {
224    pub x: f64,
225    pub y: f64,
226    pub z: f64,
227}
228
229impl DVec3 {
230    /// Full constructor.
231    pub fn new(x: f64, y: f64, z: f64) -> Self {
232        DVec3 { x, y, z }
233    }
234
235    /// Zero constructor.
236    pub fn zero() -> Self {
237        Default::default()
238    }
239
240    /// Returns the XY components of the vector.
241    pub fn xy(self) -> DVec2 {
242        DVec2::new(self.x, self.y)
243    }
244}
245
246impl From<f32> for DVec3 {
247    fn from(arg: f32) -> Self {
248        Self::from(arg as f64)
249    }
250}
251
252impl From<f64> for DVec3 {
253    fn from(arg: f64) -> Self {
254        Self::new(arg, arg, arg)
255    }
256}
257
258impl From<Vec3> for DVec3 {
259    fn from(arg: Vec3) -> Self {
260        Self::new(arg.x as f64, arg.y as f64, arg.z as f64)
261    }
262}
263
264impl<T: Into<DVec2>> From<(T, f64)> for DVec3 {
265    fn from(arg: (T, f64)) -> Self {
266        let (v, z) = (arg.0.into(), arg.1);
267        Self::new(v.x, v.y, z)
268    }
269}
270
271impl fmt::Display for DVec3 {
272    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
273        write!(f, "{:?}", (self.x, self.y, self.z))
274    }
275}
276
277/// Double-precision 4D vector.
278#[derive(Clone, Copy, Debug, Default, PartialEq)]
279#[repr(C)]
280pub struct DVec4 {
281    pub x: f64,
282    pub y: f64,
283    pub z: f64,
284    pub w: f64,
285}
286
287impl DVec4 {
288    /// Full constructor.
289    pub fn new(x: f64, y: f64, z: f64, w: f64) -> Self {
290        DVec4 { x, y, z, w }
291    }
292
293    /// Zero constructor.
294    pub fn zero() -> Self {
295        Default::default()
296    }
297
298    /// Returns the XY components of the vector.
299    pub fn xy(self) -> DVec2 {
300        DVec2::new(self.x, self.y)
301    }
302
303    /// Returns the XYZ components of the vector.
304    pub fn xyz(self) -> DVec3 {
305        DVec3::new(self.x, self.y, self.z)
306    }
307}
308
309impl From<f32> for DVec4 {
310    fn from(arg: f32) -> Self {
311        Self::from(arg as f64)
312    }
313}
314
315impl From<f64> for DVec4 {
316    fn from(arg: f64) -> Self {
317        Self::new(arg, arg, arg, arg)
318    }
319}
320
321impl From<Vec4> for DVec4 {
322    fn from(arg: Vec4) -> Self {
323        Self::new(arg.x as f64, arg.y as f64, arg.z as f64, arg.w as f64)
324    }
325}
326
327impl<T: Into<DVec2>> From<(T, f64, f64)> for DVec4 {
328    fn from(arg: (T, f64, f64)) -> Self {
329        let (v, z, w) = (arg.0.into(), arg.1, arg.2);
330        Self::new(v.x, v.y, z, w)
331    }
332}
333
334impl<T: Into<DVec3>> From<(T, f64)> for DVec4 {
335    fn from(arg: (T, f64)) -> Self {
336        let (v, w) = (arg.0.into(), arg.1);
337        Self::new(v.x, v.y, v.z, w)
338    }
339}
340
341impl fmt::Display for DVec4 {
342    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
343        write!(f, "{:?}", (self.x, self.y, self.z, self.w))
344    }
345}
346
347impl DVec3 {
348    /// Returns the cross product of two vectors.
349    pub fn cross(self, rhs: Self) -> Self {
350        let a: &cgmath::Vector3<f64> = self.as_ref().into();
351        let b: &cgmath::Vector3<f64> = rhs.as_ref().into();
352        let v: [f64; 3] = a.cross(*b).into();
353        v.into()
354    }
355}
356
357impl Vec3 {
358    /// Returns the cross product of two vectors.
359    pub fn cross(self, rhs: Self) -> Self {
360        let a: &cgmath::Vector3<f32> = self.as_ref().into();
361        let b: &cgmath::Vector3<f32> = rhs.as_ref().into();
362        let v: [f32; 3] = a.cross(*b).into();
363        v.into()
364    }
365}
366
367macro_rules! impl_angle {
368    ($self:ty, $base:ty) => {
369        impl $self {
370            /// Returns the acute angle between two vectors.
371            ///
372            /// # Panics
373            ///
374            /// Panics if `self` is the zero vector.
375            pub fn angle(self, rhs: $self) -> $base {
376                (self.dot(rhs) / self.length()).acos()
377            }
378        }
379    };
380}
381
382macro_rules! impl_vector {
383    ($self:ty, $base:ty, $inner:ty, $array:ty) => {
384        impl $self {
385            /// Returns the dot product of two vectors.
386            pub fn dot(self, rhs: $self) -> $base {
387                use cgmath::InnerSpace;
388                let a: &$inner = self.as_ref().into();
389                let b: &$inner = rhs.as_ref().into();
390                a.dot(*b)
391            }
392
393            /// Returns the length (magnitude) of the vector.
394            pub fn length(self) -> $base {
395                use cgmath::InnerSpace;
396                let a: &$inner = self.as_ref().into();
397                a.magnitude()
398            }
399
400            /// Returns the squared length of the vector.
401            pub fn squared_length(self) -> $base {
402                use cgmath::InnerSpace;
403                let a: &$inner = self.as_ref().into();
404                a.magnitude2()
405            }
406
407            /// Scales the vector to unit length.
408            ///
409            /// ## Panics
410            ///
411            /// Panics if the vector is zero.
412            pub fn normalize(self) -> $self {
413                use cgmath::InnerSpace;
414                let a: &$inner = self.as_ref().into();
415                let v: $array = a.normalize().into();
416                v.into()
417            }
418        }
419
420        impl ops::Add<$self> for $self {
421            type Output = $self;
422            fn add(self, rhs: $self) -> Self::Output {
423                let a: &$inner = self.as_ref().into();
424                let b: &$inner = rhs.as_ref().into();
425                let v: $array = (a + b).into();
426                v.into()
427            }
428        }
429
430        impl ops::AddAssign<$self> for $self {
431            fn add_assign(&mut self, rhs: $self) {
432                *self = *self + rhs;
433            }
434        }
435
436        impl<'a> std::iter::Sum<&'a Self> for $self {
437            fn sum<I>(iter: I) -> Self
438            where
439                I: Iterator<Item = &'a Self>,
440            {
441                iter.fold(Default::default(), |sum, x| sum + *x)
442            }
443        }
444
445        impl std::iter::Sum<Self> for $self {
446            fn sum<I>(iter: I) -> Self
447            where
448                I: Iterator<Item = Self>,
449            {
450                iter.fold(Default::default(), |sum, x| sum + x)
451            }
452        }
453
454        impl ops::Sub<$self> for $self {
455            type Output = $self;
456            fn sub(self, rhs: $self) -> Self::Output {
457                let a: &$inner = self.as_ref().into();
458                let b: &$inner = rhs.as_ref().into();
459                let v: $array = (a - b).into();
460                v.into()
461            }
462        }
463
464        impl ops::SubAssign<$self> for $self {
465            fn sub_assign(&mut self, rhs: $self) {
466                *self = *self - rhs;
467            }
468        }
469
470        impl ops::Mul<$self> for $base {
471            type Output = $self;
472            fn mul(self, arg: $self) -> Self::Output {
473                let a: &$inner = arg.as_ref().into();
474                let v: $array = (self * a).into();
475                v.into()
476            }
477        }
478
479        impl ops::Mul<$base> for $self {
480            type Output = $self;
481            fn mul(self, arg: $base) -> Self::Output {
482                let a: &$inner = self.as_ref().into();
483                let v: $array = (arg * a).into();
484                v.into()
485            }
486        }
487
488        impl ops::MulAssign<$base> for $self {
489            fn mul_assign(&mut self, rhs: $base) {
490                *self = *self * rhs;
491            }
492        }
493
494        impl ops::Div<$base> for $self {
495            type Output = $self;
496            fn div(self, arg: $base) -> Self::Output {
497                let a: &$inner = self.as_ref().into();
498                let v: $array = (a / arg).into();
499                v.into()
500            }
501        }
502
503        impl ops::DivAssign<$base> for $self {
504            fn div_assign(&mut self, rhs: $base) {
505                *self = *self / rhs;
506            }
507        }
508
509        impl AsRef<$array> for $self {
510            fn as_ref(&self) -> &$array {
511                unsafe { mem::transmute(self) }
512            }
513        }
514
515        impl From<$array> for $self {
516            fn from(array: $array) -> Self {
517                unsafe { mem::transmute(array) }
518            }
519        }
520
521        impl Into<$array> for $self {
522            fn into(self) -> $array {
523                unsafe { mem::transmute(self) }
524            }
525        }
526
527        impl ApproxEq for $self {
528            type Epsilon = <$inner as ApproxEq>::Epsilon;
529
530            fn default_epsilon() -> Self::Epsilon {
531                <$inner as ApproxEq>::default_epsilon()
532            }
533
534            fn default_max_relative() -> Self::Epsilon {
535                <$inner as ApproxEq>::default_max_relative()
536            }
537
538            fn default_max_ulps() -> u32 {
539                <$inner as ApproxEq>::default_max_ulps()
540            }
541
542            fn relative_eq(
543                &self,
544                other: &Self,
545                epsilon: Self::Epsilon,
546                max_relative: Self::Epsilon,
547            ) -> bool {
548                let a: &$inner = self.as_ref().into();
549                let b: &$inner = other.as_ref().into();
550                a.relative_eq(&b, epsilon, max_relative)
551            }
552
553            fn ulps_eq(&self, other: &Self, epsilon: Self::Epsilon, max_ulps: u32) -> bool {
554                let a: &$inner = self.as_ref().into();
555                let b: &$inner = other.as_ref().into();
556                a.ulps_eq(b, epsilon, max_ulps)
557            }
558        }
559    };
560}
561
562impl_vector!(Vec2, f32, cgmath::Vector2<f32>, [f32; 2]);
563impl_vector!(Vec3, f32, cgmath::Vector3<f32>, [f32; 3]);
564impl_vector!(Vec4, f32, cgmath::Vector4<f32>, [f32; 4]);
565
566impl_vector!(DVec2, f64, cgmath::Vector2<f64>, [f64; 2]);
567impl_vector!(DVec3, f64, cgmath::Vector3<f64>, [f64; 3]);
568impl_vector!(DVec4, f64, cgmath::Vector4<f64>, [f64; 4]);
569
570impl_angle!(Vec2, f32);
571impl_angle!(Vec3, f32);
572
573impl_angle!(DVec2, f64);
574impl_angle!(DVec3, f64);
575
576#[cfg(test)]
577mod tests {
578    #[test]
579    pub fn vec4_sum() {
580        use crate::vec4;
581        let vs = [
582            vec4!(1.0, 2.0, 3.0),
583            vec4!(0.0, 0.0, 0.0),
584            vec4!(-3.0, -2.0, -1.0),
585        ];
586        let sum = vs.iter().sum();
587        approx::assert_relative_eq!(sum, vec4!(-2.0, 0.0, 2.0));
588    }
589}
590
591#[cfg(feature = "mint")]
592mod mint_support {
593    use super::*;
594    use mint;
595
596    macro_rules! impl_mint_conversion {
597        ($self:ty, $mint:ty, $via:ty) => {
598            impl From<$mint> for $self {
599                fn from(m: $mint) -> Self {
600                    let v: $via = m.into();
601                    v.into()
602                }
603            }
604
605            impl Into<$mint> for $self {
606                fn into(self) -> $mint {
607                    let v: $via = self.into();
608                    v.into()
609                }
610            }
611        };
612    }
613
614    impl_mint_conversion!(Vec2, mint::Point2<f32>, [f32; 2]);
615    impl_mint_conversion!(Vec3, mint::Point3<f32>, [f32; 3]);
616
617    impl_mint_conversion!(Vec2, mint::Vector2<f32>, [f32; 2]);
618    impl_mint_conversion!(Vec3, mint::Vector3<f32>, [f32; 3]);
619    impl_mint_conversion!(Vec4, mint::Vector4<f32>, [f32; 4]);
620
621    impl_mint_conversion!(DVec2, mint::Point2<f64>, [f64; 2]);
622    impl_mint_conversion!(DVec3, mint::Point3<f64>, [f64; 3]);
623
624    impl_mint_conversion!(DVec2, mint::Vector2<f64>, [f64; 2]);
625    impl_mint_conversion!(DVec3, mint::Vector3<f64>, [f64; 3]);
626    impl_mint_conversion!(DVec4, mint::Vector4<f64>, [f64; 4]);
627}