2014-05-26 17:10:04 +00:00
|
|
|
// Copyright 2013-2014 The CGMath Developers. For a full listing of the authors,
|
2015-03-14 02:49:46 +00:00
|
|
|
// refer to the Cargo.toml file at the top-level directory of this distribution.
|
2013-09-03 03:54:03 +00:00
|
|
|
//
|
|
|
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
|
|
// you may not use this file except in compliance with the License.
|
|
|
|
// You may obtain a copy of the License at
|
|
|
|
//
|
|
|
|
// http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
//
|
|
|
|
// Unless required by applicable law or agreed to in writing, software
|
|
|
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
|
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
|
|
// See the License for the specific language governing permissions and
|
|
|
|
// limitations under the License.
|
|
|
|
|
2020-08-12 03:04:27 +00:00
|
|
|
use num_traits::{Bounded, Float, NumCast};
|
2019-05-02 09:24:50 +00:00
|
|
|
#[cfg(feature = "rand")]
|
|
|
|
use rand::{
|
|
|
|
distributions::{Distribution, Standard},
|
2019-11-05 06:16:38 +00:00
|
|
|
Rng,
|
2019-05-02 09:24:50 +00:00
|
|
|
};
|
2013-10-19 14:00:44 +00:00
|
|
|
use std::fmt;
|
2017-04-24 23:54:30 +00:00
|
|
|
use std::iter;
|
2014-05-28 01:59:03 +00:00
|
|
|
use std::mem;
|
2015-01-03 21:29:26 +00:00
|
|
|
use std::ops::*;
|
2013-09-03 03:54:03 +00:00
|
|
|
|
2016-04-19 10:51:40 +00:00
|
|
|
use structure::*;
|
2015-04-05 01:19:11 +00:00
|
|
|
|
2016-04-19 10:51:40 +00:00
|
|
|
use angle::Rad;
|
2018-05-23 11:43:52 +00:00
|
|
|
use approx;
|
2018-01-03 02:01:02 +00:00
|
|
|
use num::{BaseFloat, BaseNum};
|
2013-09-03 03:54:03 +00:00
|
|
|
|
2017-06-06 22:07:38 +00:00
|
|
|
#[cfg(feature = "mint")]
|
|
|
|
use mint;
|
|
|
|
|
2016-04-24 22:59:33 +00:00
|
|
|
/// A 1-dimensional vector.
|
|
|
|
///
|
2016-08-25 13:41:39 +00:00
|
|
|
/// This type is marked as `#[repr(C)]`.
|
|
|
|
#[repr(C)]
|
2016-05-15 12:48:57 +00:00
|
|
|
#[derive(PartialEq, Eq, Copy, Clone, Hash)]
|
2017-06-06 20:48:55 +00:00
|
|
|
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
2016-04-24 22:59:33 +00:00
|
|
|
pub struct Vector1<S> {
|
|
|
|
/// The x component of the vector.
|
|
|
|
pub x: S,
|
|
|
|
}
|
|
|
|
|
2016-03-25 01:34:12 +00:00
|
|
|
/// A 2-dimensional vector.
|
|
|
|
///
|
2016-08-25 13:41:39 +00:00
|
|
|
/// This type is marked as `#[repr(C)]`.
|
|
|
|
#[repr(C)]
|
2016-05-15 12:48:57 +00:00
|
|
|
#[derive(PartialEq, Eq, Copy, Clone, Hash)]
|
2017-06-06 20:48:55 +00:00
|
|
|
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
2016-03-25 01:34:12 +00:00
|
|
|
pub struct Vector2<S> {
|
2016-04-04 22:52:27 +00:00
|
|
|
/// The x component of the vector.
|
2016-03-25 01:34:12 +00:00
|
|
|
pub x: S,
|
2016-04-04 22:52:27 +00:00
|
|
|
/// The y component of the vector.
|
2016-03-25 01:34:12 +00:00
|
|
|
pub y: S,
|
|
|
|
}
|
|
|
|
|
|
|
|
/// A 3-dimensional vector.
|
|
|
|
///
|
2016-08-25 13:41:39 +00:00
|
|
|
/// This type is marked as `#[repr(C)]`.
|
|
|
|
#[repr(C)]
|
2016-05-15 12:48:57 +00:00
|
|
|
#[derive(PartialEq, Eq, Copy, Clone, Hash)]
|
2017-06-06 20:48:55 +00:00
|
|
|
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
2016-03-25 01:34:12 +00:00
|
|
|
pub struct Vector3<S> {
|
2016-04-04 22:52:27 +00:00
|
|
|
/// The x component of the vector.
|
2016-03-25 01:34:12 +00:00
|
|
|
pub x: S,
|
2016-04-04 22:52:27 +00:00
|
|
|
/// The y component of the vector.
|
2016-03-25 01:34:12 +00:00
|
|
|
pub y: S,
|
2016-04-04 22:52:27 +00:00
|
|
|
/// The z component of the vector.
|
2016-03-25 01:34:12 +00:00
|
|
|
pub z: S,
|
|
|
|
}
|
|
|
|
|
|
|
|
/// A 4-dimensional vector.
|
|
|
|
///
|
2016-08-25 13:41:39 +00:00
|
|
|
/// This type is marked as `#[repr(C)]`.
|
|
|
|
#[repr(C)]
|
2016-05-15 12:48:57 +00:00
|
|
|
#[derive(PartialEq, Eq, Copy, Clone, Hash)]
|
2017-06-06 20:48:55 +00:00
|
|
|
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
2016-03-25 01:34:12 +00:00
|
|
|
pub struct Vector4<S> {
|
2016-04-04 22:52:27 +00:00
|
|
|
/// The x component of the vector.
|
2016-03-25 01:34:12 +00:00
|
|
|
pub x: S,
|
2016-04-04 22:52:27 +00:00
|
|
|
/// The y component of the vector.
|
2016-03-25 01:34:12 +00:00
|
|
|
pub y: S,
|
2016-04-04 22:52:27 +00:00
|
|
|
/// The z component of the vector.
|
2016-03-25 01:34:12 +00:00
|
|
|
pub z: S,
|
2016-04-04 22:52:27 +00:00
|
|
|
/// The w component of the vector.
|
2016-03-25 01:34:12 +00:00
|
|
|
pub w: S,
|
|
|
|
}
|
|
|
|
|
2014-01-23 16:13:53 +00:00
|
|
|
// Utility macro for generating associated functions for the vectors
|
2015-12-12 11:17:03 +00:00
|
|
|
macro_rules! impl_vector {
|
2016-04-23 09:52:37 +00:00
|
|
|
($VectorN:ident { $($field:ident),+ }, $n:expr, $constructor:ident) => {
|
|
|
|
impl<S> $VectorN<S> {
|
2014-05-25 09:43:51 +00:00
|
|
|
/// Construct a new vector, using the provided values.
|
2014-01-23 16:13:53 +00:00
|
|
|
#[inline]
|
2019-01-12 22:50:34 +00:00
|
|
|
pub const fn new($($field: S),+) -> $VectorN<S> {
|
2021-06-14 23:49:37 +00:00
|
|
|
$VectorN { $($field),+ }
|
2014-01-23 16:13:53 +00:00
|
|
|
}
|
2018-01-21 04:54:59 +00:00
|
|
|
|
2018-03-16 20:32:46 +00:00
|
|
|
/// Perform the given operation on each field in the vector, returning a new point
|
|
|
|
/// constructed from the operations.
|
2018-01-21 04:54:59 +00:00
|
|
|
#[inline]
|
|
|
|
pub fn map<U, F>(self, mut f: F) -> $VectorN<U>
|
|
|
|
where F: FnMut(S) -> U
|
|
|
|
{
|
|
|
|
$VectorN { $($field: f(self.$field)),+ }
|
|
|
|
}
|
2019-06-10 08:48:28 +00:00
|
|
|
|
|
|
|
/// Construct a new vector where each component is the result of
|
|
|
|
/// applying the given operation to each pair of components of the
|
|
|
|
/// given vectors.
|
|
|
|
#[inline]
|
|
|
|
pub fn zip<S2, S3, F>(self, v2: $VectorN<S2>, mut f: F) -> $VectorN<S3>
|
|
|
|
where F: FnMut(S, S2) -> S3
|
|
|
|
{
|
|
|
|
$VectorN { $($field: f(self.$field, v2.$field)),+ }
|
|
|
|
}
|
2014-05-28 01:59:03 +00:00
|
|
|
}
|
2014-01-23 16:13:53 +00:00
|
|
|
|
2015-02-06 05:16:22 +00:00
|
|
|
/// The short constructor.
|
|
|
|
#[inline]
|
2019-01-12 22:50:34 +00:00
|
|
|
pub const fn $constructor<S>($($field: S),+) -> $VectorN<S> {
|
2015-10-02 04:54:33 +00:00
|
|
|
$VectorN::new($($field),+)
|
2015-02-06 05:16:22 +00:00
|
|
|
}
|
|
|
|
|
2016-04-23 09:52:37 +00:00
|
|
|
impl<S: NumCast + Copy> $VectorN<S> {
|
2017-03-20 23:06:06 +00:00
|
|
|
/// Component-wise casting to another type.
|
2014-11-20 14:24:38 +00:00
|
|
|
#[inline]
|
2017-08-16 20:21:51 +00:00
|
|
|
pub fn cast<T: NumCast>(&self) -> Option<$VectorN<T>> {
|
|
|
|
$(
|
|
|
|
let $field = match NumCast::from(self.$field) {
|
|
|
|
Some(field) => field,
|
|
|
|
None => return None
|
|
|
|
};
|
|
|
|
)+
|
|
|
|
Some($VectorN { $($field),+ })
|
2014-11-20 14:24:38 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-06-03 03:38:50 +00:00
|
|
|
impl<S: BaseNum> MetricSpace for $VectorN<S> {
|
2016-04-23 09:52:37 +00:00
|
|
|
type Metric = S;
|
|
|
|
|
|
|
|
#[inline]
|
|
|
|
fn distance2(self, other: Self) -> S {
|
|
|
|
(other - self).magnitude2()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-11-14 10:58:11 +00:00
|
|
|
impl<S: Copy> Array for $VectorN<S> {
|
2015-11-03 03:15:11 +00:00
|
|
|
type Element = S;
|
2015-11-14 01:03:12 +00:00
|
|
|
|
2017-07-31 20:13:15 +00:00
|
|
|
#[inline]
|
|
|
|
fn len() -> usize {
|
|
|
|
$n
|
|
|
|
}
|
|
|
|
|
2016-04-04 09:53:55 +00:00
|
|
|
#[inline]
|
|
|
|
fn from_value(scalar: S) -> $VectorN<S> {
|
|
|
|
$VectorN { $($field: scalar),+ }
|
|
|
|
}
|
|
|
|
|
|
|
|
#[inline]
|
|
|
|
fn sum(self) -> S where S: Add<Output = S> {
|
2021-04-06 14:06:21 +00:00
|
|
|
fold_array!(add, $(self.$field),+ )
|
2016-04-04 09:53:55 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
#[inline]
|
|
|
|
fn product(self) -> S where S: Mul<Output = S> {
|
2021-04-06 14:06:21 +00:00
|
|
|
fold_array!(mul, $(self.$field),+ )
|
2016-04-04 09:53:55 +00:00
|
|
|
}
|
2018-04-29 13:21:42 +00:00
|
|
|
|
2020-05-21 19:06:34 +00:00
|
|
|
fn is_finite(&self) -> bool where S: Float {
|
2018-04-29 13:21:42 +00:00
|
|
|
$(self.$field.is_finite())&&+
|
|
|
|
}
|
2015-11-03 03:15:11 +00:00
|
|
|
}
|
2014-05-28 01:59:03 +00:00
|
|
|
|
2016-04-25 05:10:53 +00:00
|
|
|
impl<S: BaseNum> Zero for $VectorN<S> {
|
|
|
|
#[inline]
|
|
|
|
fn zero() -> $VectorN<S> {
|
|
|
|
$VectorN::from_value(S::zero())
|
|
|
|
}
|
2015-11-03 03:30:59 +00:00
|
|
|
|
2016-04-04 09:45:54 +00:00
|
|
|
#[inline]
|
2016-04-25 05:10:53 +00:00
|
|
|
fn is_zero(&self) -> bool {
|
|
|
|
*self == $VectorN::zero()
|
2016-04-04 09:45:54 +00:00
|
|
|
}
|
2014-05-28 01:59:03 +00:00
|
|
|
}
|
|
|
|
|
2017-04-26 11:02:05 +00:00
|
|
|
impl<S: BaseNum> iter::Sum<$VectorN<S>> for $VectorN<S> {
|
2017-04-24 23:54:30 +00:00
|
|
|
#[inline]
|
2017-04-26 11:02:05 +00:00
|
|
|
fn sum<I: Iterator<Item=$VectorN<S>>>(iter: I) -> $VectorN<S> {
|
|
|
|
iter.fold($VectorN::zero(), Add::add)
|
2017-04-24 23:54:30 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-04-26 11:02:05 +00:00
|
|
|
impl<'a, S: 'a + BaseNum> iter::Sum<&'a $VectorN<S>> for $VectorN<S> {
|
2017-04-24 23:54:30 +00:00
|
|
|
#[inline]
|
2017-04-26 11:02:05 +00:00
|
|
|
fn sum<I: Iterator<Item=&'a $VectorN<S>>>(iter: I) -> $VectorN<S> {
|
|
|
|
iter.fold($VectorN::zero(), Add::add)
|
2017-04-24 23:54:30 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-04-25 05:10:53 +00:00
|
|
|
impl<S: BaseNum> VectorSpace for $VectorN<S> {
|
|
|
|
type Scalar = S;
|
|
|
|
}
|
|
|
|
|
2015-10-02 04:54:33 +00:00
|
|
|
impl<S: Neg<Output = S>> Neg for $VectorN<S> {
|
|
|
|
type Output = $VectorN<S>;
|
2015-01-05 01:56:01 +00:00
|
|
|
|
|
|
|
#[inline]
|
2019-09-01 14:16:04 +00:00
|
|
|
default_fn!( neg(self) -> $VectorN<S> { $VectorN::new($(-self.$field),+) } );
|
2014-01-23 16:13:53 +00:00
|
|
|
}
|
2013-09-06 06:53:37 +00:00
|
|
|
|
2018-05-23 11:43:52 +00:00
|
|
|
impl<S: BaseFloat> approx::AbsDiffEq for $VectorN<S> {
|
2016-08-22 15:21:22 +00:00
|
|
|
type Epsilon = S::Epsilon;
|
2015-11-03 03:00:39 +00:00
|
|
|
|
2015-01-05 01:56:01 +00:00
|
|
|
#[inline]
|
2016-08-22 15:21:22 +00:00
|
|
|
fn default_epsilon() -> S::Epsilon {
|
|
|
|
S::default_epsilon()
|
|
|
|
}
|
|
|
|
|
|
|
|
#[inline]
|
2018-05-23 11:43:52 +00:00
|
|
|
fn abs_diff_eq(&self, other: &Self, epsilon: S::Epsilon) -> bool {
|
|
|
|
$(S::abs_diff_eq(&self.$field, &other.$field, epsilon))&&+
|
2016-08-22 15:21:22 +00:00
|
|
|
}
|
2018-05-23 11:43:52 +00:00
|
|
|
}
|
2016-08-22 15:21:22 +00:00
|
|
|
|
2018-05-23 11:43:52 +00:00
|
|
|
impl<S: BaseFloat> approx::RelativeEq for $VectorN<S> {
|
2016-08-22 15:21:22 +00:00
|
|
|
#[inline]
|
2018-05-23 11:43:52 +00:00
|
|
|
fn default_max_relative() -> S::Epsilon {
|
|
|
|
S::default_max_relative()
|
2016-08-22 15:21:22 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
#[inline]
|
|
|
|
fn relative_eq(&self, other: &Self, epsilon: S::Epsilon, max_relative: S::Epsilon) -> bool {
|
|
|
|
$(S::relative_eq(&self.$field, &other.$field, epsilon, max_relative))&&+
|
|
|
|
}
|
2018-05-23 11:43:52 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
impl<S: BaseFloat> approx::UlpsEq for $VectorN<S> {
|
|
|
|
#[inline]
|
|
|
|
fn default_max_ulps() -> u32 {
|
|
|
|
S::default_max_ulps()
|
|
|
|
}
|
2016-08-22 15:21:22 +00:00
|
|
|
|
|
|
|
#[inline]
|
|
|
|
fn ulps_eq(&self, other: &Self, epsilon: S::Epsilon, max_ulps: u32) -> bool {
|
|
|
|
$(S::ulps_eq(&self.$field, &other.$field, epsilon, max_ulps))&&+
|
2015-09-30 07:37:52 +00:00
|
|
|
}
|
2014-01-23 16:13:53 +00:00
|
|
|
}
|
2013-09-06 06:39:15 +00:00
|
|
|
|
2019-05-02 09:24:50 +00:00
|
|
|
#[cfg(feature = "rand")]
|
2018-06-08 11:39:02 +00:00
|
|
|
impl<S> Distribution<$VectorN<S>> for Standard
|
|
|
|
where Standard: Distribution<S>,
|
2021-07-25 13:22:06 +00:00
|
|
|
S: BaseNum {
|
2015-01-05 01:56:01 +00:00
|
|
|
#[inline]
|
2018-06-08 11:39:02 +00:00
|
|
|
fn sample<R: Rng + ?Sized>(&self, rng: &mut R) -> $VectorN<S> {
|
2015-10-02 04:54:33 +00:00
|
|
|
$VectorN { $($field: rng.gen()),+ }
|
2015-09-30 07:37:52 +00:00
|
|
|
}
|
2014-07-29 05:21:58 +00:00
|
|
|
}
|
2015-09-20 15:32:53 +00:00
|
|
|
|
2017-08-08 23:11:14 +00:00
|
|
|
impl<S: Bounded> Bounded for $VectorN<S> {
|
|
|
|
#[inline]
|
|
|
|
fn min_value() -> $VectorN<S> {
|
|
|
|
$VectorN { $($field: S::min_value()),+ }
|
|
|
|
}
|
|
|
|
|
|
|
|
#[inline]
|
|
|
|
fn max_value() -> $VectorN<S> {
|
|
|
|
$VectorN { $($field: S::max_value()),+ }
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-12-21 13:43:15 +00:00
|
|
|
impl_operator!(<S: BaseNum> Add<$VectorN<S> > for $VectorN<S> {
|
2015-12-12 11:17:03 +00:00
|
|
|
fn add(lhs, rhs) -> $VectorN<S> { $VectorN::new($(lhs.$field + rhs.$field),+) }
|
|
|
|
});
|
2015-12-20 20:24:56 +00:00
|
|
|
impl_assignment_operator!(<S: BaseNum> AddAssign<$VectorN<S> > for $VectorN<S> {
|
|
|
|
fn add_assign(&mut self, other) { $(self.$field += other.$field);+ }
|
|
|
|
});
|
2015-12-12 11:17:03 +00:00
|
|
|
|
2015-12-21 13:43:15 +00:00
|
|
|
impl_operator!(<S: BaseNum> Sub<$VectorN<S> > for $VectorN<S> {
|
2015-12-12 11:17:03 +00:00
|
|
|
fn sub(lhs, rhs) -> $VectorN<S> { $VectorN::new($(lhs.$field - rhs.$field),+) }
|
|
|
|
});
|
2015-12-20 20:24:56 +00:00
|
|
|
impl_assignment_operator!(<S: BaseNum> SubAssign<$VectorN<S> > for $VectorN<S> {
|
|
|
|
fn sub_assign(&mut self, other) { $(self.$field -= other.$field);+ }
|
|
|
|
});
|
2015-12-12 11:17:03 +00:00
|
|
|
|
2015-12-21 13:43:15 +00:00
|
|
|
impl_operator!(<S: BaseNum> Mul<S> for $VectorN<S> {
|
2015-12-12 11:17:03 +00:00
|
|
|
fn mul(vector, scalar) -> $VectorN<S> { $VectorN::new($(vector.$field * scalar),+) }
|
|
|
|
});
|
2015-12-20 20:24:56 +00:00
|
|
|
impl_assignment_operator!(<S: BaseNum> MulAssign<S> for $VectorN<S> {
|
|
|
|
fn mul_assign(&mut self, scalar) { $(self.$field *= scalar);+ }
|
|
|
|
});
|
2015-12-12 11:17:03 +00:00
|
|
|
|
2015-12-21 13:43:15 +00:00
|
|
|
impl_operator!(<S: BaseNum> Div<S> for $VectorN<S> {
|
2015-12-12 11:17:03 +00:00
|
|
|
fn div(vector, scalar) -> $VectorN<S> { $VectorN::new($(vector.$field / scalar),+) }
|
|
|
|
});
|
2015-12-20 20:24:56 +00:00
|
|
|
impl_assignment_operator!(<S: BaseNum> DivAssign<S> for $VectorN<S> {
|
|
|
|
fn div_assign(&mut self, scalar) { $(self.$field /= scalar);+ }
|
|
|
|
});
|
2015-12-12 11:17:03 +00:00
|
|
|
|
2015-12-21 13:43:15 +00:00
|
|
|
impl_operator!(<S: BaseNum> Rem<S> for $VectorN<S> {
|
2015-12-12 11:17:03 +00:00
|
|
|
fn rem(vector, scalar) -> $VectorN<S> { $VectorN::new($(vector.$field % scalar),+) }
|
|
|
|
});
|
2015-12-20 20:24:56 +00:00
|
|
|
impl_assignment_operator!(<S: BaseNum> RemAssign<S> for $VectorN<S> {
|
|
|
|
fn rem_assign(&mut self, scalar) { $(self.$field %= scalar);+ }
|
|
|
|
});
|
2016-03-26 02:19:06 +00:00
|
|
|
|
|
|
|
impl<S: BaseNum> ElementWise for $VectorN<S> {
|
2019-09-01 14:16:04 +00:00
|
|
|
#[inline] default_fn!( add_element_wise(self, rhs: $VectorN<S>) -> $VectorN<S> { $VectorN::new($(self.$field + rhs.$field),+) } );
|
|
|
|
#[inline] default_fn!( sub_element_wise(self, rhs: $VectorN<S>) -> $VectorN<S> { $VectorN::new($(self.$field - rhs.$field),+) } );
|
|
|
|
#[inline] default_fn!( mul_element_wise(self, rhs: $VectorN<S>) -> $VectorN<S> { $VectorN::new($(self.$field * rhs.$field),+) } );
|
|
|
|
#[inline] default_fn!( div_element_wise(self, rhs: $VectorN<S>) -> $VectorN<S> { $VectorN::new($(self.$field / rhs.$field),+) } );
|
2016-03-26 02:19:06 +00:00
|
|
|
#[inline] fn rem_element_wise(self, rhs: $VectorN<S>) -> $VectorN<S> { $VectorN::new($(self.$field % rhs.$field),+) }
|
|
|
|
|
2019-09-01 14:16:04 +00:00
|
|
|
#[inline] default_fn!( add_assign_element_wise(&mut self, rhs: $VectorN<S>) { $(self.$field += rhs.$field);+ } );
|
|
|
|
#[inline] default_fn!( sub_assign_element_wise(&mut self, rhs: $VectorN<S>) { $(self.$field -= rhs.$field);+ } );
|
|
|
|
#[inline] default_fn!( mul_assign_element_wise(&mut self, rhs: $VectorN<S>) { $(self.$field *= rhs.$field);+ } );
|
|
|
|
#[inline] default_fn!( div_assign_element_wise(&mut self, rhs: $VectorN<S>) { $(self.$field /= rhs.$field);+ } );
|
2016-04-15 07:16:50 +00:00
|
|
|
#[inline] fn rem_assign_element_wise(&mut self, rhs: $VectorN<S>) { $(self.$field %= rhs.$field);+ }
|
2016-03-26 02:19:06 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
impl<S: BaseNum> ElementWise<S> for $VectorN<S> {
|
2019-09-01 14:16:04 +00:00
|
|
|
#[inline] default_fn!( add_element_wise(self, rhs: S) -> $VectorN<S> { $VectorN::new($(self.$field + rhs),+) } );
|
|
|
|
#[inline] default_fn!( sub_element_wise(self, rhs: S) -> $VectorN<S> { $VectorN::new($(self.$field - rhs),+) } );
|
|
|
|
#[inline] default_fn!( mul_element_wise(self, rhs: S) -> $VectorN<S> { $VectorN::new($(self.$field * rhs),+) } );
|
|
|
|
#[inline] default_fn!( div_element_wise(self, rhs: S) -> $VectorN<S> { $VectorN::new($(self.$field / rhs),+) } );
|
2016-03-26 02:19:06 +00:00
|
|
|
#[inline] fn rem_element_wise(self, rhs: S) -> $VectorN<S> { $VectorN::new($(self.$field % rhs),+) }
|
|
|
|
|
2019-09-01 14:16:04 +00:00
|
|
|
#[inline] default_fn!( add_assign_element_wise(&mut self, rhs: S) { $(self.$field += rhs);+ } );
|
|
|
|
#[inline] default_fn!( sub_assign_element_wise(&mut self, rhs: S) { $(self.$field -= rhs);+ } );
|
|
|
|
#[inline] default_fn!( mul_assign_element_wise(&mut self, rhs: S) { $(self.$field *= rhs);+ } );
|
|
|
|
#[inline] default_fn!( div_assign_element_wise(&mut self, rhs: S) { $(self.$field /= rhs);+ } );
|
2016-04-15 07:16:50 +00:00
|
|
|
#[inline] fn rem_assign_element_wise(&mut self, rhs: S) { $(self.$field %= rhs);+ }
|
2016-03-26 02:19:06 +00:00
|
|
|
}
|
2015-12-12 11:17:03 +00:00
|
|
|
|
2016-01-01 13:09:11 +00:00
|
|
|
impl_scalar_ops!($VectorN<usize> { $($field),+ });
|
|
|
|
impl_scalar_ops!($VectorN<u8> { $($field),+ });
|
|
|
|
impl_scalar_ops!($VectorN<u16> { $($field),+ });
|
|
|
|
impl_scalar_ops!($VectorN<u32> { $($field),+ });
|
|
|
|
impl_scalar_ops!($VectorN<u64> { $($field),+ });
|
|
|
|
impl_scalar_ops!($VectorN<isize> { $($field),+ });
|
|
|
|
impl_scalar_ops!($VectorN<i8> { $($field),+ });
|
|
|
|
impl_scalar_ops!($VectorN<i16> { $($field),+ });
|
|
|
|
impl_scalar_ops!($VectorN<i32> { $($field),+ });
|
|
|
|
impl_scalar_ops!($VectorN<i64> { $($field),+ });
|
|
|
|
impl_scalar_ops!($VectorN<f32> { $($field),+ });
|
|
|
|
impl_scalar_ops!($VectorN<f64> { $($field),+ });
|
|
|
|
|
2015-12-12 11:17:03 +00:00
|
|
|
impl_index_operators!($VectorN<S>, $n, S, usize);
|
|
|
|
impl_index_operators!($VectorN<S>, $n, [S], Range<usize>);
|
|
|
|
impl_index_operators!($VectorN<S>, $n, [S], RangeTo<usize>);
|
|
|
|
impl_index_operators!($VectorN<S>, $n, [S], RangeFrom<usize>);
|
|
|
|
impl_index_operators!($VectorN<S>, $n, [S], RangeFull);
|
2015-09-20 15:32:53 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-01-01 13:09:11 +00:00
|
|
|
macro_rules! impl_scalar_ops {
|
|
|
|
($VectorN:ident<$S:ident> { $($field:ident),+ }) => {
|
|
|
|
impl_operator!(Mul<$VectorN<$S>> for $S {
|
|
|
|
fn mul(scalar, vector) -> $VectorN<$S> { $VectorN::new($(scalar * vector.$field),+) }
|
|
|
|
});
|
|
|
|
impl_operator!(Div<$VectorN<$S>> for $S {
|
|
|
|
fn div(scalar, vector) -> $VectorN<$S> { $VectorN::new($(scalar / vector.$field),+) }
|
|
|
|
});
|
|
|
|
impl_operator!(Rem<$VectorN<$S>> for $S {
|
|
|
|
fn rem(scalar, vector) -> $VectorN<$S> { $VectorN::new($(scalar % vector.$field),+) }
|
|
|
|
});
|
2017-02-24 23:26:11 +00:00
|
|
|
};
|
|
|
|
}
|
|
|
|
|
2016-04-24 22:59:33 +00:00
|
|
|
impl_vector!(Vector1 { x }, 1, vec1);
|
2016-04-23 09:52:37 +00:00
|
|
|
impl_vector!(Vector2 { x, y }, 2, vec2);
|
|
|
|
impl_vector!(Vector3 { x, y, z }, 3, vec3);
|
|
|
|
impl_vector!(Vector4 { x, y, z, w }, 4, vec4);
|
2015-09-20 15:32:53 +00:00
|
|
|
|
2016-04-24 22:59:33 +00:00
|
|
|
impl_fixed_array_conversions!(Vector1<S> { x: 0 }, 1);
|
2015-12-12 11:17:03 +00:00
|
|
|
impl_fixed_array_conversions!(Vector2<S> { x: 0, y: 1 }, 2);
|
|
|
|
impl_fixed_array_conversions!(Vector3<S> { x: 0, y: 1, z: 2 }, 3);
|
|
|
|
impl_fixed_array_conversions!(Vector4<S> { x: 0, y: 1, z: 2, w: 3 }, 4);
|
2015-09-20 15:32:53 +00:00
|
|
|
|
2016-04-24 22:59:33 +00:00
|
|
|
impl_tuple_conversions!(Vector1<S> { x }, (S,));
|
2015-12-12 11:17:03 +00:00
|
|
|
impl_tuple_conversions!(Vector2<S> { x, y }, (S, S));
|
|
|
|
impl_tuple_conversions!(Vector3<S> { x, y, z }, (S, S, S));
|
|
|
|
impl_tuple_conversions!(Vector4<S> { x, y, z, w }, (S, S, S, S));
|
2015-09-20 15:32:53 +00:00
|
|
|
|
2016-04-24 22:59:33 +00:00
|
|
|
impl<S: BaseNum> Vector1<S> {
|
|
|
|
/// A unit vector in the `x` direction.
|
|
|
|
#[inline]
|
|
|
|
pub fn unit_x() -> Vector1<S> {
|
|
|
|
Vector1::new(S::one())
|
|
|
|
}
|
2017-09-30 21:41:17 +00:00
|
|
|
|
2017-09-30 22:09:03 +00:00
|
|
|
impl_swizzle_functions!(Vector1, Vector2, Vector3, Vector4, S, x);
|
2016-04-24 22:59:33 +00:00
|
|
|
}
|
|
|
|
|
2014-05-26 17:10:04 +00:00
|
|
|
impl<S: BaseNum> Vector2<S> {
|
2014-05-25 09:43:51 +00:00
|
|
|
/// A unit vector in the `x` direction.
|
2015-09-29 11:36:57 +00:00
|
|
|
#[inline]
|
|
|
|
pub fn unit_x() -> Vector2<S> {
|
|
|
|
Vector2::new(S::one(), S::zero())
|
|
|
|
}
|
|
|
|
|
2014-05-25 09:43:51 +00:00
|
|
|
/// A unit vector in the `y` direction.
|
2015-09-29 11:36:57 +00:00
|
|
|
#[inline]
|
|
|
|
pub fn unit_y() -> Vector2<S> {
|
|
|
|
Vector2::new(S::zero(), S::one())
|
|
|
|
}
|
2014-01-23 16:13:53 +00:00
|
|
|
|
2013-09-03 03:54:03 +00:00
|
|
|
/// The perpendicular dot product of the vector and `other`.
|
|
|
|
#[inline]
|
2015-11-09 09:12:04 +00:00
|
|
|
pub fn perp_dot(self, other: Vector2<S>) -> S {
|
2013-09-03 03:54:03 +00:00
|
|
|
(self.x * other.y) - (self.y * other.x)
|
|
|
|
}
|
2014-01-23 16:13:53 +00:00
|
|
|
|
2014-05-25 09:43:51 +00:00
|
|
|
/// Create a `Vector3`, using the `x` and `y` values from this vector, and the
|
|
|
|
/// provided `z`.
|
2014-01-23 16:13:53 +00:00
|
|
|
#[inline]
|
2017-02-24 23:26:11 +00:00
|
|
|
pub fn extend(self, z: S) -> Vector3<S> {
|
2014-07-29 18:06:31 +00:00
|
|
|
Vector3::new(self.x, self.y, z)
|
2014-01-23 16:13:53 +00:00
|
|
|
}
|
2017-09-30 21:41:17 +00:00
|
|
|
|
2017-09-30 22:09:03 +00:00
|
|
|
impl_swizzle_functions!(Vector1, Vector2, Vector3, Vector4, S, xy);
|
2013-09-03 03:54:03 +00:00
|
|
|
}
|
|
|
|
|
2014-05-26 17:10:04 +00:00
|
|
|
impl<S: BaseNum> Vector3<S> {
|
2014-05-25 09:43:51 +00:00
|
|
|
/// A unit vector in the `x` direction.
|
2015-09-29 11:36:57 +00:00
|
|
|
#[inline]
|
|
|
|
pub fn unit_x() -> Vector3<S> {
|
|
|
|
Vector3::new(S::one(), S::zero(), S::zero())
|
|
|
|
}
|
|
|
|
|
2014-05-25 09:43:51 +00:00
|
|
|
/// A unit vector in the `y` direction.
|
2015-09-29 11:36:57 +00:00
|
|
|
#[inline]
|
|
|
|
pub fn unit_y() -> Vector3<S> {
|
|
|
|
Vector3::new(S::zero(), S::one(), S::zero())
|
|
|
|
}
|
|
|
|
|
2017-12-04 01:57:37 +00:00
|
|
|
/// A unit vector in the `z` direction.
|
2015-09-29 11:36:57 +00:00
|
|
|
#[inline]
|
|
|
|
pub fn unit_z() -> Vector3<S> {
|
|
|
|
Vector3::new(S::zero(), S::zero(), S::one())
|
|
|
|
}
|
2014-01-23 16:13:53 +00:00
|
|
|
|
2013-09-03 03:54:03 +00:00
|
|
|
/// Returns the cross product of the vector and `other`.
|
|
|
|
#[inline]
|
2015-11-09 09:12:04 +00:00
|
|
|
pub fn cross(self, other: Vector3<S>) -> Vector3<S> {
|
2018-01-03 02:01:02 +00:00
|
|
|
Vector3::new(
|
|
|
|
(self.y * other.z) - (self.z * other.y),
|
|
|
|
(self.z * other.x) - (self.x * other.z),
|
|
|
|
(self.x * other.y) - (self.y * other.x),
|
|
|
|
)
|
2013-09-03 03:54:03 +00:00
|
|
|
}
|
2013-09-06 02:32:07 +00:00
|
|
|
|
2014-05-25 09:43:51 +00:00
|
|
|
/// Create a `Vector4`, using the `x`, `y` and `z` values from this vector, and the
|
|
|
|
/// provided `w`.
|
2014-01-23 16:13:53 +00:00
|
|
|
#[inline]
|
2017-02-24 23:26:11 +00:00
|
|
|
pub fn extend(self, w: S) -> Vector4<S> {
|
2014-07-29 18:06:31 +00:00
|
|
|
Vector4::new(self.x, self.y, self.z, w)
|
2014-01-23 16:13:53 +00:00
|
|
|
}
|
|
|
|
|
2014-05-25 09:43:51 +00:00
|
|
|
/// Create a `Vector2`, dropping the `z` value.
|
2014-01-23 16:13:53 +00:00
|
|
|
#[inline]
|
2017-02-24 23:26:11 +00:00
|
|
|
pub fn truncate(self) -> Vector2<S> {
|
2014-07-29 18:06:31 +00:00
|
|
|
Vector2::new(self.x, self.y)
|
2014-01-23 16:13:53 +00:00
|
|
|
}
|
2017-09-30 21:41:17 +00:00
|
|
|
|
2017-09-30 22:09:03 +00:00
|
|
|
impl_swizzle_functions!(Vector1, Vector2, Vector3, Vector4, S, xyz);
|
2014-01-23 16:13:53 +00:00
|
|
|
}
|
|
|
|
|
2014-05-26 17:10:04 +00:00
|
|
|
impl<S: BaseNum> Vector4<S> {
|
2014-05-25 09:43:51 +00:00
|
|
|
/// A unit vector in the `x` direction.
|
2015-09-29 11:36:57 +00:00
|
|
|
#[inline]
|
|
|
|
pub fn unit_x() -> Vector4<S> {
|
|
|
|
Vector4::new(S::one(), S::zero(), S::zero(), S::zero())
|
|
|
|
}
|
|
|
|
|
2014-05-25 09:43:51 +00:00
|
|
|
/// A unit vector in the `y` direction.
|
2015-09-29 11:36:57 +00:00
|
|
|
#[inline]
|
|
|
|
pub fn unit_y() -> Vector4<S> {
|
|
|
|
Vector4::new(S::zero(), S::one(), S::zero(), S::zero())
|
|
|
|
}
|
|
|
|
|
2014-05-25 09:43:51 +00:00
|
|
|
/// A unit vector in the `z` direction.
|
2015-09-29 11:36:57 +00:00
|
|
|
#[inline]
|
|
|
|
pub fn unit_z() -> Vector4<S> {
|
|
|
|
Vector4::new(S::zero(), S::zero(), S::one(), S::zero())
|
|
|
|
}
|
|
|
|
|
2014-05-25 09:43:51 +00:00
|
|
|
/// A unit vector in the `w` direction.
|
2015-09-29 11:36:57 +00:00
|
|
|
#[inline]
|
|
|
|
pub fn unit_w() -> Vector4<S> {
|
|
|
|
Vector4::new(S::zero(), S::zero(), S::zero(), S::one())
|
|
|
|
}
|
2014-01-23 16:13:53 +00:00
|
|
|
|
2014-05-25 09:43:51 +00:00
|
|
|
/// Create a `Vector3`, dropping the `w` value.
|
2014-01-23 16:13:53 +00:00
|
|
|
#[inline]
|
2017-02-24 23:26:11 +00:00
|
|
|
pub fn truncate(self) -> Vector3<S> {
|
2014-07-29 18:06:31 +00:00
|
|
|
Vector3::new(self.x, self.y, self.z)
|
2014-01-23 16:13:53 +00:00
|
|
|
}
|
2014-06-05 07:58:09 +00:00
|
|
|
|
2017-03-20 23:06:06 +00:00
|
|
|
/// Create a `Vector3`, dropping the nth element.
|
2014-06-05 07:58:09 +00:00
|
|
|
#[inline]
|
2017-02-24 23:26:11 +00:00
|
|
|
pub fn truncate_n(&self, n: isize) -> Vector3<S> {
|
2014-06-05 07:58:09 +00:00
|
|
|
match n {
|
2014-07-29 18:06:31 +00:00
|
|
|
0 => Vector3::new(self.y, self.z, self.w),
|
|
|
|
1 => Vector3::new(self.x, self.z, self.w),
|
|
|
|
2 => Vector3::new(self.x, self.y, self.w),
|
|
|
|
3 => Vector3::new(self.x, self.y, self.z),
|
2017-02-24 23:26:11 +00:00
|
|
|
_ => panic!("{:?} is out of range", n),
|
2014-06-05 07:58:09 +00:00
|
|
|
}
|
|
|
|
}
|
2017-09-30 21:41:17 +00:00
|
|
|
|
|
|
|
impl_swizzle_functions!(Vector1, Vector2, Vector3, Vector4, S, xyzw);
|
2013-09-03 03:54:03 +00:00
|
|
|
}
|
|
|
|
|
2016-04-04 09:45:54 +00:00
|
|
|
/// Dot product of two vectors.
|
|
|
|
#[inline]
|
2017-02-24 23:26:11 +00:00
|
|
|
pub fn dot<V: InnerSpace>(a: V, b: V) -> V::Scalar
|
2018-01-03 02:01:02 +00:00
|
|
|
where
|
2021-07-25 13:22:06 +00:00
|
|
|
V::Scalar: BaseNum,
|
2016-04-04 09:45:54 +00:00
|
|
|
{
|
|
|
|
V::dot(a, b)
|
|
|
|
}
|
|
|
|
|
2020-06-03 03:38:50 +00:00
|
|
|
impl<S: BaseNum> InnerSpace for Vector1<S> {
|
2016-04-24 22:59:33 +00:00
|
|
|
#[inline]
|
|
|
|
fn dot(self, other: Vector1<S>) -> S {
|
|
|
|
Vector1::mul_element_wise(self, other).sum()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-06-03 03:38:50 +00:00
|
|
|
impl<S: BaseNum> InnerSpace for Vector2<S> {
|
2016-04-04 09:45:54 +00:00
|
|
|
#[inline]
|
|
|
|
fn dot(self, other: Vector2<S>) -> S {
|
|
|
|
Vector2::mul_element_wise(self, other).sum()
|
|
|
|
}
|
|
|
|
|
2013-09-03 03:54:03 +00:00
|
|
|
#[inline]
|
2020-08-12 03:04:27 +00:00
|
|
|
fn angle(self, other: Vector2<S>) -> Rad<S>
|
|
|
|
where
|
|
|
|
S: BaseFloat,
|
|
|
|
{
|
2016-03-27 05:25:03 +00:00
|
|
|
Rad::atan2(Self::perp_dot(self, other), Self::dot(self, other))
|
2013-09-03 03:54:03 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-06-03 03:38:50 +00:00
|
|
|
impl<S: BaseNum> InnerSpace for Vector3<S> {
|
2016-04-04 09:45:54 +00:00
|
|
|
#[inline]
|
|
|
|
fn dot(self, other: Vector3<S>) -> S {
|
|
|
|
Vector3::mul_element_wise(self, other).sum()
|
|
|
|
}
|
|
|
|
|
2013-09-03 03:54:03 +00:00
|
|
|
#[inline]
|
2020-08-12 03:04:27 +00:00
|
|
|
fn angle(self, other: Vector3<S>) -> Rad<S>
|
|
|
|
where
|
|
|
|
S: BaseFloat,
|
|
|
|
{
|
2016-03-27 05:25:03 +00:00
|
|
|
Rad::atan2(self.cross(other).magnitude(), Self::dot(self, other))
|
2013-09-03 03:54:03 +00:00
|
|
|
}
|
|
|
|
}
|
2013-09-03 07:33:33 +00:00
|
|
|
|
2020-06-03 03:38:50 +00:00
|
|
|
impl<S: BaseNum> InnerSpace for Vector4<S> {
|
2016-04-04 09:45:54 +00:00
|
|
|
#[inline]
|
|
|
|
fn dot(self, other: Vector4<S>) -> S {
|
|
|
|
Vector4::mul_element_wise(self, other).sum()
|
|
|
|
}
|
2013-09-06 06:39:15 +00:00
|
|
|
}
|
|
|
|
|
2016-04-24 22:59:33 +00:00
|
|
|
impl<S: fmt::Debug> fmt::Debug for Vector1<S> {
|
|
|
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
2019-08-24 19:06:31 +00:00
|
|
|
write!(f, "Vector1 ")?;
|
2016-04-24 22:59:33 +00:00
|
|
|
<[S; 1] as fmt::Debug>::fmt(self.as_ref(), f)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-12-29 10:50:43 +00:00
|
|
|
impl<S: fmt::Debug> fmt::Debug for Vector2<S> {
|
2014-02-25 08:56:22 +00:00
|
|
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
2019-08-24 19:06:31 +00:00
|
|
|
write!(f, "Vector2 ")?;
|
2015-12-29 10:50:43 +00:00
|
|
|
<[S; 2] as fmt::Debug>::fmt(self.as_ref(), f)
|
2013-09-03 07:33:33 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-12-29 10:50:43 +00:00
|
|
|
impl<S: fmt::Debug> fmt::Debug for Vector3<S> {
|
2014-02-25 08:56:22 +00:00
|
|
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
2019-08-24 19:06:31 +00:00
|
|
|
write!(f, "Vector3 ")?;
|
2015-12-29 10:50:43 +00:00
|
|
|
<[S; 3] as fmt::Debug>::fmt(self.as_ref(), f)
|
2013-09-03 07:33:33 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-12-29 10:50:43 +00:00
|
|
|
impl<S: fmt::Debug> fmt::Debug for Vector4<S> {
|
2014-02-25 08:56:22 +00:00
|
|
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
2019-08-24 19:06:31 +00:00
|
|
|
write!(f, "Vector4 ")?;
|
2015-12-29 10:50:43 +00:00
|
|
|
<[S; 4] as fmt::Debug>::fmt(self.as_ref(), f)
|
2013-09-03 07:33:33 +00:00
|
|
|
}
|
|
|
|
}
|
2015-09-27 03:01:14 +00:00
|
|
|
|
2017-06-06 22:07:38 +00:00
|
|
|
#[cfg(feature = "mint")]
|
|
|
|
impl_mint_conversions!(Vector2 { x, y }, Vector2);
|
|
|
|
#[cfg(feature = "mint")]
|
|
|
|
impl_mint_conversions!(Vector3 { x, y, z }, Vector3);
|
|
|
|
#[cfg(feature = "mint")]
|
|
|
|
impl_mint_conversions!(Vector4 { x, y, z, w }, Vector4);
|
|
|
|
|
2015-09-27 03:01:14 +00:00
|
|
|
#[cfg(test)]
|
|
|
|
mod tests {
|
|
|
|
mod vector2 {
|
|
|
|
use vector::*;
|
|
|
|
|
|
|
|
const VECTOR2: Vector2<i32> = Vector2 { x: 1, y: 2 };
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn test_index() {
|
|
|
|
assert_eq!(VECTOR2[0], VECTOR2.x);
|
|
|
|
assert_eq!(VECTOR2[1], VECTOR2.y);
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn test_index_mut() {
|
|
|
|
let mut v = VECTOR2;
|
2021-06-14 23:49:37 +00:00
|
|
|
v[0] = 0;
|
2015-09-27 03:01:14 +00:00
|
|
|
assert_eq!(v, [0, 2].into());
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
#[should_panic]
|
|
|
|
fn test_index_out_of_bounds() {
|
|
|
|
VECTOR2[2];
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn test_index_range() {
|
|
|
|
assert_eq!(&VECTOR2[..0], &[]);
|
|
|
|
assert_eq!(&VECTOR2[..1], &[1]);
|
|
|
|
assert_eq!(VECTOR2[..0].len(), 0);
|
|
|
|
assert_eq!(VECTOR2[..1].len(), 1);
|
|
|
|
assert_eq!(&VECTOR2[2..], &[]);
|
|
|
|
assert_eq!(&VECTOR2[1..], &[2]);
|
|
|
|
assert_eq!(VECTOR2[2..].len(), 0);
|
|
|
|
assert_eq!(VECTOR2[1..].len(), 1);
|
|
|
|
assert_eq!(&VECTOR2[..], &[1, 2]);
|
|
|
|
assert_eq!(VECTOR2[..].len(), 2);
|
|
|
|
}
|
2015-09-27 07:20:02 +00:00
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn test_into() {
|
|
|
|
let v = VECTOR2;
|
|
|
|
{
|
|
|
|
let v: [i32; 2] = v.into();
|
|
|
|
assert_eq!(v, [1, 2]);
|
|
|
|
}
|
|
|
|
{
|
|
|
|
let v: (i32, i32) = v.into();
|
|
|
|
assert_eq!(v, (1, 2));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn test_as_ref() {
|
|
|
|
let v = VECTOR2;
|
|
|
|
{
|
|
|
|
let v: &[i32; 2] = v.as_ref();
|
|
|
|
assert_eq!(v, &[1, 2]);
|
|
|
|
}
|
|
|
|
{
|
|
|
|
let v: &(i32, i32) = v.as_ref();
|
|
|
|
assert_eq!(v, &(1, 2));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn test_as_mut() {
|
|
|
|
let mut v = VECTOR2;
|
|
|
|
{
|
|
|
|
let v: &mut [i32; 2] = v.as_mut();
|
|
|
|
assert_eq!(v, &mut [1, 2]);
|
|
|
|
}
|
|
|
|
{
|
|
|
|
let v: &mut (i32, i32) = v.as_mut();
|
|
|
|
assert_eq!(v, &mut (1, 2));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn test_from() {
|
|
|
|
assert_eq!(Vector2::from([1, 2]), VECTOR2);
|
|
|
|
{
|
|
|
|
let v = &[1, 2];
|
|
|
|
let v: &Vector2<_> = From::from(v);
|
|
|
|
assert_eq!(v, &VECTOR2);
|
|
|
|
}
|
|
|
|
{
|
|
|
|
let v = &mut [1, 2];
|
|
|
|
let v: &mut Vector2<_> = From::from(v);
|
|
|
|
assert_eq!(v, &VECTOR2);
|
|
|
|
}
|
|
|
|
assert_eq!(Vector2::from((1, 2)), VECTOR2);
|
|
|
|
{
|
|
|
|
let v = &(1, 2);
|
|
|
|
let v: &Vector2<_> = From::from(v);
|
|
|
|
assert_eq!(v, &VECTOR2);
|
|
|
|
}
|
|
|
|
{
|
|
|
|
let v = &mut (1, 2);
|
|
|
|
let v: &mut Vector2<_> = From::from(v);
|
|
|
|
assert_eq!(v, &VECTOR2);
|
|
|
|
}
|
|
|
|
}
|
2018-04-28 10:34:45 +00:00
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn test_is_finite() {
|
|
|
|
use num_traits::Float;
|
|
|
|
assert!(!Vector2::from([Float::nan(), 1.0]).is_finite());
|
|
|
|
assert!(!Vector2::from([1.0, Float::infinity()]).is_finite());
|
|
|
|
assert!(Vector2::from([-1.0, 1.0]).is_finite());
|
|
|
|
}
|
2019-06-10 08:48:28 +00:00
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn test_zip() {
|
|
|
|
assert_eq!(
|
|
|
|
Vector2::new(true, false),
|
|
|
|
Vector2::new(-2, 1).zip(Vector2::new(-1, -1), |a, b| a < b)
|
|
|
|
);
|
|
|
|
}
|
2015-09-27 03:01:14 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
mod vector3 {
|
|
|
|
use vector::*;
|
|
|
|
|
|
|
|
const VECTOR3: Vector3<i32> = Vector3 { x: 1, y: 2, z: 3 };
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn test_index() {
|
|
|
|
assert_eq!(VECTOR3[0], VECTOR3.x);
|
|
|
|
assert_eq!(VECTOR3[1], VECTOR3.y);
|
|
|
|
assert_eq!(VECTOR3[2], VECTOR3.z);
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn test_index_mut() {
|
|
|
|
let mut v = VECTOR3;
|
2021-06-14 23:49:37 +00:00
|
|
|
v[1] = 0;
|
2015-09-27 03:01:14 +00:00
|
|
|
assert_eq!(v, [1, 0, 3].into());
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
#[should_panic]
|
|
|
|
fn test_index_out_of_bounds() {
|
|
|
|
VECTOR3[3];
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn test_index_range() {
|
|
|
|
assert_eq!(&VECTOR3[..1], &[1]);
|
|
|
|
assert_eq!(&VECTOR3[..2], &[1, 2]);
|
|
|
|
assert_eq!(VECTOR3[..1].len(), 1);
|
|
|
|
assert_eq!(VECTOR3[..2].len(), 2);
|
|
|
|
assert_eq!(&VECTOR3[2..], &[3]);
|
|
|
|
assert_eq!(&VECTOR3[1..], &[2, 3]);
|
|
|
|
assert_eq!(VECTOR3[2..].len(), 1);
|
|
|
|
assert_eq!(VECTOR3[1..].len(), 2);
|
|
|
|
assert_eq!(&VECTOR3[..], &[1, 2, 3]);
|
|
|
|
assert_eq!(VECTOR3[..].len(), 3);
|
|
|
|
}
|
2015-09-27 07:20:02 +00:00
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn test_into() {
|
|
|
|
let v = VECTOR3;
|
|
|
|
{
|
|
|
|
let v: [i32; 3] = v.into();
|
|
|
|
assert_eq!(v, [1, 2, 3]);
|
|
|
|
}
|
|
|
|
{
|
|
|
|
let v: (i32, i32, i32) = v.into();
|
|
|
|
assert_eq!(v, (1, 2, 3));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn test_as_ref() {
|
|
|
|
let v = VECTOR3;
|
|
|
|
{
|
|
|
|
let v: &[i32; 3] = v.as_ref();
|
|
|
|
assert_eq!(v, &[1, 2, 3]);
|
|
|
|
}
|
|
|
|
{
|
|
|
|
let v: &(i32, i32, i32) = v.as_ref();
|
|
|
|
assert_eq!(v, &(1, 2, 3));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn test_as_mut() {
|
|
|
|
let mut v = VECTOR3;
|
|
|
|
{
|
|
|
|
let v: &mut [i32; 3] = v.as_mut();
|
|
|
|
assert_eq!(v, &mut [1, 2, 3]);
|
|
|
|
}
|
|
|
|
{
|
|
|
|
let v: &mut (i32, i32, i32) = v.as_mut();
|
|
|
|
assert_eq!(v, &mut (1, 2, 3));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn test_from() {
|
|
|
|
assert_eq!(Vector3::from([1, 2, 3]), VECTOR3);
|
|
|
|
{
|
|
|
|
let v = &[1, 2, 3];
|
|
|
|
let v: &Vector3<_> = From::from(v);
|
|
|
|
assert_eq!(v, &VECTOR3);
|
|
|
|
}
|
|
|
|
{
|
|
|
|
let v = &mut [1, 2, 3];
|
|
|
|
let v: &mut Vector3<_> = From::from(v);
|
|
|
|
assert_eq!(v, &VECTOR3);
|
|
|
|
}
|
|
|
|
assert_eq!(Vector3::from((1, 2, 3)), VECTOR3);
|
|
|
|
{
|
|
|
|
let v = &(1, 2, 3);
|
|
|
|
let v: &Vector3<_> = From::from(v);
|
|
|
|
assert_eq!(v, &VECTOR3);
|
|
|
|
}
|
|
|
|
{
|
|
|
|
let v = &mut (1, 2, 3);
|
|
|
|
let v: &mut Vector3<_> = From::from(v);
|
|
|
|
assert_eq!(v, &VECTOR3);
|
|
|
|
}
|
|
|
|
}
|
2018-04-28 10:34:45 +00:00
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn test_is_finite() {
|
|
|
|
use num_traits::Float;
|
|
|
|
assert!(!Vector3::from([Float::nan(), 1.0, 1.0]).is_finite());
|
|
|
|
assert!(!Vector3::from([1.0, 1.0, Float::infinity()]).is_finite());
|
|
|
|
assert!(Vector3::from([-1.0, 1.0, 1.0]).is_finite());
|
|
|
|
}
|
2019-06-10 08:48:28 +00:00
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn test_zip() {
|
|
|
|
assert_eq!(
|
|
|
|
Vector3::new(true, false, false),
|
|
|
|
Vector3::new(-2, 1, 0).zip(Vector3::new(-1, -1, -1), |a, b| a < b)
|
|
|
|
);
|
|
|
|
}
|
2015-09-27 03:01:14 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
mod vector4 {
|
|
|
|
use vector::*;
|
|
|
|
|
2017-02-24 23:26:11 +00:00
|
|
|
const VECTOR4: Vector4<i32> = Vector4 {
|
|
|
|
x: 1,
|
|
|
|
y: 2,
|
|
|
|
z: 3,
|
|
|
|
w: 4,
|
|
|
|
};
|
2015-09-27 03:01:14 +00:00
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn test_index() {
|
|
|
|
assert_eq!(VECTOR4[0], VECTOR4.x);
|
|
|
|
assert_eq!(VECTOR4[1], VECTOR4.y);
|
|
|
|
assert_eq!(VECTOR4[2], VECTOR4.z);
|
|
|
|
assert_eq!(VECTOR4[3], VECTOR4.w);
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn test_index_mut() {
|
|
|
|
let mut v = VECTOR4;
|
2021-06-14 23:49:37 +00:00
|
|
|
v[2] = 0;
|
2015-09-27 03:01:14 +00:00
|
|
|
assert_eq!(v, [1, 2, 0, 4].into());
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
#[should_panic]
|
|
|
|
fn test_index_out_of_bounds() {
|
|
|
|
VECTOR4[4];
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn test_index_range() {
|
|
|
|
assert_eq!(&VECTOR4[..2], &[1, 2]);
|
|
|
|
assert_eq!(&VECTOR4[..3], &[1, 2, 3]);
|
|
|
|
assert_eq!(VECTOR4[..2].len(), 2);
|
|
|
|
assert_eq!(VECTOR4[..3].len(), 3);
|
|
|
|
assert_eq!(&VECTOR4[2..], &[3, 4]);
|
|
|
|
assert_eq!(&VECTOR4[1..], &[2, 3, 4]);
|
|
|
|
assert_eq!(VECTOR4[2..].len(), 2);
|
|
|
|
assert_eq!(VECTOR4[1..].len(), 3);
|
|
|
|
assert_eq!(&VECTOR4[..], &[1, 2, 3, 4]);
|
|
|
|
assert_eq!(VECTOR4[..].len(), 4);
|
|
|
|
}
|
2015-09-27 07:20:02 +00:00
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn test_into() {
|
|
|
|
let v = VECTOR4;
|
|
|
|
{
|
|
|
|
let v: [i32; 4] = v.into();
|
|
|
|
assert_eq!(v, [1, 2, 3, 4]);
|
|
|
|
}
|
|
|
|
{
|
|
|
|
let v: (i32, i32, i32, i32) = v.into();
|
|
|
|
assert_eq!(v, (1, 2, 3, 4));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn test_as_ref() {
|
|
|
|
let v = VECTOR4;
|
|
|
|
{
|
|
|
|
let v: &[i32; 4] = v.as_ref();
|
|
|
|
assert_eq!(v, &[1, 2, 3, 4]);
|
|
|
|
}
|
|
|
|
{
|
|
|
|
let v: &(i32, i32, i32, i32) = v.as_ref();
|
|
|
|
assert_eq!(v, &(1, 2, 3, 4));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn test_as_mut() {
|
|
|
|
let mut v = VECTOR4;
|
|
|
|
{
|
2017-02-24 23:26:11 +00:00
|
|
|
let v: &mut [i32; 4] = v.as_mut();
|
2015-09-27 07:20:02 +00:00
|
|
|
assert_eq!(v, &mut [1, 2, 3, 4]);
|
|
|
|
}
|
|
|
|
{
|
2017-02-24 23:26:11 +00:00
|
|
|
let v: &mut (i32, i32, i32, i32) = v.as_mut();
|
2015-09-27 07:20:02 +00:00
|
|
|
assert_eq!(v, &mut (1, 2, 3, 4));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn test_from() {
|
|
|
|
assert_eq!(Vector4::from([1, 2, 3, 4]), VECTOR4);
|
|
|
|
{
|
|
|
|
let v = &[1, 2, 3, 4];
|
|
|
|
let v: &Vector4<_> = From::from(v);
|
|
|
|
assert_eq!(v, &VECTOR4);
|
|
|
|
}
|
|
|
|
{
|
|
|
|
let v = &mut [1, 2, 3, 4];
|
|
|
|
let v: &mut Vector4<_> = From::from(v);
|
|
|
|
assert_eq!(v, &VECTOR4);
|
|
|
|
}
|
|
|
|
assert_eq!(Vector4::from((1, 2, 3, 4)), VECTOR4);
|
|
|
|
{
|
|
|
|
let v = &(1, 2, 3, 4);
|
|
|
|
let v: &Vector4<_> = From::from(v);
|
|
|
|
assert_eq!(v, &VECTOR4);
|
|
|
|
}
|
|
|
|
{
|
|
|
|
let v = &mut (1, 2, 3, 4);
|
|
|
|
let v: &mut Vector4<_> = From::from(v);
|
|
|
|
assert_eq!(v, &VECTOR4);
|
|
|
|
}
|
|
|
|
}
|
2018-04-28 10:34:45 +00:00
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn test_is_finite() {
|
|
|
|
use num_traits::Float;
|
|
|
|
assert!(!Vector4::from([0.0, Float::nan(), 1.0, 1.0]).is_finite());
|
|
|
|
assert!(!Vector4::from([1.0, 1.0, Float::neg_infinity(), 0.0]).is_finite());
|
|
|
|
assert!(Vector4::from([-1.0, 0.0, 1.0, 1.0]).is_finite());
|
|
|
|
}
|
2019-06-10 08:48:28 +00:00
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn test_zip() {
|
|
|
|
assert_eq!(
|
|
|
|
Vector4::new(true, false, false, false),
|
|
|
|
Vector4::new(-2, 1, 0, 1).zip(Vector4::new(-1, -1, -1, -1), |a, b| a < b)
|
|
|
|
);
|
|
|
|
}
|
2020-06-03 03:38:50 +00:00
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn test_dot() {
|
|
|
|
assert_eq!(vec3(1.0, 2.0, 3.0).dot(vec3(4.0, 5.0, 6.0)), 32.0);
|
|
|
|
assert_eq!(vec3(1, 2, 3).dot(vec3(4, 5, 6)), 32);
|
|
|
|
}
|
2015-09-27 03:01:14 +00:00
|
|
|
}
|
|
|
|
}
|