2014-05-26 17:10:04 +00:00
|
|
|
// Copyright 2013-2014 The CGMath Developers. For a full listing of the authors,
|
2013-09-03 03:54:03 +00:00
|
|
|
// refer to the AUTHORS file at the top-level directory of this distribution.
|
|
|
|
//
|
|
|
|
// 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.
|
|
|
|
|
2013-10-19 14:00:44 +00:00
|
|
|
use std::fmt;
|
2014-05-28 01:59:03 +00:00
|
|
|
use std::mem;
|
2014-04-02 09:24:04 +00:00
|
|
|
use std::num::{Zero, zero, One, one};
|
2013-09-03 03:54:03 +00:00
|
|
|
|
2013-09-06 06:39:15 +00:00
|
|
|
use angle::{Rad, atan2, acos};
|
2014-01-09 00:26:50 +00:00
|
|
|
use approx::ApproxEq;
|
2014-05-28 01:59:03 +00:00
|
|
|
use array::Array1;
|
|
|
|
use num::{BaseNum, BaseFloat};
|
2013-09-03 03:54:03 +00:00
|
|
|
|
2013-09-03 06:37:06 +00:00
|
|
|
/// A trait that specifies a range of numeric operations for vectors. Not all
|
|
|
|
/// of these make sense from a linear algebra point of view, but are included
|
|
|
|
/// for pragmatic reasons.
|
2014-05-28 01:59:03 +00:00
|
|
|
pub trait Vector<S: BaseNum>: Array1<S>
|
|
|
|
+ Neg<Self>
|
|
|
|
+ Zero
|
|
|
|
+ One {
|
2014-05-25 09:43:51 +00:00
|
|
|
/// Add a scalar to this vector, returning a new vector.
|
2014-05-28 01:59:03 +00:00
|
|
|
fn add_s(&self, s: S) -> Self;
|
2014-05-25 09:43:51 +00:00
|
|
|
/// Subtract a scalar from this vector, returning a new vector.
|
2014-05-28 01:59:03 +00:00
|
|
|
fn sub_s(&self, s: S) -> Self;
|
2014-05-25 09:43:51 +00:00
|
|
|
/// Multiply this vector by a scalar, returning a new vector.
|
2014-05-28 01:59:03 +00:00
|
|
|
fn mul_s(&self, s: S) -> Self;
|
2014-05-25 09:43:51 +00:00
|
|
|
/// Divide this vector by a scalar, returning a new vector.
|
2014-05-28 01:59:03 +00:00
|
|
|
fn div_s(&self, s: S) -> Self;
|
2014-05-25 09:43:51 +00:00
|
|
|
/// Take the remainder of this vector by a scalar, returning a new vector.
|
2014-05-28 01:59:03 +00:00
|
|
|
fn rem_s(&self, s: S) -> Self;
|
2013-09-14 01:58:19 +00:00
|
|
|
|
2014-05-25 09:43:51 +00:00
|
|
|
/// Add this vector to another, returning a new vector.
|
2014-05-28 01:59:03 +00:00
|
|
|
fn add_v(&self, v: &Self) -> Self;
|
2014-05-25 09:43:51 +00:00
|
|
|
/// Subtract another vector from this one, returning a new vector.
|
2014-05-28 01:59:03 +00:00
|
|
|
fn sub_v(&self, v: &Self) -> Self;
|
2014-05-25 09:43:51 +00:00
|
|
|
/// Multiply this vector by another, returning a new vector.
|
2014-05-28 01:59:03 +00:00
|
|
|
fn mul_v(&self, v: &Self) -> Self;
|
2014-05-25 09:43:51 +00:00
|
|
|
/// Divide this vector by another, returning a new vector.
|
2014-05-28 01:59:03 +00:00
|
|
|
fn div_v(&self, v: &Self) -> Self;
|
2014-05-25 09:43:51 +00:00
|
|
|
/// Take the remainder of this vector by another, returning a new scalar.
|
2014-05-28 01:59:03 +00:00
|
|
|
fn rem_v(&self, v: &Self) -> Self;
|
2013-09-06 06:53:37 +00:00
|
|
|
|
2014-05-25 09:43:51 +00:00
|
|
|
/// Negate this vector in-place.
|
2014-05-28 01:59:03 +00:00
|
|
|
fn neg_self(&mut self);
|
2013-09-06 06:53:37 +00:00
|
|
|
|
2014-05-25 09:43:51 +00:00
|
|
|
/// Add a scalar to this vector in-place.
|
2014-05-28 01:59:03 +00:00
|
|
|
fn add_self_s(&mut self, s: S);
|
2014-05-25 09:43:51 +00:00
|
|
|
/// Subtract a scalar from this vector, in-place.
|
2014-05-28 01:59:03 +00:00
|
|
|
fn sub_self_s(&mut self, s: S);
|
2014-05-25 09:43:51 +00:00
|
|
|
/// Multiply this vector by a scalar, in-place.
|
2014-05-28 01:59:03 +00:00
|
|
|
fn mul_self_s(&mut self, s: S);
|
2014-05-25 09:43:51 +00:00
|
|
|
/// Divide this vector by a scalar, in-place.
|
2014-05-28 01:59:03 +00:00
|
|
|
fn div_self_s(&mut self, s: S);
|
2014-05-25 09:43:51 +00:00
|
|
|
/// Take the remainder of this vector by a scalar, in-place.
|
2014-05-28 01:59:03 +00:00
|
|
|
fn rem_self_s(&mut self, s: S);
|
2013-09-06 06:53:37 +00:00
|
|
|
|
2014-05-25 09:43:51 +00:00
|
|
|
/// Add another vector to this one, in-place.
|
2014-05-28 01:59:03 +00:00
|
|
|
fn add_self_v(&mut self, v: &Self);
|
2014-05-25 09:43:51 +00:00
|
|
|
/// Subtract another vector from this one, in-place.
|
2014-05-28 01:59:03 +00:00
|
|
|
fn sub_self_v(&mut self, v: &Self);
|
2014-05-25 09:43:51 +00:00
|
|
|
/// Multiply this matrix by another, in-place.
|
2014-05-28 01:59:03 +00:00
|
|
|
fn mul_self_v(&mut self, v: &Self);
|
2014-05-25 09:43:51 +00:00
|
|
|
/// Divide this matrix by anothor, in-place.
|
2014-05-28 01:59:03 +00:00
|
|
|
fn div_self_v(&mut self, v: &Self);
|
2014-05-25 09:43:51 +00:00
|
|
|
/// Take the remainder of this vector by another, in-place.
|
2014-05-28 01:59:03 +00:00
|
|
|
fn rem_self_v(&mut self, v: &Self);
|
2013-09-03 06:37:06 +00:00
|
|
|
|
|
|
|
/// The sum of each component of the vector.
|
2014-05-28 01:59:03 +00:00
|
|
|
fn comp_add(&self) -> S;
|
2013-09-03 06:37:06 +00:00
|
|
|
/// The product of each component of the vector.
|
2014-05-28 01:59:03 +00:00
|
|
|
fn comp_mul(&self) -> S;
|
2013-09-06 06:53:37 +00:00
|
|
|
|
|
|
|
/// Vector dot product.
|
2014-05-28 01:59:03 +00:00
|
|
|
#[inline]
|
|
|
|
fn dot(&self, v: &Self) -> S { self.mul_v(v).comp_add() }
|
2013-09-06 02:32:07 +00:00
|
|
|
|
|
|
|
/// The minimum component of the vector.
|
2014-05-28 01:59:03 +00:00
|
|
|
fn comp_min(&self) -> S;
|
2013-09-06 02:32:07 +00:00
|
|
|
/// The maximum component of the vector.
|
2014-05-28 01:59:03 +00:00
|
|
|
fn comp_max(&self) -> S;
|
2013-09-03 03:54:03 +00:00
|
|
|
}
|
|
|
|
|
2014-05-25 09:43:51 +00:00
|
|
|
/// Dot product of two vectors.
|
2014-05-28 01:59:03 +00:00
|
|
|
#[inline] pub fn dot<S: BaseNum, V: Vector<S>>(a: V, b: V) -> S { a.dot(&b) }
|
2013-09-14 01:53:12 +00:00
|
|
|
|
2014-01-23 16:13:53 +00:00
|
|
|
// Utility macro for generating associated functions for the vectors
|
|
|
|
macro_rules! vec(
|
|
|
|
($Self:ident <$S:ident> { $($field:ident),+ }, $n:expr) => (
|
2014-06-02 08:18:05 +00:00
|
|
|
#[deriving(PartialEq, Eq, Clone, Hash)]
|
2014-04-01 11:00:17 +00:00
|
|
|
pub struct $Self<S> { $(pub $field: S),+ }
|
2014-01-23 16:13:53 +00:00
|
|
|
|
2014-05-28 01:59:03 +00:00
|
|
|
impl<$S> $Self<$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]
|
|
|
|
pub fn new($($field: $S),+) -> $Self<$S> {
|
|
|
|
$Self { $($field: $field),+ }
|
|
|
|
}
|
2014-05-28 01:59:03 +00:00
|
|
|
}
|
2014-01-23 16:13:53 +00:00
|
|
|
|
2014-05-28 01:59:03 +00:00
|
|
|
impl<$S: Clone> $Self<$S> {
|
2014-05-25 09:43:51 +00:00
|
|
|
/// Construct a vector from a single value, replicating it.
|
2014-01-23 16:13:53 +00:00
|
|
|
#[inline]
|
|
|
|
pub fn from_value(value: $S) -> $Self<$S> {
|
|
|
|
$Self { $($field: value.clone()),+ }
|
|
|
|
}
|
2014-05-28 01:59:03 +00:00
|
|
|
}
|
2014-01-23 16:13:53 +00:00
|
|
|
|
2014-05-28 01:59:03 +00:00
|
|
|
impl<$S: BaseNum> $Self<$S> {
|
2014-01-23 16:13:53 +00:00
|
|
|
/// The additive identity of the vector.
|
|
|
|
#[inline]
|
|
|
|
pub fn zero() -> $Self<$S> { $Self::from_value(zero()) }
|
|
|
|
|
|
|
|
/// The multiplicative identity of the vector.
|
|
|
|
#[inline]
|
|
|
|
pub fn ident() -> $Self<$S> { $Self::from_value(one()) }
|
|
|
|
}
|
|
|
|
|
2014-05-28 01:59:03 +00:00
|
|
|
impl<S: Copy> Array1<S> for $Self<S> {
|
|
|
|
#[inline]
|
|
|
|
fn ptr<'a>(&'a self) -> &'a S { &self.x }
|
|
|
|
|
|
|
|
#[inline]
|
|
|
|
fn mut_ptr<'a>(&'a mut self) -> &'a mut S { &mut self.x }
|
|
|
|
|
|
|
|
#[inline]
|
|
|
|
fn i(&self, i: uint) -> S {
|
|
|
|
let slice: &[S, ..$n] = unsafe { mem::transmute(self) };
|
|
|
|
slice[i]
|
|
|
|
}
|
|
|
|
|
|
|
|
#[inline]
|
|
|
|
fn mut_i<'a>(&'a mut self, i: uint) -> &'a mut S {
|
|
|
|
let slice: &'a mut [S, ..$n] = unsafe { mem::transmute(self) };
|
2014-07-05 00:15:10 +00:00
|
|
|
&mut slice[i]
|
2014-05-28 01:59:03 +00:00
|
|
|
}
|
2014-07-03 04:34:26 +00:00
|
|
|
|
|
|
|
#[inline]
|
|
|
|
fn map(&mut self, op: |S| -> S) -> $Self<S> { $(self.$field = op(self.$field);)+ *self }
|
2014-05-28 01:59:03 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
impl<S: BaseNum> Vector<S> for $Self<S> {
|
|
|
|
#[inline] fn add_s(&self, s: S) -> $Self<S> { $Self::new($(self.$field + s),+) }
|
|
|
|
#[inline] fn sub_s(&self, s: S) -> $Self<S> { $Self::new($(self.$field - s),+) }
|
|
|
|
#[inline] fn mul_s(&self, s: S) -> $Self<S> { $Self::new($(self.$field * s),+) }
|
|
|
|
#[inline] fn div_s(&self, s: S) -> $Self<S> { $Self::new($(self.$field / s),+) }
|
|
|
|
#[inline] fn rem_s(&self, s: S) -> $Self<S> { $Self::new($(self.$field % s),+) }
|
|
|
|
|
|
|
|
#[inline] fn add_v(&self, v: &$Self<S>) -> $Self<S> { $Self::new($(self.$field + v.$field),+) }
|
|
|
|
#[inline] fn sub_v(&self, v: &$Self<S>) -> $Self<S> { $Self::new($(self.$field - v.$field),+) }
|
|
|
|
#[inline] fn mul_v(&self, v: &$Self<S>) -> $Self<S> { $Self::new($(self.$field * v.$field),+) }
|
|
|
|
#[inline] fn div_v(&self, v: &$Self<S>) -> $Self<S> { $Self::new($(self.$field / v.$field),+) }
|
|
|
|
#[inline] fn rem_v(&self, v: &$Self<S>) -> $Self<S> { $Self::new($(self.$field % v.$field),+) }
|
|
|
|
|
|
|
|
#[inline] fn neg_self(&mut self) { $(self.$field = -self.$field;)+ }
|
|
|
|
|
|
|
|
#[inline] fn add_self_s(&mut self, s: S) { $(self.$field = self.$field + s;)+ }
|
|
|
|
#[inline] fn sub_self_s(&mut self, s: S) { $(self.$field = self.$field - s;)+ }
|
|
|
|
#[inline] fn mul_self_s(&mut self, s: S) { $(self.$field = self.$field * s;)+ }
|
|
|
|
#[inline] fn div_self_s(&mut self, s: S) { $(self.$field = self.$field / s;)+ }
|
|
|
|
#[inline] fn rem_self_s(&mut self, s: S) { $(self.$field = self.$field % s;)+ }
|
|
|
|
|
|
|
|
#[inline] fn add_self_v(&mut self, v: &$Self<S>) { $(self.$field = self.$field + v.$field;)+ }
|
|
|
|
#[inline] fn sub_self_v(&mut self, v: &$Self<S>) { $(self.$field = self.$field - v.$field;)+ }
|
|
|
|
#[inline] fn mul_self_v(&mut self, v: &$Self<S>) { $(self.$field = self.$field * v.$field;)+ }
|
|
|
|
#[inline] fn div_self_v(&mut self, v: &$Self<S>) { $(self.$field = self.$field / v.$field;)+ }
|
|
|
|
#[inline] fn rem_self_v(&mut self, v: &$Self<S>) { $(self.$field = self.$field % v.$field;)+ }
|
|
|
|
|
|
|
|
#[inline] fn comp_add(&self) -> S { fold!(&add, { $(self.$field),+ }) }
|
|
|
|
#[inline] fn comp_mul(&self) -> S { fold!(&mul, { $(self.$field),+ }) }
|
|
|
|
#[inline] fn comp_min(&self) -> S { fold!(partial_min, { $(self.$field),+ }) }
|
|
|
|
#[inline] fn comp_max(&self) -> S { fold!(partial_max, { $(self.$field),+ }) }
|
|
|
|
}
|
|
|
|
|
2014-05-26 17:10:04 +00:00
|
|
|
impl<S: BaseNum> Add<$Self<S>, $Self<S>> for $Self<S> {
|
2014-05-28 01:59:03 +00:00
|
|
|
#[inline] fn add(&self, v: &$Self<S>) -> $Self<S> { self.add_v(v) }
|
2014-01-23 16:13:53 +00:00
|
|
|
}
|
|
|
|
|
2014-05-26 17:10:04 +00:00
|
|
|
impl<S: BaseNum> Sub<$Self<S>, $Self<S>> for $Self<S> {
|
2014-05-28 01:59:03 +00:00
|
|
|
#[inline] fn sub(&self, v: &$Self<S>) -> $Self<S> { self.sub_v(v) }
|
2014-01-23 16:13:53 +00:00
|
|
|
}
|
2014-01-23 16:00:24 +00:00
|
|
|
|
2014-05-26 17:10:04 +00:00
|
|
|
impl<S: BaseNum> Zero for $Self<S> {
|
2014-01-23 16:13:53 +00:00
|
|
|
#[inline] fn zero() -> $Self<S> { $Self::from_value(zero()) }
|
|
|
|
#[inline] fn is_zero(&self) -> bool { *self == zero() }
|
|
|
|
}
|
2014-01-23 16:00:24 +00:00
|
|
|
|
2014-05-26 17:10:04 +00:00
|
|
|
impl<S: BaseNum> Neg<$Self<S>> for $Self<S> {
|
2014-05-28 01:59:03 +00:00
|
|
|
#[inline] fn neg(&self) -> $Self<S> { $Self::new($(-self.$field),+) }
|
2014-01-23 16:13:53 +00:00
|
|
|
}
|
2013-09-06 06:53:37 +00:00
|
|
|
|
2014-05-26 17:10:04 +00:00
|
|
|
impl<S: BaseNum> Mul<$Self<S>, $Self<S>> for $Self<S> {
|
2014-05-28 01:59:03 +00:00
|
|
|
#[inline] fn mul(&self, v: &$Self<S>) -> $Self<S> { self.mul_v(v) }
|
2014-01-23 16:13:53 +00:00
|
|
|
}
|
2013-09-06 06:39:15 +00:00
|
|
|
|
2014-05-26 17:10:04 +00:00
|
|
|
impl<S: BaseNum> One for $Self<S> {
|
2014-01-23 16:13:53 +00:00
|
|
|
#[inline] fn one() -> $Self<S> { $Self::from_value(one()) }
|
|
|
|
}
|
2014-01-23 16:00:24 +00:00
|
|
|
|
2014-05-28 01:59:03 +00:00
|
|
|
impl<S: BaseFloat> ApproxEq<S> for $Self<S> {
|
|
|
|
#[inline]
|
|
|
|
fn approx_eq_eps(&self, other: &$Self<S>, epsilon: &S) -> bool {
|
|
|
|
$(self.$field.approx_eq_eps(&other.$field, epsilon))&&+
|
|
|
|
}
|
|
|
|
}
|
2014-01-23 16:13:53 +00:00
|
|
|
)
|
|
|
|
)
|
2014-01-23 16:00:24 +00:00
|
|
|
|
2014-05-28 01:59:03 +00:00
|
|
|
macro_rules! fold {
|
|
|
|
(&$method:ident, { $x:expr, $y:expr }) => { $x.$method(&$y) };
|
|
|
|
(&$method:ident, { $x:expr, $y:expr, $z:expr }) => { $x.$method(&$y).$method(&$z) };
|
|
|
|
(&$method:ident, { $x:expr, $y:expr, $z:expr, $w:expr }) => { $x.$method(&$y).$method(&$z).$method(&$w) };
|
|
|
|
($method:ident, { $x:expr, $y:expr }) => { $x.$method($y) };
|
|
|
|
($method:ident, { $x:expr, $y:expr, $z:expr }) => { $x.$method($y).$method($z) };
|
|
|
|
($method:ident, { $x:expr, $y:expr, $z:expr, $w:expr }) => { $x.$method($y).$method($z).$method($w) };
|
|
|
|
}
|
|
|
|
|
2014-04-14 01:30:24 +00:00
|
|
|
vec!(Vector2<S> { x, y }, 2)
|
|
|
|
vec!(Vector3<S> { x, y, z }, 3)
|
|
|
|
vec!(Vector4<S> { x, y, z, w }, 4)
|
2014-01-23 16:13:53 +00:00
|
|
|
|
2013-09-03 03:54:03 +00:00
|
|
|
/// Operations specific to numeric two-dimensional vectors.
|
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.
|
2014-04-14 01:30:24 +00:00
|
|
|
#[inline] pub fn unit_x() -> Vector2<S> { Vector2::new(one(), zero()) }
|
2014-05-25 09:43:51 +00:00
|
|
|
/// A unit vector in the `y` direction.
|
2014-04-14 01:30:24 +00:00
|
|
|
#[inline] pub fn unit_y() -> Vector2<S> { Vector2::new(zero(), 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]
|
2014-04-14 01:30:24 +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]
|
2014-04-14 01:30:24 +00:00
|
|
|
pub fn extend(&self, z: S)-> Vector3<S> {
|
|
|
|
Vector3::new(self.x.clone(), self.y.clone(), z)
|
2014-01-23 16:13:53 +00:00
|
|
|
}
|
2013-09-03 03:54:03 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/// Operations specific to numeric three-dimensional vectors.
|
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.
|
2014-04-14 01:30:24 +00:00
|
|
|
#[inline] pub fn unit_x() -> Vector3<S> { Vector3::new(one(), zero(), zero()) }
|
2014-05-25 09:43:51 +00:00
|
|
|
/// A unit vector in the `y` direction.
|
2014-04-14 01:30:24 +00:00
|
|
|
#[inline] pub fn unit_y() -> Vector3<S> { Vector3::new(zero(), one(), zero()) }
|
2014-05-25 09:43:51 +00:00
|
|
|
/// A unit vector in the `w` direction.
|
2014-04-14 01:30:24 +00:00
|
|
|
#[inline] pub fn unit_z() -> Vector3<S> { Vector3::new(zero(), zero(), 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]
|
2014-04-14 01:30:24 +00:00
|
|
|
pub fn cross(&self, other: &Vector3<S>) -> Vector3<S> {
|
|
|
|
Vector3::new((self.y * other.z) - (self.z * other.y),
|
2013-09-03 03:54:03 +00:00
|
|
|
(self.z * other.x) - (self.x * other.z),
|
|
|
|
(self.x * other.y) - (self.y * other.x))
|
|
|
|
}
|
2013-09-06 02:32:07 +00:00
|
|
|
|
|
|
|
/// Calculates the cross product of the vector and `other`, then stores the
|
|
|
|
/// result in `self`.
|
|
|
|
#[inline]
|
2014-04-14 01:30:24 +00:00
|
|
|
pub fn cross_self(&mut self, other: &Vector3<S>) {
|
2013-09-06 02:32:07 +00:00
|
|
|
*self = self.cross(other)
|
|
|
|
}
|
2014-01-23 16:13:53 +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]
|
2014-04-14 01:30:24 +00:00
|
|
|
pub fn extend(&self, w: S)-> Vector4<S> {
|
|
|
|
Vector4::new(self.x.clone(), self.y.clone(), self.z.clone(), 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]
|
2014-04-14 01:30:24 +00:00
|
|
|
pub fn truncate(&self)-> Vector2<S> {
|
2014-05-25 09:43:51 +00:00
|
|
|
Vector2::new(self.x.clone(), self.y.clone())
|
2014-01-23 16:13:53 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Operations specific to numeric four-dimensional vectors.
|
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.
|
2014-04-14 01:30:24 +00:00
|
|
|
#[inline] pub fn unit_x() -> Vector4<S> { Vector4::new(one(), zero(), zero(), zero()) }
|
2014-05-25 09:43:51 +00:00
|
|
|
/// A unit vector in the `y` direction.
|
2014-04-14 01:30:24 +00:00
|
|
|
#[inline] pub fn unit_y() -> Vector4<S> { Vector4::new(zero(), one(), zero(), zero()) }
|
2014-05-25 09:43:51 +00:00
|
|
|
/// A unit vector in the `z` direction.
|
2014-04-14 01:30:24 +00:00
|
|
|
#[inline] pub fn unit_z() -> Vector4<S> { Vector4::new(zero(), zero(), one(), zero()) }
|
2014-05-25 09:43:51 +00:00
|
|
|
/// A unit vector in the `w` direction.
|
2014-04-14 01:30:24 +00:00
|
|
|
#[inline] pub fn unit_w() -> Vector4<S> { Vector4::new(zero(), zero(), zero(), 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]
|
2014-04-14 01:30:24 +00:00
|
|
|
pub fn truncate(&self)-> Vector3<S> {
|
2014-05-25 09:43:51 +00:00
|
|
|
Vector3::new(self.x.clone(), self.y.clone(), self.z.clone())
|
2014-01-23 16:13:53 +00:00
|
|
|
}
|
2014-06-05 07:58:09 +00:00
|
|
|
|
|
|
|
/// Create a `Vector3`, dropping the nth element
|
|
|
|
#[inline]
|
|
|
|
pub fn truncate_n(&self, n: int)-> Vector3<S> {
|
|
|
|
match n {
|
|
|
|
0 => Vector3::new(self.y.clone(), self.z.clone(), self.w.clone()),
|
|
|
|
1 => Vector3::new(self.x.clone(), self.z.clone(), self.w.clone()),
|
|
|
|
2 => Vector3::new(self.x.clone(), self.y.clone(), self.w.clone()),
|
|
|
|
3 => Vector3::new(self.x.clone(), self.y.clone(), self.z.clone()),
|
|
|
|
_ => fail!("{} is out of range", n)
|
|
|
|
}
|
|
|
|
}
|
2013-09-03 03:54:03 +00:00
|
|
|
}
|
|
|
|
|
2013-09-03 06:37:06 +00:00
|
|
|
/// Specifies geometric operations for vectors. This is only implemented for
|
|
|
|
/// 2-dimensional and 3-dimensional vectors.
|
2014-05-28 01:59:03 +00:00
|
|
|
pub trait EuclideanVector<S: BaseFloat>: Vector<S>
|
|
|
|
+ ApproxEq<S> {
|
2014-05-25 09:43:51 +00:00
|
|
|
/// Returns `true` if the vector is perpendicular (at right angles) to the
|
|
|
|
/// other vector.
|
2013-09-03 03:54:03 +00:00
|
|
|
fn is_perpendicular(&self, other: &Self) -> bool {
|
|
|
|
self.dot(other).approx_eq(&zero())
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Returns the squared length of the vector. This does not perform an
|
|
|
|
/// expensive square root operation like in the `length` method and can
|
|
|
|
/// therefore be more efficient for comparing the lengths of two vectors.
|
|
|
|
#[inline]
|
|
|
|
fn length2(&self) -> S {
|
|
|
|
self.dot(self)
|
|
|
|
}
|
|
|
|
|
|
|
|
/// The norm of the vector.
|
|
|
|
#[inline]
|
|
|
|
fn length(&self) -> S {
|
2014-04-02 09:24:04 +00:00
|
|
|
self.dot(self).sqrt()
|
2013-09-03 03:54:03 +00:00
|
|
|
}
|
|
|
|
|
2014-05-25 09:43:51 +00:00
|
|
|
/// The angle between the vector and `other`, in radians.
|
2013-09-04 05:29:53 +00:00
|
|
|
fn angle(&self, other: &Self) -> Rad<S>;
|
2013-09-03 03:54:03 +00:00
|
|
|
|
|
|
|
/// Returns a vector with the same direction, but with a `length` (or
|
|
|
|
/// `norm`) of `1`.
|
|
|
|
#[inline]
|
|
|
|
fn normalize(&self) -> Self {
|
|
|
|
self.normalize_to(one::<S>())
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Returns a vector with the same direction and a given `length`.
|
|
|
|
#[inline]
|
|
|
|
fn normalize_to(&self, length: S) -> Self {
|
|
|
|
self.mul_s(length / self.length())
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Returns the result of linarly interpolating the length of the vector
|
2013-09-03 12:12:54 +00:00
|
|
|
/// towards the length of `other` by the specified amount.
|
2013-09-03 03:54:03 +00:00
|
|
|
#[inline]
|
|
|
|
fn lerp(&self, other: &Self, amount: S) -> Self {
|
|
|
|
self.add_v(&other.sub_v(self).mul_s(amount))
|
|
|
|
}
|
2013-09-03 12:12:54 +00:00
|
|
|
|
|
|
|
/// Normalises the vector to a length of `1`.
|
|
|
|
#[inline]
|
|
|
|
fn normalize_self(&mut self) {
|
|
|
|
let rlen = self.length().recip();
|
|
|
|
self.mul_self_s(rlen);
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Normalizes the vector to `length`.
|
|
|
|
#[inline]
|
|
|
|
fn normalize_self_to(&mut self, length: S) {
|
|
|
|
let n = length / self.length();
|
|
|
|
self.mul_self_s(n);
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Linearly interpolates the length of the vector towards the length of
|
|
|
|
/// `other` by the specified amount.
|
|
|
|
fn lerp_self(&mut self, other: &Self, amount: S) {
|
|
|
|
let v = other.sub_v(self).mul_s(amount);
|
|
|
|
self.add_self_v(&v);
|
|
|
|
}
|
2013-09-03 03:54:03 +00:00
|
|
|
}
|
|
|
|
|
2014-05-28 01:59:03 +00:00
|
|
|
impl<S: BaseFloat> EuclideanVector<S> for Vector2<S> {
|
2013-09-03 03:54:03 +00:00
|
|
|
#[inline]
|
2014-04-14 01:30:24 +00:00
|
|
|
fn angle(&self, other: &Vector2<S>) -> Rad<S> {
|
2013-09-03 03:54:03 +00:00
|
|
|
atan2(self.perp_dot(other), self.dot(other))
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-05-28 01:59:03 +00:00
|
|
|
impl<S: BaseFloat> EuclideanVector<S> for Vector3<S> {
|
2013-09-03 03:54:03 +00:00
|
|
|
#[inline]
|
2014-04-14 01:30:24 +00:00
|
|
|
fn angle(&self, other: &Vector3<S>) -> Rad<S> {
|
2013-09-03 03:54:03 +00:00
|
|
|
atan2(self.cross(other).length(), self.dot(other))
|
|
|
|
}
|
|
|
|
}
|
2013-09-03 07:33:33 +00:00
|
|
|
|
2014-05-28 01:59:03 +00:00
|
|
|
impl<S: BaseFloat> EuclideanVector<S> for Vector4<S> {
|
2013-09-06 06:39:15 +00:00
|
|
|
#[inline]
|
2014-04-14 01:30:24 +00:00
|
|
|
fn angle(&self, other: &Vector4<S>) -> Rad<S> {
|
2013-09-06 06:39:15 +00:00
|
|
|
acos(self.dot(other) / (self.length() * other.length()))
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-05-28 01:59:03 +00:00
|
|
|
impl<S: BaseNum> fmt::Show for Vector2<S> {
|
2014-02-25 08:56:22 +00:00
|
|
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
2014-05-16 20:11:27 +00:00
|
|
|
write!(f, "[{}, {}]", self.x, self.y)
|
2013-09-03 07:33:33 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-05-28 01:59:03 +00:00
|
|
|
impl<S: BaseNum> fmt::Show for Vector3<S> {
|
2014-02-25 08:56:22 +00:00
|
|
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
2014-05-16 20:11:27 +00:00
|
|
|
write!(f, "[{}, {}, {}]", self.x, self.y, self.z)
|
2013-09-03 07:33:33 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-05-28 01:59:03 +00:00
|
|
|
impl<S: BaseNum> fmt::Show for Vector4<S> {
|
2014-02-25 08:56:22 +00:00
|
|
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
2014-05-16 20:11:27 +00:00
|
|
|
write!(f, "[{}, {}, {}, {}]", self.x, self.y, self.z, self.w)
|
2013-09-03 07:33:33 +00:00
|
|
|
}
|
|
|
|
}
|