cvmath/vec.rs
1/*!
2Defines the vector types.
3
4An overview of their implementations:
5
6## Derived traits
7
8`Copy`, `Clone` where T: `Copy`, `Clone`: For convenience all instances are passed by value, greatly simplifying usage.
9
10`Debug`, `Display` where T: `Debug`, `Display`: Struct-based formatting and tuple-based formatting respectively.
11
12`Eq`, `PartialEq` where T: `Eq`, `PartialEq`: Compares if _all_ the underlying components are equal.
13
14`Ord`, `PartialOrd` where T: `Ord`, `PartialOrd`
15
16`Hash` where T: `Hash`
17
18### Examples
19
20```
21use cvmath::{Vec2, Vec3};
22
23assert_eq!("(2,3,4)", format!("{}", Vec3(2, 3, 4)));
24assert_eq!("(2.300,2.142)", format!("{:.3}", Vec2(2.3, 2.14159278)));
25assert_eq!("(16,25)", format!("{:?}", Vec2(16, 25)));
26assert_eq!("( 2, 3, 14)", format!("{:>3}", Vec3(2, 3, 14)));
27
28assert_eq!(Vec2 { x: -5, y: 9 }, Vec2(-5, 9));
29assert!(Vec2(1, 9) > Vec2(1, -2));
30```
31
32## Constructors
33
34`new(x, y, ...)`: Constructs a new vector from components.
35
36`dup(u)` where T: `Copy`: Constructs a new vector by splatting to its components.
37
38`X`, `Y`, `Z`, `W` where T: `Zero` + `One`: Constructs a unit vector along the given axis (given that axis exists for the vector).
39
40`with_x(self, x)`, `with_y(self, y)`, `with_z(self, z)`, `with_w(self, w)`: Note that these return new vectors with the respective component changed.
41
42`get(self, c)`: Gets a component generically.
43
44`shuffle(self, x, y, ..)`: Shuffles the components.
45
46### Examples
47
48```
49use cvmath::{Vec2, Vec3, X, Y, Z};
50
51assert_eq!(Vec2 { x: 1, y: 2 }, Vec2(1, 2));
52
53assert_eq!(Vec3 { x: 42, y: 42, z: 42 }, Vec3::dup(42));
54
55assert_eq!(Vec2 { x: 0.0, y: 1.0 }, Vec2::Y);
56assert_eq!(Vec3 { x: 1, y: 0, z: 0 }, Vec3::X);
57
58assert_eq!(Vec3 { x: -12, y: 0, z: 12 }, Vec3::default().with_x(-12).with_z(12));
59
60assert_eq!(2, Vec2 { x: 13, y: 2}.get(Y));
61
62assert_eq!(Vec3 { x: 5, y: -2, z: 5 }, Vec3(-2, 12, 5).shuffle(Z, X, Z));
63```
64
65## Extending and truncating
66
67`vec3(self, T)`: Extends `Vec2` with a `z` component.
68
69`vec4(self, T)`: Extends `Vec3` with a `w` component.
70
71`xy(self)`: Drops the `z` component from `Vec3` and `w` from `Vec4`.
72
73`xyz(self)`: Drops the `w` component from `Vec4`.
74
75### Examples
76
77```
78use cvmath::{Vec2, Vec3, Vec4};
79
80assert_eq!(Vec3 { x: 3, y: 4, z: 5 }, Vec2(3, 4).vec3(5));
81
82assert_eq!(Vec4 { x: -1, y: -2, z: -3, w: -4 }, Vec3(-1, -2, -3).vec4(-4));
83
84assert_eq!(Vec2 { x: 2, y: 1 }, Vec3(2, 1, 0).xy());
85assert_eq!(Vec2 { x: 1, y: 2 }, Vec4(1, 2, 3, 4).xy());
86
87assert_eq!(Vec3 { x: 1, y: 2, z: 3 }, Vec4(1, 2, 3, 4).xyz());
88```
89
90## Transformations
91
92`cast<U>(self)` where T: `CastTo<U>`: Casts to a vector of type `U` with the same dimensions.
93
94`map<U, F>(self, F)` where F: `FnMut(T) -> U`: Maps a callable over the components.
95
96`zip<U, F>(self, rhs, F)` where F: `FnMut(T, T) -> U`: Zips two vectors together.
97
98`reduce<F>(self, F)` where F: `Fn(T, T) -> T`: Reduces the vector. The `x` component is used as the initial value of the accumulator.
99
100`fold<A, F>(self, acc, F)` where F: `Fn(A, T) -> A`: Folds the vector.
101
102### Examples
103
104```
105use cvmath::{Vec2, Vec3};
106
107assert_eq!(Vec2 { x: 2, y: 4 }, Vec2(2.2, 4.9).cast());
108
109assert_eq!(Vec2 { x: 2, y: 4 }, Vec2(1, 2).map(|c| c * 2));
110
111let left = Vec2(1, 2);
112let right = Vec2(1, -1);
113assert_eq!(Vec2 { x: 3, y: 3 }, Vec2::zip(left, right, |a, b| a * 2 + b));
114
115let vec = Vec3(5, 3, 2);
116assert_eq!(0, vec.reduce(|acc, c| acc - c));
117assert_eq!(-10, vec.fold(0, |acc, c| acc - c));
118```
119
120## Conversions
121
122`From`, `Into`: PointN, N-tuple and N-array conversions.
123
124`AsRef`, `AsMut`: PointN, N-tuple, N-array and slice conversions.
125
126### Examples
127
128```
129use cvmath::Vec2;
130
131assert_eq!(Vec2::<i32>::from((2, 3)), Vec2::from([2, 3]));
132```
133
134## Operations where T is `Scalar`
135
136`sqr(self)`: Squares the components.
137
138`len_sqr(self)`: Calculates the squared length of the vector.
139
140`len(self)` where T: `Float`: Calculates the length of the vector.
141
142`distance_sqr(self, to)`: Calculates the squared euclidean distance to another vector.
143
144`distance(self, to)` where T: `Float`: Calculates the euclidean distance to another vector.
145
146`normalize(self)` where T: `Float`: Normalizes the vector. The vector with length zero stays zero.
147
148`resize(self, len)` where T: `Float`: Scales the vector such that its length equals the given value. The vector with length zero remains zero.
149
150`project_scalar(self, v)` where T: `Float`: Scalar projection of `self` onto `v`.
151
152`project(self, v)` where T: `Float`: Projection of `self` onto `v`.
153
154`project_sat(self, v)` where T: `Float`: Saturated projection of `self` onto `v`.
155
156`dot(self, rhs)`: Calculates the inner product.
157
158`cos_angle(self, rhs)`: Calculates the cosine of the inner angle.
159
160`angle(self, rhs)`: Calculates the inner angle.
161
162`hadd(self)`: Horizontal adds all components.
163
164`abs(self)`: Component-wise absolute value.
165
166`min(self, rhs)`: Component-wise minimum value.
167
168`vmin(self)`: Horizontal minimum value.
169
170`max(self, rhs)`: Component-wise maximum value.
171
172`vmax(self)`: Horizontal maximum value.
173
174`mul_add(self, vec, scale)`: Adds the scaled value.
175
176Exclusive to `Vec2`:
177
178`polar_angle(self)`: Calculates the polar angle.
179
180`ccw(self)`: Rotates the vector counter-clockwise by 90°.
181
182`cw(self)`: Rotates the vector clockwise by 90°.
183
184`cross(self, rhs)`: Calculates the 3D cross product where the inputs are extended with `z = 0` and returns the magnitude of the result.
185
186`hsub(self)`: Horizontal subtracts y from x.
187
188Exclusive to `Vec3`:
189
190`cross(self, rhs)`: Calculates the 3D cross product.
191
192### Examples
193
194```
195use cvmath::{Vec2, Vec3};
196
197assert_eq!(Vec2 { x: 9, y: 16 }, Vec2(3, 4).sqr());
198
199assert_eq!(25, Vec2(3, 4).len_sqr());
200assert_eq!(5.0, Vec2(3.0, 4.0).len());
201
202assert_eq!(2, Vec2::distance_sqr(Vec2(1, 1), Vec2(2, 2)));
203assert_eq!(5.0, Vec2::distance(Vec2(10.0, 10.0), Vec2(13.0, 14.0)));
204
205assert_eq!(Vec2 { x: 0.6, y: 0.8 }, Vec2(3.0, 4.0).normalize());
206assert_eq!(Vec2 { x: 0.0, y: 0.0 }, Vec2(0.0, 0.0).normalize());
207
208assert_eq!(Vec2 { x: 1.5, y: 2.0 }, Vec2(3.0, 4.0).resize(2.5));
209assert_eq!(Vec2 { x: 0.0, y: 0.0 }, Vec2(0.0, 0.0).resize(2.0));
210
211assert_eq!(2.0, Vec2(2.0, 1.0).project_scalar(Vec2(3.0, 4.0)));
212assert_eq!(2.0, Vec2(2.0, 1.0).project(Vec2(3.0, 4.0)).len());
213assert_eq!(Vec2(-3.0, -4.0), Vec2(-5.0, -2.5).project(Vec2(3.0, 4.0)));
214assert_eq!(Vec2(0.0, 0.0), Vec2(-5.0, -2.5).project_sat(Vec2(3.0, 4.0)));
215
216assert_eq!(2.2, Vec2(1.0, 2.0).project_scalar(Vec2(3.0, 4.0)));
217assert_eq!(2.0, Vec3(1.0, 4.0, 0.0).project_scalar(Vec3(4.0, 2.0, 4.0)));
218
219assert_eq!(12, Vec3(3, 4, 5).hadd());
220assert_eq!(-1, Vec2(3, 4).hsub());
221
222assert_eq!(Vec2 { x: 4, y: -3 }, Vec2(3, 4).ccw());
223assert_eq!(Vec2 { x: -4, y: 3 }, Vec2(3, 4).cw());
224assert_eq!(10, Vec2::cross(Vec2(3, 4), Vec2(-1, 2)));
225
226assert_eq!(12, Vec3::dot(Vec3(1, 2, 3), Vec3(4, -5, 6)));
227assert_eq!(Vec3 { x: -12, y: 1, z: 39 }, Vec3::cross(Vec3(3, -3, 1), Vec3(4, 9, 1)));
228```
229
230## Operators
231
232`Add`: Adds the vectors component-wise.
233
234`Sub`: Subtracts the vectors component-wise.
235
236`Neg`: Negates the vector component-wise.
237
238`Mul`: Multiply by scalar or vector.
239
240`Div`: Divide by scalar or vector.
241
242`Rem`: Remainder by scalar or vector.
243
244### Examples
245
246*/
247
248use super::*;
249
250// /// A 1-dimensional vector.
251// #[derive(Copy, Clone, Default, Eq, PartialEq, Ord, PartialOrd, Hash)]
252// #[repr(C)]
253// pub struct Vec1<T> {
254// pub x: T,
255// }
256
257/// Vec2 vector.
258#[derive(Copy, Clone, Default, Eq, PartialEq, Ord, PartialOrd, Hash)]
259#[repr(C)]
260pub struct Vec2<T> {
261 pub x: T,
262 pub y: T,
263}
264
265/// Vec3 vector.
266#[derive(Copy, Clone, Default, Eq, PartialEq, Ord, PartialOrd, Hash)]
267#[repr(C)]
268pub struct Vec3<T> {
269 pub x: T,
270 pub y: T,
271 pub z: T,
272}
273
274/// Vec4 vector.
275#[derive(Copy, Clone, Default, Eq, PartialEq, Ord, PartialOrd, Hash)]
276#[repr(C)]
277pub struct Vec4<T> {
278 pub x: T,
279 pub y: T,
280 pub z: T,
281 pub w: T,
282}
283
284/// X component.
285pub struct X;
286/// Y component.
287pub struct Y;
288/// Z component.
289pub struct Z;
290/// W component.
291pub struct W;
292
293/// Access the components of a vector generically.
294///
295/// Implementation helper for other functions.
296pub trait ComponentImpl<T, C> {
297 fn get(self) -> T;
298}
299
300impl<T> ComponentImpl<T, X> for Vec2<T> {
301 #[inline]
302 #[must_use]
303 fn get(self) -> T { self.x }
304}
305impl<T> ComponentImpl<T, Y> for Vec2<T> {
306 #[inline]
307 #[must_use]
308 fn get(self) -> T { self.y }
309}
310
311impl<T> ComponentImpl<T, X> for Vec3<T> {
312 #[inline]
313 #[must_use]
314 fn get(self) -> T { self.x }
315}
316impl<T> ComponentImpl<T, Y> for Vec3<T> {
317 #[inline]
318 #[must_use]
319 fn get(self) -> T { self.y }
320}
321impl<T> ComponentImpl<T, Z> for Vec3<T> {
322 #[inline]
323 #[must_use]
324 fn get(self) -> T { self.z }
325}
326
327impl<T> ComponentImpl<T, X> for Vec4<T> {
328 #[inline]
329 #[must_use]
330 fn get(self) -> T { self.x }
331}
332impl<T> ComponentImpl<T, Y> for Vec4<T> {
333 #[inline]
334 #[must_use]
335 fn get(self) -> T { self.y }
336}
337impl<T> ComponentImpl<T, Z> for Vec4<T> {
338 #[inline]
339 #[must_use]
340 fn get(self) -> T { self.z }
341}
342impl<T> ComponentImpl<T, W> for Vec4<T> {
343 #[inline]
344 #[must_use]
345 fn get(self) -> T { self.w }
346}
347
348macro_rules! unit {
349 (Vec1) => {
350 /// Unit vector in the `x` direction.
351 pub const X: Vec1<T> = Vec1 { x: T::ONE };
352 };
353 (Vec2) => {
354 /// Unit vector in the `x` direction.
355 pub const X: Vec2<T> = Vec2 { x: T::ONE, y: T::ZERO };
356 /// Unit vector in the `y` direction.
357 pub const Y: Vec2<T> = Vec2 { x: T::ZERO, y: T::ONE };
358 };
359 (Vec3) => {
360 /// Unit vector in the `x` direction.
361 pub const X: Vec3<T> = Vec3 { x: T::ONE, y: T::ZERO, z: T::ZERO };
362 /// Unit vector in the `y` direction.
363 pub const Y: Vec3<T> = Vec3 { x: T::ZERO, y: T::ONE, z: T::ZERO };
364 /// Unit vector in the `z` direction.
365 pub const Z: Vec3<T> = Vec3 { x: T::ZERO, y: T::ZERO, z: T::ONE };
366 };
367 (Vec4) => {
368 /// Unit vector in the `x` direction.
369 pub const X: Vec4<T> = Vec4 { x: T::ONE, y: T::ZERO, z: T::ZERO, w: T::ZERO };
370 /// Unit vector in the `y` direction.
371 pub const Y: Vec4<T> = Vec4 { x: T::ZERO, y: T::ONE, z: T::ZERO, w: T::ZERO };
372 /// Unit vector in the `z` direction.
373 pub const Z: Vec4<T> = Vec4 { x: T::ZERO, y: T::ZERO, z: T::ONE, w: T::ZERO };
374 /// Unit vector in the `w` direction.
375 pub const W: Vec4<T> = Vec4 { x: T::ZERO, y: T::ZERO, z: T::ZERO, w: T::ONE };
376 };
377}
378
379macro_rules! with {
380 (Vec1) => {
381 /// Sets the `x` component.
382 #[inline]
383 #[must_use]
384 pub fn with_x(self, x: T) -> Vec1<T> { Vec1 { x } }
385 };
386 (Vec2) => {
387 /// Sets the `x` component.
388 #[inline]
389 #[must_use]
390 pub fn with_x(self, x: T) -> Vec2<T> { Vec2 { x, y: self.y } }
391 /// Sets the `y` component.
392 #[inline]
393 #[must_use]
394 pub fn with_y(self, y: T) -> Vec2<T> { Vec2 { x: self.x, y } }
395 };
396 (Vec3) => {
397 /// Sets the `x` component.
398 #[inline]
399 #[must_use]
400 pub fn with_x(self, x: T) -> Vec3<T> { Vec3 { x, y: self.y, z: self.z } }
401 /// Sets the `y` component.
402 #[inline]
403 #[must_use]
404 pub fn with_y(self, y: T) -> Vec3<T> { Vec3 { x: self.x, y, z: self.z } }
405 /// Sets the `z` component.
406 #[inline]
407 #[must_use]
408 pub fn with_z(self, z: T) -> Vec3<T> { Vec3 { x: self.x, y: self.y, z } }
409 };
410 (Vec4) => {
411 /// Sets the `x` component.
412 #[inline]
413 #[must_use]
414 pub fn with_x(self, x: T) -> Vec4<T> { Vec4 { x, y: self.y, z: self.z, w: self.w } }
415 /// Sets the `y` component.
416 #[inline]
417 #[must_use]
418 pub fn with_y(self, y: T) -> Vec4<T> { Vec4 { x: self.x, y, z: self.z, w: self.w } }
419 /// Sets the `z` component.
420 #[inline]
421 #[must_use]
422 pub fn with_z(self, z: T) -> Vec4<T> { Vec4 { x: self.x, y: self.y, z, w: self.w } }
423 /// Sets the `w` component.
424 #[inline]
425 #[must_use]
426 pub fn with_w(self, w: T) -> Vec4<T> { Vec4 { x: self.x, y: self.y, z: self.z, w } }
427 };
428}
429
430macro_rules! cvt {
431 (Vec1) => {
432 /// Extends the 1D vector with a `y` component.
433 #[inline]
434 #[must_use]
435 pub fn vec2(self, y: T) -> Vec2<T> { Vec2 { x: self.x, y } }
436 };
437 (Vec2) => {
438 /// Extends the 2D vector with a `z` component.
439 #[inline]
440 #[must_use]
441 pub fn vec3(self, z: T) -> Vec3<T> { Vec3 { x: self.x, y: self.y, z } }
442 /// Extends the 2D vector with a `z` and `w` component.
443 #[inline]
444 #[must_use]
445 pub fn vec4(self, z: T, w: T) -> Vec4<T> { Vec4 { x: self.x, y: self.y, z, w } }
446 };
447 (Vec3) => {
448 /// Extends the 3D vector with a `w` component.
449 #[inline]
450 #[must_use]
451 pub fn vec4(self, w: T) -> Vec4<T> { Vec4 { x: self.x, y: self.y, z: self.z, w } }
452 /// Drops the `z` component.
453 #[inline]
454 #[must_use]
455 pub fn xy(self) -> Vec2<T> { Vec2 { x: self.x, y: self.y } }
456 };
457 (Vec4) => {
458 /// Drops the `z` and `w` coordinates.
459 #[inline]
460 #[must_use]
461 pub fn xy(self) -> Vec2<T> { Vec2 { x: self.x, y: self.y } }
462 /// Drops the `w` component.
463 #[inline]
464 #[must_use]
465 pub fn xyz(self) -> Vec3<T> { Vec3 { x: self.x, y: self.y, z: self.z } }
466 };
467}
468
469macro_rules! fmt {
470 ($ty:ident { $($field:ident),+ }) => {
471 fmt!($ty { $($field),+ } fmt::Display);
472 fmt!($ty { $($field),+ } fmt::Debug);
473 fmt!($ty { $($field),+ } fmt::Binary);
474 fmt!($ty { $($field),+ } fmt::Octal);
475 fmt!($ty { $($field),+ } fmt::LowerHex);
476 fmt!($ty { $($field),+ } fmt::UpperHex);
477 fmt!($ty { $($field),+ } fmt::LowerExp);
478 fmt!($ty { $($field),+ } fmt::UpperExp);
479 };
480 ($ty:ident { $($field:ident),+ } $fmt:path) => {
481 impl<T: $fmt> $fmt for $ty<T> {
482 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
483 f.write_str("(")?;
484 instmt!(f.write_str(",")?; $(self.$field.fmt(f)?;)+);
485 f.write_str(")")
486 }
487 }
488 };
489}
490
491macro_rules! parse_vec_elems {
492 ($s:ident, $iter:ident, $next:ident; $field:ident, $($tail:ident),+) => {{
493 $field = {
494 let start = $next;
495 let end = $iter.next().ok_or(ParseVecError::DimMismatch)?;
496 $next = end + 1;
497 $s[start..end].trim().parse()?
498 };
499 parse_vec_elems!($s, $iter, $next; $($tail),+);
500 }};
501 ($s:ident, $iter:ident, $next:ident; $field:ident) => {{
502 $field = {
503 if $iter.next().is_some() {
504 return Err(ParseVecError::DimMismatch);
505 }
506 $s[$next..$s.len() - 1].trim().parse()?
507 };
508 }};
509}
510
511// This may or may not be horrible abuse of the `macro_rules!` system :)
512macro_rules! vec {
513 (
514 $vec:ident $N:tt
515 { $($field:ident $I:tt $T:ident $U:ident $C:ident),+ }
516 { $($ops:tt)* }
517 ) => {
518
519 #[cfg(feature = "dataview")]
520 unsafe impl<T> dataview::Pod for $vec<T> where T: dataview::Pod {}
521
522 //----------------------------------------------------------------
523 // Constructors
524
525 impl<T> $vec<T> {
526 /// Constructs a new vector from components.
527 #[inline]
528 #[must_use]
529 pub const fn new($($field: T),+) -> $vec<T> {
530 $vec { $($field),+ }
531 }
532 /// Constructs a new vector by broadcasting to all its components.
533 #[inline]
534 #[must_use]
535 pub const fn dup(u: T) -> $vec<T> where T: Copy {
536 $vec { $($field: u),+ }
537 }
538 }
539
540 impl<T: Zero> $vec<T> {
541 /// Returns the origin for the vector space.
542 #[inline]
543 #[must_use]
544 pub const fn zero() -> $vec<T> {
545 $vec { $($field: T::ZERO),+ }
546 }
547 #[doc = stringify!($vec)]
548 #[doc = " of all zero."]
549 pub const ZERO: $vec<T> = $vec { $($field: T::ZERO),+ };
550 }
551 impl<T: One> $vec<T> {
552 #[doc = stringify!($vec)]
553 #[doc = " of all one."]
554 pub const ONE: $vec<T> = $vec { $($field: T::ONE),+ };
555 }
556 impl<T: Zero> Zero for $vec<T> {
557 const ZERO: $vec<T> = $vec::ZERO;
558 }
559 impl<T: One> One for $vec<T> {
560 const ONE: $vec<T> = $vec::ONE;
561 }
562 impl<T: Zero + One> $vec<T> {
563 unit!($vec);
564 }
565
566 #[doc = stringify!($vec)]
567 #[doc = " constructor."]
568 #[allow(non_snake_case)]
569 #[inline]
570 #[must_use]
571 pub const fn $vec<T>($($field: T),+) -> $vec<T> {
572 $vec { $($field),+ }
573 }
574
575 impl<T> $vec<T> {
576 with!($vec);
577 cvt!($vec);
578 }
579
580 impl<T: Copy> $vec<T> {
581 /// Gets a component generically.
582 #[inline]
583 #[must_use]
584 pub fn get<C>(self, _: C) -> T where Self: ComponentImpl<T, C> {
585 <Self as ComponentImpl<T, C>>::get(self)
586 }
587 /// Shuffles the components.
588 #[inline]
589 #[must_use]
590 #[allow(unused_variables)]
591 pub fn shuffle<$($C),+>(self, $($field: $C),+) -> $vec<T> where Self: $(ComponentImpl<$T, $C> +)+ {
592 $vec {
593 $($field: <Self as ComponentImpl<$T, $C>>::get(self),)+
594 }
595 }
596 }
597
598 //----------------------------------------------------------------
599 // Transformations
600
601 impl<T> $vec<T> {
602 /// Casts to a vector of different type with the same dimensions.
603 #[inline]
604 #[must_use]
605 pub fn cast<U>(self) -> $vec<U> where T: CastTo<U> {
606 $vec { $($field: self.$field.cast_to()),+ }
607 }
608 /// Maps a callable over the components.
609 #[inline]
610 #[must_use]
611 pub fn map<U, F>(self, mut f: F) -> $vec<U> where F: FnMut(T) -> U {
612 $vec { $($field: f(self.$field)),+ }
613 }
614 /// Zips two vectors together.
615 #[inline]
616 #[must_use]
617 pub fn zip<U, F>(self, rhs: $vec<T>, mut f: F) -> $vec<U> where F: FnMut(T, T) -> U {
618 $vec { $($field: f(self.$field, rhs.$field)),+ }
619 }
620 /// Reduces the vector.
621 #[inline]
622 #[must_use]
623 pub fn reduce<F>(self, f: F) -> T where F: Fn(T, T) -> T {
624 // These will end up nested without temporaries which won't work with `FnMut`...
625 fold!(f, $(self.$field),+)
626 }
627 /// Folds the vector.
628 #[inline]
629 #[must_use]
630 pub fn fold<A, F>(self, acc: A, f: F) -> A where F: Fn(A, T) -> A {
631 // These will end up nested without temporaries which won't work with `FnMut`...
632 fold!(f, acc, $(self.$field),+)
633 }
634 }
635
636 //----------------------------------------------------------------
637 // Conversions
638
639 impl<T: Scalar> From<T> for $vec<T> {
640 #[inline]
641 #[must_use]
642 fn from(val: T) -> $vec<T> {
643 $vec { $($field: val),+ }
644 }
645 }
646
647 impl<T> From<($($T,)+)> for $vec<T> {
648 #[inline]
649 #[must_use]
650 fn from(val: ($($T,)+)) -> $vec<T> {
651 $vec { $($field: val.$I),+ }
652 }
653 }
654 impl<T> Into<($($T,)+)> for $vec<T> {
655 #[inline]
656 #[must_use]
657 fn into(self) -> ($($T,)+) {
658 ($(self.$field,)+)
659 }
660 }
661
662 impl<T> From<[T; $N]> for $vec<T> {
663 #[inline]
664 #[must_use]
665 fn from(val: [T; $N]) -> $vec<T> {
666 let [$($field),+] = val;
667 $vec { $($field),+ }
668 }
669 }
670 impl<T> Into<[T; $N]> for $vec<T> {
671 #[inline]
672 #[must_use]
673 fn into(self) -> [T; $N] {
674 [$(self.$field),+]
675 }
676 }
677
678 //----------------------------------------------------------------
679 // As references
680
681 impl<T> AsRef<[T; $N]> for $vec<T> {
682 #[inline]
683 #[must_use]
684 fn as_ref(&self) -> &[T; $N] {
685 unsafe { mem::transmute(self) }
686 }
687 }
688 impl<T> AsRef<[T]> for $vec<T> {
689 #[inline]
690 #[must_use]
691 fn as_ref(&self) -> &[T] {
692 <Self as AsRef<[T; $N]>>::as_ref(self)
693 }
694 }
695 impl<T> $vec<T> {
696 #[inline]
697 #[must_use]
698 pub fn as_bytes(&self) -> &[u8] {
699 unsafe { slice::from_raw_parts(self as *const _ as *const u8, mem::size_of_val(self)) }
700 }
701 }
702
703 impl<T> AsMut<[T; $N]> for $vec<T> {
704 #[inline]
705 #[must_use]
706 fn as_mut(&mut self) -> &mut [T; $N] {
707 unsafe { mem::transmute(self) }
708 }
709 }
710 impl<T> AsMut<[T]> for $vec<T> {
711 #[inline]
712 #[must_use]
713 fn as_mut(&mut self) -> &mut [T] {
714 <Self as AsMut<[T; $N]>>::as_mut(self)
715 }
716 }
717
718 impl<T> ops::Index<usize> for $vec<T> {
719 type Output = T;
720 #[inline]
721 #[must_use]
722 fn index(&self, i: usize) -> &T {
723 let array: &[T; $N] = self.as_ref();
724 &array[i]
725 }
726 }
727
728 //----------------------------------------------------------------
729 // Operations
730
731 /// Operations on vectors of scalars.
732 impl<T: Scalar> $vec<T> {
733 /// Squares the components.
734 ///
735 /// ```
736 /// use cvmath::{Vec2, Vec3};
737 ///
738 /// let this = Vec2 { x: -3, y: 4 };
739 /// assert_eq!(Vec2(9, 16), this.sqr());
740 ///
741 /// let this = Vec3 { x: 2, y: 3, z: -6 };
742 /// assert_eq!(Vec3(4, 9, 36), this.sqr());
743 /// ```
744 #[inline]
745 #[must_use]
746 pub fn sqr(self) -> $vec<T> {
747 $vec { $($field: self.$field * self.$field),+ }
748 }
749 /// Calculates the squared length of the vector.
750 ///
751 /// ```
752 /// use cvmath::{Vec2, Vec3};
753 ///
754 /// let this = Vec2 { x: -3, y: 4 };
755 /// assert_eq!(25, this.len_sqr());
756 ///
757 /// let this = Vec3 { x: 2, y: -3, z: 6 };
758 /// assert_eq!(49, this.len_sqr());
759 /// ```
760 #[inline]
761 #[must_use]
762 pub fn len_sqr(self) -> T {
763 infix!(+ $(self.$field * self.$field),+)
764 }
765 /// Calculates the length of the vector.
766 ///
767 /// ```
768 /// use cvmath::{Vec2, Vec3};
769 ///
770 /// let this = Vec2 { x: -3.0, y: 4.0 };
771 /// assert_eq!(5.0, this.len());
772 ///
773 /// let this = Vec3 { x: -2.0, y: 3.0, z: -6.0 };
774 /// assert_eq!(7.0, this.len());
775 /// ```
776 #[inline]
777 #[must_use]
778 pub fn len(self) -> T where T: Float {
779 self.len_sqr().sqrt()
780 }
781 /// Calculates the manhattan length of the vector.
782 ///
783 /// <!--LEN_HAT--><svg width="400" height="120" font-family="monospace" xmlns="http://www.w3.org/2000/svg"><path fill="none" d="M40 100 L360.5 20 M353.70688 25.818361 L360.5 20 L351.76944 18.056509" stroke="black" /><path fill="none" d="M40 100 L360.5 100 M352.5 104 L360.5 100 L352.5 96" stroke="grey" stroke-width="0.5" /><path fill="none" d="M360.5 100 L360.5 20 M364.5 28 L360.5 20 L356.5 28" stroke="grey" stroke-width="0.5" /><circle cx="40" cy="100" r="2" /><text x="365.5" y="20">this</text><text x="200.25" y="115" fill="grey">x</text><text x="365.5" y="60" fill="grey">y</text></svg>
784 ///
785 /// ```
786 /// use cvmath::{Vec2, Vec3};
787 ///
788 /// let this = Vec2 { x: 3, y: 4 };
789 /// assert_eq!(7, this.len_hat());
790 ///
791 /// let this = Vec3 { x: 2, y: -3, z: -6 };
792 /// assert_eq!(11, this.len_hat());
793 /// ```
794 #[inline]
795 #[must_use]
796 pub fn len_hat(self) -> T {
797 infix!(+ $(self.$field.abs()),+)
798 }
799 /// Calculates the squared euclidean distance to another vector.
800 ///
801 /// ```
802 /// use cvmath::Vec2;
803 ///
804 /// let this = Vec2 { x: 1, y: 1 };
805 /// let to = Vec2 { x: 2, y: 2 };
806 /// assert_eq!(2, this.distance_sqr(to));
807 /// ```
808 #[inline]
809 #[must_use]
810 pub fn distance_sqr(self, to: $vec<T>) -> T {
811 infix!(+ $((to.$field - self.$field) * (to.$field - self.$field)),+)
812 }
813 /// Calculates the euclidean distance to another vector.
814 ///
815 /// ```
816 /// use cvmath::Vec2;
817 ///
818 /// let this = Vec2 { x: 10.0, y: 10.0 };
819 /// let to = Vec2 { x: 13.0, y: 14.0 };
820 /// assert_eq!(5.0, this.distance(to));
821 /// ```
822 #[inline]
823 #[must_use]
824 pub fn distance(self, to: $vec<T>) -> T where T: Float {
825 self.distance_sqr(to).sqrt()
826 }
827 /// Calculates the manhattan distance to another vector.
828 ///
829 /// <!--DISTANCE_HAT--><svg width="400" height="120" font-family="monospace" xmlns="http://www.w3.org/2000/svg"><line x1="40" y1="100" x2="360.5" y2="20" stroke="black" /><path fill="none" d="M40 100 L360.5 100 M352.5 104 L360.5 100 L352.5 96" stroke="grey" stroke-width="0.5" /><path fill="none" d="M360.5 100 L360.5 20 M364.5 28 L360.5 20 L356.5 28" stroke="grey" stroke-width="0.5" /><circle cx="40" cy="100" r="2" /><circle cx="360.5" cy="20" r="2" /><text x="20" y="90">this</text><text x="365.5" y="20">to</text><text x="200.25" y="115" fill="grey">x</text><text x="365.5" y="60" fill="grey">y</text></svg>
830 ///
831 /// ```
832 /// use cvmath::{Vec2, Vec3};
833 ///
834 /// let this = Vec2 { x: 1.0, y: 5.0 };
835 /// let to = Vec2 { x: 5.0, y: 2.0 };
836 /// assert_eq!(7.0, this.distance_hat(to));
837 ///
838 /// let this = Vec3 { x: 1.0, y: 5.0, z: -1.0 };
839 /// let to = Vec3 { x: 2.0, y: 3.0, z: 1.0 };
840 /// assert_eq!(5.0, this.distance_hat(to));
841 /// ```
842 #[inline]
843 #[must_use]
844 pub fn distance_hat(self, to: $vec<T>) -> T {
845 infix!(+ $((to.$field - self.$field).abs()),+)
846 }
847 /// Normalizes the vector.
848 ///
849 /// After normalizing the vector has the length `1.0` except the zero vector remains zero.
850 ///
851 /// ```
852 /// use cvmath::{Vec2, Vec3};
853 ///
854 /// let this = Vec2 { x: 3.0, y: -4.0 };
855 /// assert_eq!(Vec2(0.6, -0.8), this.normalize());
856 ///
857 /// let this = Vec3 { x: 0.0, y: 0.0, z: 0.0 };
858 /// assert_eq!(this, this.normalize());
859 /// ```
860 #[inline]
861 #[must_use]
862 pub fn normalize(self) -> $vec<T> where T: Float {
863 self.normalize_len().0
864 }
865 /// Calculates the normalized vector and its length.
866 ///
867 /// After normalizing the vector has the length `1.0` except the zero vector remains zero.
868 ///
869 /// ```
870 /// use cvmath::{Vec2, Vec3};
871 ///
872 /// let this = Vec2 { x: 3.0, y: -4.0 };
873 /// assert_eq!((Vec2(0.6, -0.8), 5.0), this.normalize_len());
874 ///
875 /// let this = Vec3 { x: 0.0, y: 0.0, z: 0.0 };
876 /// assert_eq!((this, 0.0), this.normalize_len());
877 /// ```
878 #[inline]
879 #[must_use]
880 pub fn normalize_len(self) -> ($vec<T>, T) where T: Float {
881 let self_len = self.len();
882 if self_len > T::ZERO {
883 (self / self_len, self_len)
884 }
885 else {
886 (self, self_len)
887 }
888 }
889 /// Resizes the vector to the given length.
890 ///
891 /// The zero vector remains zero.
892 ///
893 /// ```
894 /// use cvmath::{Vec2, Vec3};
895 ///
896 /// let this = Vec2 { x: -3.0, y: -4.0 };
897 /// assert_eq!(Vec2(-1.5, -2.0), this.resize(2.5));
898 ///
899 /// let this = Vec3 { x: 0.0, y: 0.0, z: 0.0 };
900 /// assert_eq!(Vec3(0.0, 0.0, 0.0), this.resize(2.0));
901 /// ```
902 #[inline]
903 #[must_use]
904 pub fn resize(self, len: T) -> $vec<T> where T: Float {
905 let self_len = self.len();
906 if self_len > T::ZERO {
907 self * (len / self_len)
908 }
909 else { self }
910 }
911 /// Calculates the length of `self` projected onto `v`.
912 ///
913 /// <!--PROJECT_SCALAR--><svg width="400" height="200" font-family="monospace" xmlns="http://www.w3.org/2000/svg"><path fill="none" d="M40 160 L200 20 M196.6134 28.278343 L200 20 L191.34537 22.257729" stroke="black" /><path fill="none" d="M40 160 L360 120 M352.5579 124.96139 L360 120 L351.56564 117.02317" stroke="black" /><circle cx="40" cy="160" r="2" fill="black" /><line x1="214.76923" y1="138.15384" x2="200" y2="20" stroke="black" stroke-dasharray="5.0, 5.0" stroke-width="0.5" /><line x1="194.92368" y1="140.63454" x2="192.44298" y2="120.78898" stroke="black" stroke-width="0.5" /><line x1="192.44298" y1="120.78898" x2="212.28854" y2="118.30828" stroke="black" stroke-width="0.5" /><line x1="41.860523" y1="174.88417" x2="216.62975" y2="153.03801" stroke="red" stroke-width="1.5" /><line x1="41.395393" y1="171.16313" x2="42.325653" y2="178.60521" stroke="red" stroke-width="1.5" /><line x1="216.16461" y1="149.31697" x2="217.09488" y2="156.75905" stroke="red" stroke-width="1.5" /><text x="205" y="25" fill="black">self</text><text x="340" y="142" fill="black">v</text></svg>
914 ///
915 /// ```
916 /// use cvmath::{Vec2, Vec3};
917 ///
918 /// let this = Vec2 { x: 1.0, y: 2.0 };
919 /// let v = Vec2 { x: 3.0, y: 4.0 };
920 /// assert_eq!(2.2, this.project_scalar(v));
921 ///
922 /// let this = Vec3 { x: 1.0, y: 4.0, z: 0.0 };
923 /// let v = Vec3 { x: 4.0, y: 2.0, z: 4.0 };
924 /// assert_eq!(2.0, this.project_scalar(v));
925 /// ```
926 #[inline]
927 #[must_use]
928 pub fn project_scalar(self, v: $vec<T>) -> T where T: Float {
929 let len = v.len();
930 if len > T::ZERO {
931 v.dot(self) / len
932 }
933 else { len }
934 }
935 /// Projection of `self` onto `v`.
936 ///
937 /// <!--PROJECT-->
938 ///
939 /// ```
940 /// use cvmath::{Vec2, Vec3};
941 ///
942 /// let this = Vec2 { x: -5.0, y: -2.5 };
943 /// let v = Vec2 { x: 3.0, y: 4.0 };
944 /// assert_eq!(Vec2(-3.0, -4.0), this.project(v));
945 ///
946 /// let this = Vec3 { x: -5.0, y: -2.5, z: 0.0 };
947 /// let v = Vec3 { x: 3.0, y: 4.0, z: 0.0 };
948 /// assert_eq!(Vec3(-3.0, -4.0, 0.0), this.project(v));
949 /// ```
950 #[inline]
951 #[must_use]
952 pub fn project(self, v: $vec<T>) -> $vec<T> where T: Float {
953 let len_sqr = v.len_sqr();
954 if len_sqr > T::ZERO {
955 v * (v.dot(self) / len_sqr)
956 }
957 else { v }
958 }
959 /// Projection of `self` onto `v` clamped to `v`.
960 ///
961 /// <!--PROJECT_SAT-->
962 ///
963 /// ```
964 /// use cvmath::Vec2;
965 ///
966 /// let this = Vec2 { x: -5.0, y: -2.5 };
967 /// let v = Vec2 { x: 3.0, y: 4.0 };
968 /// assert_eq!(Vec2(0.0, 0.0), this.project_sat(v));
969 /// ```
970 #[inline]
971 #[must_use]
972 pub fn project_sat(self, v: $vec<T>) -> $vec<T> {
973 let len_sqr = v.len_sqr();
974 if len_sqr > T::ZERO {
975 v * (v.dot(self) / len_sqr).min(T::ONE).max(T::ZERO)
976 }
977 else { v }
978 }
979 /// Reflects `self` around `v`.
980 ///
981 /// <!--REFLECT_2D--><svg width="400" height="200" font-family="monospace" xmlns="http://www.w3.org/2000/svg"><line x1="140" y1="20" x2="175.29413" y2="161.17647" stroke="black" stroke-width="0.5" stroke-dasharray="5.0, 5.0" /><line x1="157.64706" y1="90.588234" x2="57.647064" y2="190.58823" stroke="black" stroke-width="0.5" stroke-dasharray="5.0, 5.0" /><line x1="57.647064" y1="190.58823" x2="175.29413" y2="161.17647" stroke="black" stroke-width="0.5" stroke-dasharray="5.0, 5.0" /><path fill="none" d="M40 120 L290 57.5 M283.209 63.320854 L290 57.5 L281.2687 55.559715" stroke="black" /><path fill="none" d="M40 120 L140 20 M137.17157 28.485283 L140 20 L131.51471 22.828426" stroke="black" /><path fill="none" d="M40 120 L175.29413 161.17647 M166.47609 162.67386 L175.29413 161.17647 L168.80537 155.02048" stroke="red" /><circle cx="157.64706" cy="90.588234" r="2" fill="black" /><text x="290" y="57.5" fill="black">v</text><text x="140" y="20" fill="black">self</text><text x="165.64706" y="100.588234" fill="black">p</text><text x="175.29413" y="161.17647" fill="red">result</text><text x="52.647064" y="175.58823" fill="black">-self</text><text x="151.76471" y="182.05882" fill="black">+p</text></svg>
982 ///
983 /// <!--REFLECT_3D-->
984 ///
985 /// ```
986 /// use cvmath::Vec2;
987 ///
988 /// let this = Vec2 { x: 1.0, y: 3.0 };
989 /// let v = Vec2 { x: 4.0, y: 4.0 };
990 /// assert_eq!(Vec2(3.0, 1.0), this.reflect(v));
991 /// ```
992 #[inline]
993 #[must_use]
994 pub fn reflect(self, v: $vec<T>) -> $vec<T> where T: Float {
995 let p = self.project(v);
996 p + p - self
997 }
998 $($ops)*
999 /// Calculates the dot product.
1000 ///
1001 /// <!--DOT-->
1002 ///
1003 /// ```
1004 /// use cvmath::Vec3;
1005 ///
1006 /// let lhs = Vec3 { x: 1, y: 2, z: 3 };
1007 /// let rhs = Vec3 { x: 4, y: -5, z: 6 };
1008 /// assert_eq!(12, Vec3::dot(lhs, rhs));
1009 /// ```
1010 #[inline]
1011 #[must_use]
1012 pub fn dot(self, rhs: $vec<T>) -> T {
1013 infix!(+ $(self.$field * rhs.$field),+)
1014 }
1015 /// Calculates the cosine of the angle between two vectors.
1016 ///
1017 /// <!--COS_ANGLE-->
1018 ///
1019 /// ```
1020 /// use cvmath::Vec2;
1021 ///
1022 /// let lhs = Vec2 { x: 1.0, y: 1.0 };
1023 /// let rhs = Vec2 { x: 1.0, y: 0.0 };
1024 /// let sqrt_2_div_2 = 1.0 / 2_f32.sqrt(); // √2 ÷ 2
1025 /// assert_eq!(sqrt_2_div_2, lhs.cos_angle(rhs));
1026 /// ```
1027 #[inline]
1028 #[must_use]
1029 pub fn cos_angle(self, rhs: $vec<T>) -> T where T: Float {
1030 // |self| * |rhs| <=> √(self ∙ self * rhs ∙ rhs)
1031 let d = (self.dot(self) * rhs.dot(rhs)).sqrt();
1032 self.dot(rhs) / d
1033 }
1034 /// Calculates the angle between two vectors.
1035 ///
1036 /// <!--ANGLE-->
1037 ///
1038 /// ```
1039 /// use cvmath::{Deg, Vec2};
1040 ///
1041 /// let lhs = Vec2 { x: 1.0, y: 1.0 };
1042 /// let rhs = Vec2 { x: 1.0, y: 0.0 };
1043 /// assert_eq!(Deg(45_f32), lhs.angle(rhs).to_deg());
1044 /// ```
1045 #[inline]
1046 #[must_use]
1047 pub fn angle(self, rhs: $vec<T>) -> Rad<T> where T: Float {
1048 Rad::acos(self.cos_angle(rhs))
1049 }
1050 /// Horizontal adds all components.
1051 ///
1052 /// ```
1053 /// use cvmath::{Vec2, Vec3};
1054 ///
1055 /// let this = Vec2 { x: -2, y: 7 };
1056 /// assert_eq!(5, this.hadd());
1057 ///
1058 /// let this = Vec3 { x: 3, y: 4, z: 5 };
1059 /// assert_eq!(12, this.hadd());
1060 /// ```
1061 #[inline]
1062 #[must_use]
1063 pub fn hadd(self) -> T {
1064 infix!(+ $(self.$field),+)
1065 }
1066 /// Component-wise absolute value.
1067 ///
1068 /// ```
1069 /// use cvmath::Vec2;
1070 ///
1071 /// let this = Vec2 { x: -3, y: 5 };
1072 /// assert_eq!(Vec2(3, 5), this.abs());
1073 /// ```
1074 #[inline]
1075 #[must_use]
1076 pub fn abs(self) -> $vec<T> {
1077 $vec { $($field: self.$field.abs()),+ }
1078 }
1079 /// Component-wise minimum value.
1080 ///
1081 /// ```
1082 /// use cvmath::Vec2;
1083 ///
1084 /// let lhs = Vec2 { x: -3, y: 5 };
1085 /// let rhs = Vec2 { x: 0, y: 2 };
1086 /// assert_eq!(Vec2(-3, 2), lhs.min(rhs));
1087 /// ```
1088 #[inline]
1089 #[must_use]
1090 pub fn min(self, rhs: $vec<T>) -> $vec<T> {
1091 $vec { $($field: T::min(self.$field, rhs.$field)),+ }
1092 }
1093 /// Horizontal minimum value.
1094 #[inline]
1095 #[must_use]
1096 pub fn vmin(self) -> T {
1097 self.reduce(T::min)
1098 }
1099 /// Component-wise maximum value.
1100 ///
1101 /// ```
1102 /// use cvmath::Vec2;
1103 ///
1104 /// let lhs = Vec2 { x: -3, y: 5 };
1105 /// let rhs = Vec2 { x: 0, y: 2 };
1106 /// assert_eq!(Vec2(0, 5), lhs.max(rhs));
1107 /// ```
1108 #[inline]
1109 #[must_use]
1110 pub fn max(self, rhs: $vec<T>) -> $vec<T> {
1111 $vec { $($field: T::max(self.$field, rhs.$field)),+ }
1112 }
1113 /// Horizontal maximum value.
1114 #[inline]
1115 #[must_use]
1116 pub fn vmax(self) -> T {
1117 self.reduce(T::max)
1118 }
1119 /// Adds the scaled vector.
1120 ///
1121 /// Equivalent to `self + (vec * scale)` with less rounding errors.
1122 #[inline]
1123 #[must_use]
1124 pub fn mul_add(self, vec: $vec<T>, scale: T) -> $vec<T> {
1125 $vec { $($field: T::mul_add(vec.$field, scale, self.$field)),+ }
1126 }
1127 /// Linear interpolation between the vectors.
1128 ///
1129 /// <!--LERP--><svg width="400" height="120" font-family="monospace" xmlns="http://www.w3.org/2000/svg"><line x1="40" y1="100" x2="104" y2="84" stroke="green" /><line x1="104" y1="84" x2="200" y2="60" stroke="blue" /><line x1="200" y1="60" x2="360" y2="20" stroke="black" /><circle cx="40" cy="100" r="2" fill="black" /><circle cx="360" cy="20" r="2" fill="black" /><circle cx="104" cy="84" r="2" fill="green" /><circle cx="200" cy="60" r="2" fill="blue" /><text x="20" y="90" fill="black">self</text><text x="345" y="40" fill="black">rhs</text><text x="84" y="104" fill="green">t = 0.2</text><text x="180" y="80" fill="blue">t = 0.5</text></svg>
1130 #[inline]
1131 #[must_use]
1132 pub fn lerp(self, rhs: $vec<T>, t: T) -> $vec<T> {
1133 self + (rhs - self) * t
1134 }
1135 /// Spherical interpolation between the vectors with constant velocity.
1136 ///
1137 /// The result is linear interpolation of the angles between the vectors and their lengths.
1138 ///
1139 /// This is fairly expensive to calculate requiring trigonometric functions.
1140 /// If constant velocity isn't required, see the less expensive [nlerp](#method.nlerp).
1141 ///
1142 /// <!--SLERP--><svg width="400" height="140" font-family="monospace" xmlns="http://www.w3.org/2000/svg"><path fill="none" d="M200 136.33249 L100 70 M108.87775 71.08883 L100 70 L104.45558 77.7555" stroke="black" stroke-width="0.5" /><path fill="none" d="M200 136.33249 L300 70 M295.54443 77.7555 L300 70 L291.12225 71.08883" stroke="black" stroke-width="0.5" /><path fill="none" d="M200 136.33249 L143.25452 30.597214 M150.56206 35.754715 L143.25452 30.597214 L143.51305 39.53775" stroke="green" stroke-width="0.25" /><path fill="none" d="M200 136.33249 L200 16.332481 M204 24.332481 L200 16.332481 L196 24.332481" stroke="green" stroke-width="0.25" /><path fill="none" d="M200 136.33249 L256.74548 30.597221 M256.48697 39.537758 L256.74548 30.597221 L249.43794 35.754723" stroke="green" /><path fill="none" d="M88.950035 90.85828 A120 120 0 0 1 100 70" stroke="black" stroke-width="0.5" /><path fill="none" d="M100 70 A120 120 0 0 1 256.74548 30.597221" stroke="green" /><path fill="none" d="M256.74548 30.597221 A120 120 0 0 1 300 70" stroke="black" /><path fill="none" d="M300 70 A120 120 0 0 1 311.05 90.85829" stroke="black" stroke-width="0.5" /><line x1="100" y1="70" x2="250" y2="70" stroke="blue" stroke-width="0.5" /><circle cx="100" cy="70" r="2" fill="black" /><circle cx="300" cy="70" r="2" fill="black" /><circle cx="250" cy="70" r="2" fill="blue" /><circle cx="256.74548" cy="30.597221" r="2" fill="green" /><text x="98.25452" y="25.597214" fill="green" font-size="10">t = 0.25</text><text x="180" y="11.332481" fill="green" font-size="10">t = 0.50</text><text x="256.74548" y="25.597221" fill="green" font-size="10">t = 0.75</text><text x="230" y="90" fill="blue">lerp</text><text x="196.74548" y="40.59722" fill="green">slerp</text><text x="50" y="70" fill="black">self</text><text x="310" y="70" fill="black">rhs</text></svg>
1143 #[inline]
1144 #[must_use]
1145 pub fn slerp(self, rhs: $vec<T>, t: T) -> $vec<T> where T: Float {
1146 let (v0, len0) = self.normalize_len();
1147 let (v1, len1) = rhs.normalize_len();
1148 let len = len0 + (len1 - len0) * t;
1149
1150 let dot = v0.dot(v1);
1151 let theta = Rad::acos(dot) * t;
1152 let (sin, cos) = theta.sin_cos();
1153
1154 let v2 = (v1 - v0 * dot).normalize();
1155 (v0 * cos + v2 * sin) * len
1156 }
1157 /// Cheap spherical interpolation between the vectors without constant velocity.
1158 ///
1159 /// <!--NLERP--><svg width="400" height="140" font-family="monospace" xmlns="http://www.w3.org/2000/svg"><path fill="none" d="M200 136.33249 L100 70 M108.87775 71.08883 L100 70 L104.45558 77.7555" stroke="black" stroke-width="0.5" /><path fill="none" d="M200 136.33249 L300 70 M295.54443 77.7555 L300 70 L291.12225 71.08883" stroke="black" stroke-width="0.5" /><path fill="none" d="M200 136.33249 L127.768486 40.50657 M135.77812 44.487244 L127.768486 40.50657 L129.38972 49.30268" stroke="green" stroke-width="0.25" /><path fill="none" d="M200 136.33249 L200 16.332497 M204 24.332497 L200 16.332497 L196 24.332497" stroke="green" stroke-width="0.25" /><path fill="none" d="M200 136.33249 L272.2315 40.50657 M270.61026 49.30268 L272.2315 40.50657 L264.2219 44.487244" stroke="green" /><path fill="none" d="M94.97722 78.27897 A120 120 0 0 1 100 70" stroke="black" stroke-width="0.5" /><path fill="none" d="M100 70 A120 120 0 0 1 272.2315 40.50657" stroke="green" /><path fill="none" d="M272.2315 40.50657 A120 120 0 0 1 300 70" stroke="black" /><path fill="none" d="M300 70 A120 120 0 0 1 305.02277 78.27897" stroke="black" stroke-width="0.5" /><line x1="100" y1="70" x2="250" y2="70" stroke="blue" stroke-width="0.5" /><circle cx="100" cy="70" r="2" fill="black" /><circle cx="300" cy="70" r="2" fill="black" /><circle cx="250" cy="70" r="2" fill="blue" /><circle cx="272.2315" cy="40.50657" r="2" fill="green" /><text x="82.768486" y="35.50657" fill="green" font-size="10">t = 0.25</text><text x="180" y="11.332497" fill="green" font-size="10">t = 0.50</text><text x="272.2315" y="35.50657" fill="green" font-size="10">t = 0.75</text><text x="230" y="90" fill="blue">lerp</text><text x="212.2315" y="50.50657" fill="green">nlerp</text><text x="50" y="70" fill="black">self</text><text x="310" y="70" fill="black">rhs</text></svg>
1160 #[inline]
1161 #[must_use]
1162 pub fn nlerp(self, rhs: $vec<T>, t: T) -> $vec<T> where T: Float {
1163 let self_len = self.len();
1164 let rhs_len = rhs.len();
1165 let len = self_len + (rhs_len - self_len) * t;
1166 self.lerp(rhs, t).resize(len)
1167 }
1168 /// Exponential decay smoothing.
1169 ///
1170 /// Also known as lerp smoothing.
1171 /// Useful decay values range from approx 1.0 to 25.0, slow to fast.
1172 ///
1173 /// ```
1174 /// use cvmath::Vec2;
1175 ///
1176 /// struct Entity {
1177 /// pos: Vec2<f32>,
1178 /// target: Vec2<f32>,
1179 /// }
1180 /// impl Entity {
1181 /// fn update(&mut self, dt: f32) {
1182 /// // Smoothly move towards the target.
1183 /// self.pos = self.pos.exp_decay(self.target, 5.0, dt);
1184 /// }
1185 /// }
1186 /// ```
1187 #[inline]
1188 #[must_use]
1189 pub fn exp_decay(self, rhs: $vec<T>, decay: T, dt: T) -> $vec<T> where T: Float {
1190 rhs + (self - rhs) * (-decay * dt).exp()
1191 }
1192 }
1193
1194 // Float ops
1195 impl<T: Float> $vec<T> {
1196 /// Component-wise floor.
1197 #[inline]
1198 #[must_use]
1199 pub fn floor(self) -> $vec<T> {
1200 $vec { $($field: self.$field.floor()),+ }
1201 }
1202 /// Component-wise ceil.
1203 #[inline]
1204 #[must_use]
1205 pub fn ceil(self) -> $vec<T> {
1206 $vec { $($field: self.$field.ceil()),+ }
1207 }
1208 /// Component-wise round.
1209 #[inline]
1210 #[must_use]
1211 pub fn round(self) -> $vec<T> {
1212 $vec { $($field: self.$field.round()),+ }
1213 }
1214 /// Component-wise fract.
1215 #[inline]
1216 #[must_use]
1217 pub fn fract(self) -> $vec<T> {
1218 $vec { $($field: self.$field.fract()),+ }
1219 }
1220 }
1221
1222 //----------------------------------------------------------------
1223 // Operators
1224
1225 impl<T: Extrema> Extrema<$vec<T>> for $vec<T> {
1226 #[inline]
1227 #[must_use]
1228 fn min(self, rhs: $vec<T>) -> $vec<T> {
1229 $vec { $($field: T::min(self.$field, rhs.$field)),+ }
1230 }
1231 #[inline]
1232 #[must_use]
1233 fn max(self, rhs: $vec<T>) -> $vec<T> {
1234 $vec { $($field: T::max(self.$field, rhs.$field)),+ }
1235 }
1236 #[inline]
1237 #[must_use]
1238 fn min_max(self, rhs: $vec<T>) -> ($vec<T>, $vec<T>) {
1239 let temp = $vec { $($field: self.$field.min_max(rhs.$field)),+ };
1240 ($vec { $($field: temp.$field.0),+ }, $vec { $($field: temp.$field.1),+ })
1241 }
1242 }
1243 impl<T: PartialOrd> SpatialOrd<$vec<T>> for $vec<T> {
1244 #[inline] fn spatial_lt(&self, rhs: &$vec<T>) -> bool { $(self.$field < rhs.$field &&)+ true }
1245 #[inline] fn spatial_le(&self, rhs: &$vec<T>) -> bool { $(self.$field <= rhs.$field &&)+ true }
1246 #[inline] fn spatial_gt(&self, rhs: &$vec<T>) -> bool { $(self.$field > rhs.$field &&)+ true }
1247 #[inline] fn spatial_ge(&self, rhs: &$vec<T>) -> bool { $(self.$field >= rhs.$field &&)+ true }
1248 }
1249
1250 // Vector addition, subtraction and negation
1251 impl<U, T: ops::Add<U>> ops::Add<$vec<U>> for $vec<T> {
1252 type Output = $vec<T::Output>;
1253 #[inline]
1254 fn add(self, rhs: $vec<U>) -> $vec<T::Output> {
1255 $vec { $($field: self.$field + rhs.$field),+ }
1256 }
1257 }
1258 impl<U, T: ops::Sub<U>> ops::Sub<$vec<U>> for $vec<T> {
1259 type Output = $vec<T::Output>;
1260 #[inline]
1261 fn sub(self, rhs: $vec<U>) -> $vec<T::Output> {
1262 $vec { $($field: self.$field - rhs.$field),+ }
1263 }
1264 }
1265 impl<T: ops::Neg> ops::Neg for $vec<T> {
1266 type Output = $vec<T::Output>;
1267 #[inline]
1268 fn neg(self) -> $vec<T::Output> {
1269 $vec { $($field: -self.$field),+ }
1270 }
1271 }
1272 impl<U, T: ops::AddAssign<U>> ops::AddAssign<$vec<U>> for $vec<T> {
1273 #[inline]
1274 fn add_assign(&mut self, rhs: $vec<U>) {
1275 $(self.$field += rhs.$field;)+
1276 }
1277 }
1278 impl<U, T: ops::SubAssign<U>> ops::SubAssign<$vec<U>> for $vec<T> {
1279 #[inline]
1280 fn sub_assign(&mut self, rhs: $vec<U>) {
1281 $(self.$field -= rhs.$field;)+
1282 }
1283 }
1284
1285 // Vector addition, subtraction and negation (tuple)
1286 impl<U, T: ops::Add<U>> ops::Add<($($U,)+)> for $vec<T> {
1287 type Output = $vec<T::Output>;
1288 #[inline]
1289 fn add(self, rhs: ($($U,)+)) -> $vec<T::Output> {
1290 $vec { $($field: self.$field + rhs.$I),+ }
1291 }
1292 }
1293 impl<U, T: ops::Sub<U>> ops::Sub<($($U,)+)> for $vec<T> {
1294 type Output = $vec<T::Output>;
1295 #[inline]
1296 fn sub(self, rhs: ($($U,)+)) -> $vec<T::Output> {
1297 $vec { $($field: self.$field - rhs.$I),+ }
1298 }
1299 }
1300 impl<U, T: ops::AddAssign<U>> ops::AddAssign<($($U,)+)> for $vec<T> {
1301 #[inline]
1302 fn add_assign(&mut self, rhs: ($($U,)+)) {
1303 $(self.$field += rhs.$I;)+
1304 }
1305 }
1306 impl<U, T: ops::SubAssign<U>> ops::SubAssign<($($U,)+)> for $vec<T> {
1307 #[inline]
1308 fn sub_assign(&mut self, rhs: ($($U,)+)) {
1309 $(self.$field -= rhs.$I;)+
1310 }
1311 }
1312
1313 // Scalar multiplication, division and remainder
1314 impl<U: Scalar, T: ops::Mul<U>> ops::Mul<U> for $vec<T> {
1315 type Output = $vec<T::Output>;
1316 #[inline]
1317 fn mul(self, rhs: U) -> $vec<T::Output> {
1318 $vec { $($field: self.$field * rhs),+ }
1319 }
1320 }
1321 impl<U: Scalar, T: ops::Div<U>> ops::Div<U> for $vec<T> {
1322 type Output = $vec<T::Output>;
1323 #[inline]
1324 fn div(self, rhs: U) -> $vec<T::Output> {
1325 $vec { $($field: self.$field / rhs),+ }
1326 }
1327 }
1328 impl<U: Scalar, T: ops::Rem<U>> ops::Rem<U> for $vec<T> {
1329 type Output = $vec<T::Output>;
1330 #[inline]
1331 fn rem(self, rhs: U) -> $vec<T::Output> {
1332 $vec { $($field: self.$field % rhs),+ }
1333 }
1334 }
1335 impl<U: Scalar, T: ops::MulAssign<U>> ops::MulAssign<U> for $vec<T> {
1336 #[inline]
1337 fn mul_assign(&mut self, rhs: U) {
1338 $(self.$field *= rhs;)+
1339 }
1340 }
1341 impl<U: Scalar, T: ops::DivAssign<U>> ops::DivAssign<U> for $vec<T> {
1342 #[inline]
1343 fn div_assign(&mut self, rhs: U) {
1344 $(self.$field /= rhs;)+
1345 }
1346 }
1347 impl<U: Scalar, T: ops::RemAssign<U>> ops::RemAssign<U> for $vec<T> {
1348 #[inline]
1349 fn rem_assign(&mut self, rhs: U) {
1350 $(self.$field %= rhs;)+
1351 }
1352 }
1353
1354 // Vector multiplication, division and remainder
1355 impl<U, T: ops::Mul<U>> ops::Mul<$vec<U>> for $vec<T> {
1356 type Output = $vec<T::Output>;
1357 #[inline]
1358 fn mul(self, rhs: $vec<U>) -> $vec<T::Output> {
1359 $vec { $($field: self.$field * rhs.$field),+ }
1360 }
1361 }
1362 impl<U, T: ops::Div<U>> ops::Div<$vec<U>> for $vec<T> {
1363 type Output = $vec<T::Output>;
1364 #[inline]
1365 fn div(self, rhs: $vec<U>) -> $vec<T::Output> {
1366 $vec { $($field: self.$field / rhs.$field),+ }
1367 }
1368 }
1369 impl<U, T: ops::Rem<U>> ops::Rem<$vec<U>> for $vec<T> {
1370 type Output = $vec<T::Output>;
1371 #[inline]
1372 fn rem(self, rhs: $vec<U>) -> $vec<T::Output> {
1373 $vec { $($field: self.$field % rhs.$field),+ }
1374 }
1375 }
1376 impl<U, T: ops::MulAssign<U>> ops::MulAssign<$vec<U>> for $vec<T> {
1377 #[inline]
1378 fn mul_assign(&mut self, rhs: $vec<U>) {
1379 $(self.$field *= rhs.$field;)+
1380 }
1381 }
1382 impl<U, T: ops::DivAssign<U>> ops::DivAssign<$vec<U>> for $vec<T> {
1383 #[inline]
1384 fn div_assign(&mut self, rhs: $vec<U>) {
1385 $(self.$field /= rhs.$field;)+
1386 }
1387 }
1388 impl<U, T: ops::RemAssign<U>> ops::RemAssign<$vec<U>> for $vec<T> {
1389 #[inline]
1390 fn rem_assign(&mut self, rhs: $vec<U>) {
1391 $(self.$field %= rhs.$field;)+
1392 }
1393 }
1394
1395 // Vector multiplication, division and remainder (tuple)
1396 impl<U, T: ops::Mul<U>> ops::Mul<($($U,)+)> for $vec<T> {
1397 type Output = $vec<T::Output>;
1398 #[inline]
1399 fn mul(self, rhs: ($($U,)+)) -> $vec<T::Output> {
1400 $vec { $($field: self.$field * rhs.$I),+ }
1401 }
1402 }
1403 impl<U, T: ops::Div<U>> ops::Div<($($U,)+)> for $vec<T> {
1404 type Output = $vec<T::Output>;
1405 #[inline]
1406 fn div(self, rhs: ($($U,)+)) -> $vec<T::Output> {
1407 $vec { $($field: self.$field / rhs.$I),+ }
1408 }
1409 }
1410 impl<U, T: ops::Rem<U>> ops::Rem<($($U,)+)> for $vec<T> {
1411 type Output = $vec<T::Output>;
1412 #[inline]
1413 fn rem(self, rhs: ($($U,)+)) -> $vec<T::Output> {
1414 $vec { $($field: self.$field % rhs.$I),+ }
1415 }
1416 }
1417 impl<U, T: ops::MulAssign<U>> ops::MulAssign<($($U,)+)> for $vec<T> {
1418 #[inline]
1419 fn mul_assign(&mut self, rhs: ($($U,)+)) {
1420 $(self.$field *= rhs.$I;)+
1421 }
1422 }
1423 impl<U, T: ops::DivAssign<U>> ops::DivAssign<($($U,)+)> for $vec<T> {
1424 #[inline]
1425 fn div_assign(&mut self, rhs: ($($U,)+)) {
1426 $(self.$field /= rhs.$I;)+
1427 }
1428 }
1429 impl<U, T: ops::RemAssign<U>> ops::RemAssign<($($U,)+)> for $vec<T> {
1430 #[inline]
1431 fn rem_assign(&mut self, rhs: ($($U,)+)) {
1432 $(self.$field %= rhs.$I;)+
1433 }
1434 }
1435
1436 //----------------------------------------------------------------
1437 // Formatting
1438
1439 fmt!($vec { $($field),+ });
1440
1441 //----------------------------------------------------------------
1442 // Parsing
1443
1444 impl<T: FromStr> FromStr for $vec<T> {
1445 type Err = ParseVecError<T::Err>;
1446 fn from_str(s: &str) -> Result<$vec<T>, Self::Err> {
1447 let bytes = s.as_bytes();
1448 // Must be surrounded by parenthesis
1449 if bytes.len() < 2 || bytes[0] != b'(' || bytes[bytes.len() - 1] != b')' {
1450 return Err(ParseVecError::SyntaxError);
1451 }
1452 // Comma separated list of values
1453 let mut iter = s.bytes().enumerate().filter_map(|(i, v)| if v == b',' { Some(i) } else { None });
1454 let mut next = 1;
1455 $(let $field;)+
1456 parse_vec_elems!(s, iter, next; $($field),+);
1457 Ok($vec { $($field),+ })
1458 }
1459 }
1460 }
1461}
1462
1463// vec!(Vec1 1 { x 0 T U X });
1464vec!(Vec2 2 { x 0 T U X, y 1 T U Y } {
1465 /// Calculates the polar angle.
1466 ///
1467 /// <!--POLAR_ANGLE-->
1468 ///
1469 /// ```
1470 /// use cvmath::{Rad, Vec2};
1471 ///
1472 /// let this = Vec2 { x: 1.0, y: 1.0 };
1473 /// assert_eq!(Rad::eight(), this.polar_angle());
1474 /// ```
1475 #[inline]
1476 pub fn polar_angle(self) -> Rad<T> where T: Float {
1477 Rad::atan2(self.y, self.x)
1478 }
1479 /// Rotates the vector counter-clockwise by 90°.
1480 ///
1481 /// The resulting vector is perpendicular to the given vector.
1482 ///
1483 /// ```
1484 /// use cvmath::Vec2;
1485 ///
1486 /// let this = Vec2 { x: 3.0, y: 4.0 };
1487 /// assert_eq!(Vec2(4.0, -3.0), this.ccw());
1488 /// ```
1489 #[inline]
1490 pub fn ccw(self) -> Vec2<T> {
1491 Vec2 { x: self.y, y: -self.x }
1492 }
1493 /// Rotates the vector clockwise by 90°.
1494 ///
1495 /// The resulting vector is perpendicular to the given vector.
1496 ///
1497 /// ```
1498 /// use cvmath::Vec2;
1499 ///
1500 /// let this = Vec2 { x: 3.0, y: 4.0 };
1501 /// assert_eq!(Vec2(-4.0, 3.0), this.cw());
1502 /// ```
1503 #[inline]
1504 pub fn cw(self) -> Vec2<T> {
1505 Vec2 { x: -self.y, y: self.x }
1506 }
1507 /// Calculates the magnitude of the 3D cross product where the inputs are extended with `z = 0`.
1508 ///
1509 /// This result is equal to the area of the parallelogram between the two vectors.
1510 /// This result is equal to twice the area of the triangle between the two vectors.
1511 ///
1512 /// Furthermore this area is signed; a positive value means the `rhs` is on the left side of `self` and a negative value means `rhs` is on the right side.
1513 ///
1514 /// <!--CROSS_2D-->
1515 ///
1516 /// ```
1517 /// use cvmath::Vec2;
1518 ///
1519 /// let lhs = Vec2 { x: -3, y: -4 };
1520 /// let rhs = Vec2 { x: -1, y: 2 };
1521 /// assert_eq!(-10, lhs.cross(rhs));
1522 /// // Area under the parallelogram defined by (origin, lhs, rhs, lhs + rhs) equals 10
1523 /// // Area under the triangle defined by (origin, lhs, rhs) equals 5
1524 /// ```
1525 #[inline]
1526 pub fn cross(self, rhs: Vec2<T>) -> T {
1527 self.x * rhs.y - self.y * rhs.x
1528 }
1529 /// Horizontal subtracts the components.
1530 ///
1531 /// ```
1532 /// use cvmath::Vec2;
1533 ///
1534 /// let this = Vec2 { x: 3, y: 4 };
1535 /// assert_eq!(-1, this.hsub());
1536 /// ```
1537 #[inline]
1538 pub fn hsub(self) -> T {
1539 self.x - self.y
1540 }
1541 /// Intercepts the vector with `x = constant` returning the y.
1542 #[inline]
1543 pub fn y_intercept(self, x: T) -> Option<T> {
1544 if self.x != T::ZERO {
1545 Some((self.y * x) / self.x)
1546 }
1547 else {
1548 None
1549 }
1550 }
1551 /// Intercepts the vector with `y = constant` returning the x.
1552 #[inline]
1553 pub fn x_intercept(self, y: T) -> Option<T> {
1554 if self.y != T::ZERO {
1555 Some((y * self.x) / self.y)
1556 }
1557 else {
1558 None
1559 }
1560 }
1561});
1562vec!(Vec3 3 { x 0 T U X, y 1 T U Y, z 2 T U Z } {
1563 /// Calculates the 3D cross product.
1564 ///
1565 /// Effectively calculates the vector perpendicular to both inputs with direction according to the [right-hand rule](https://en.wikipedia.org/wiki/Right-hand_rule).
1566 ///
1567 /// <!--CROSS_3D-->
1568 ///
1569 /// ```
1570 /// use cvmath::Vec3;
1571 ///
1572 /// let lhs = Vec3 { x: 3, y: -3, z: 1 };
1573 /// let rhs = Vec3 { x: 4, y: 9, z: 1 };
1574 /// assert_eq!(Vec3(-12, 1, 39), lhs.cross(rhs));
1575 /// ```
1576 #[inline]
1577 pub fn cross(self, rhs: Vec3<T>) -> Vec3<T> {
1578 Vec3 {
1579 x: self.y * rhs.z - self.z * rhs.y,
1580 y: self.z * rhs.x - self.x * rhs.z,
1581 z: self.x * rhs.y - self.y * rhs.x,
1582 }
1583 }
1584 /// Homogeneous divide.
1585 #[inline]
1586 pub fn hdiv(self) -> Vec2<T> {
1587 if self.z != T::ZERO {
1588 Vec2 {
1589 x: self.x / self.z,
1590 y: self.x / self.z,
1591 }
1592 }
1593 else { self.xy() }
1594 }
1595});
1596vec!(Vec4 4 { x 0 T U X, y 1 T U Y, z 2 T U Z, w 3 T U W } {
1597 /// Homogeneous divide.
1598 #[inline]
1599 pub fn hdiv(self) -> Vec3<T> {
1600 if self.w != T::ZERO {
1601 let inv_w = T::ONE / self.w;
1602 Vec3 {
1603 x: self.x * inv_w,
1604 y: self.y * inv_w,
1605 z: self.z * inv_w,
1606 }
1607 }
1608 else { self.xyz() }
1609 }
1610});
1611
1612specialized_type!(Vec2, Vec2f, f32, x, y);
1613specialized_type!(Vec3, Vec3f, f32, x, y, z);
1614specialized_type!(Vec4, Vec4f, f32, x, y, z, w);
1615
1616specialized_type!(Vec2, Vec2d, f64, x, y);
1617specialized_type!(Vec3, Vec3d, f64, x, y, z);
1618specialized_type!(Vec4, Vec4d, f64, x, y, z, w);
1619
1620specialized_type!(Vec2, Vec2i, i32, x, y);
1621specialized_type!(Vec3, Vec3i, i32, x, y, z);
1622specialized_type!(Vec4, Vec4i, i32, x, y, z, w);
1623
1624//----------------------------------------------------------------
1625
1626#[cfg(feature = "serde")]
1627impl<T: serde::Serialize> serde::Serialize for Vec2<T> {
1628 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> where S: serde::Serializer {
1629 let slice = <Vec2<T> as AsRef<[T; 2]>>::as_ref(self).as_slice();
1630 serializer.collect_seq(slice)
1631 }
1632}
1633
1634#[cfg(feature = "serde")]
1635impl<T: serde::Serialize> serde::Serialize for Vec3<T> {
1636 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> where S: serde::Serializer {
1637 let slice = <Vec3<T> as AsRef<[T; 3]>>::as_ref(self).as_slice();
1638 serializer.collect_seq(slice)
1639 }
1640}
1641
1642#[cfg(feature = "serde")]
1643impl<T: serde::Serialize> serde::Serialize for Vec4<T> {
1644 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> where S: serde::Serializer {
1645 let slice = <Vec4<T> as AsRef<[T; 4]>>::as_ref(self).as_slice();
1646 serializer.collect_seq(slice)
1647 }
1648}
1649
1650#[cfg(feature = "serde")]
1651impl<'de, T: serde::Deserialize<'de>> serde::Deserialize<'de> for Vec2<T> {
1652 fn deserialize<D>(deserializer: D) -> Result<Vec2<T>, D::Error> where D: serde::Deserializer<'de> {
1653 let [x, y] = <[T; 2]>::deserialize(deserializer)?;
1654 Ok(Vec2 { x, y })
1655 }
1656}
1657
1658#[cfg(feature = "serde")]
1659impl<'de, T: serde::Deserialize<'de>> serde::Deserialize<'de> for Vec3<T> {
1660 fn deserialize<D>(deserializer: D) -> Result<Vec3<T>, D::Error> where D: serde::Deserializer<'de> {
1661 let [x, y, z] = <[T; 3]>::deserialize(deserializer)?;
1662 Ok(Vec3 { x, y, z })
1663 }
1664}
1665
1666#[cfg(feature = "serde")]
1667impl<'de, T: serde::Deserialize<'de>> serde::Deserialize<'de> for Vec4<T> {
1668 fn deserialize<D>(deserializer: D) -> Result<Vec4<T>, D::Error> where D: serde::Deserializer<'de> {
1669 let [x, y, z, w] = <[T; 4]>::deserialize(deserializer)?;
1670 Ok(Vec4 { x, y, z, w })
1671 }
1672}
1673
1674//----------------------------------------------------------------
1675
1676use std::str::FromStr;
1677use std::error::Error;
1678
1679/// An error which can be returned when parsing a vec.
1680#[derive(Copy, Clone, Debug, Eq, PartialEq)]
1681pub enum ParseVecError<E> {
1682 /// Missing parentheses surrounding the vector elements.
1683 SyntaxError,
1684 /// The number of vector elements doesn't match the vector dimensions.
1685 DimMismatch,
1686 /// Error parsing the vector elements.
1687 ParseValue(E),
1688}
1689impl<E> From<E> for ParseVecError<E> {
1690 #[inline]
1691 fn from(err: E) -> ParseVecError<E> {
1692 ParseVecError::ParseValue(err)
1693 }
1694}
1695impl<E: Error + 'static> fmt::Display for ParseVecError<E> {
1696 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1697 #[allow(deprecated)]
1698 self.description().fmt(f)
1699 }
1700}
1701impl<E: Error + 'static> Error for ParseVecError<E> {
1702 fn description(&self) -> &str {
1703 #[allow(deprecated)]
1704 match *self {
1705 ParseVecError::SyntaxError => "syntax error",
1706 ParseVecError::DimMismatch => "dim mismatch",
1707 ParseVecError::ParseValue(ref inner) => inner.description(),
1708 }
1709 }
1710 fn source(&self) -> Option<&(dyn Error + 'static)> {
1711 match *self {
1712 ParseVecError::SyntaxError => None,
1713 ParseVecError::DimMismatch => None,
1714 ParseVecError::ParseValue(ref inner) => Some(inner),
1715 }
1716 }
1717}