nalgebra/src/vec_macros.rs

558 lines
15 KiB
Rust
Raw Normal View History

2013-07-22 16:26:20 +08:00
#[macro_escape];
macro_rules! new_impl(
2013-08-05 15:44:56 +08:00
($t: ident, $comp0: ident $(,$compN: ident)*) => (
2013-08-05 16:13:44 +08:00
impl<N> $t<N> {
2013-08-05 15:44:56 +08:00
/// Creates a new vector.
#[inline]
2013-08-05 16:13:44 +08:00
pub fn new($comp0: N $( , $compN: N )*) -> $t<N> {
2013-08-05 15:44:56 +08:00
$t {
$comp0: $comp0
$(, $compN: $compN )*
}
}
2013-07-22 16:26:20 +08:00
}
2013-08-05 15:44:56 +08:00
)
2013-07-22 16:26:20 +08:00
)
macro_rules! ord_impl(
2013-08-05 15:44:56 +08:00
($t: ident, $comp0: ident $(,$compN: ident)*) => (
2013-08-05 16:13:44 +08:00
impl<N: Ord> Ord for $t<N> {
2013-08-05 15:44:56 +08:00
#[inline]
2013-08-05 16:13:44 +08:00
fn lt(&self, other: &$t<N>) -> bool {
self.$comp0 < other.$comp0 $(&& self.$compN < other.$compN)*
}
2013-08-05 15:44:56 +08:00
#[inline]
2013-08-05 16:13:44 +08:00
fn le(&self, other: &$t<N>) -> bool {
self.$comp0 <= other.$comp0 $(&& self.$compN <= other.$compN)*
}
2013-08-05 15:44:56 +08:00
#[inline]
2013-08-05 16:13:44 +08:00
fn gt(&self, other: &$t<N>) -> bool {
self.$comp0 > other.$comp0 $(&& self.$compN > other.$compN)*
}
2013-08-05 15:44:56 +08:00
#[inline]
2013-08-05 16:13:44 +08:00
fn ge(&self, other: &$t<N>) -> bool {
self.$comp0 >= other.$comp0 $(&& self.$compN >= other.$compN)*
}
2013-08-05 15:44:56 +08:00
}
)
)
macro_rules! orderable_impl(
2013-08-05 15:44:56 +08:00
($t: ident, $comp0: ident $(,$compN: ident)*) => (
impl<N: Clone + Orderable> Orderable for $t<N> {
2013-08-05 15:44:56 +08:00
#[inline]
2013-08-05 16:13:44 +08:00
fn max(&self, other: &$t<N>) -> $t<N> {
$t::new(self.$comp0.max(&other.$comp0) $(, self.$compN.max(&other.$compN))*)
}
2013-08-05 15:44:56 +08:00
#[inline]
2013-08-05 16:13:44 +08:00
fn min(&self, other: &$t<N>) -> $t<N> {
$t::new(self.$comp0.min(&other.$comp0) $(, self.$compN.min(&other.$compN))*)
}
2013-08-05 15:44:56 +08:00
#[inline]
2013-08-05 16:13:44 +08:00
fn clamp(&self, min: &$t<N>, max: &$t<N>) -> $t<N> {
2013-08-05 15:44:56 +08:00
$t::new(self.$comp0.clamp(&min.$comp0, &max.$comp0)
$(, self.$compN.clamp(&min.$comp0, &max.$comp0))*)
}
}
)
)
macro_rules! vec_axis_impl(
2013-08-05 15:44:56 +08:00
($t: ident, $comp0: ident $(,$compN: ident)*) => (
2013-08-05 16:13:44 +08:00
impl<N: Zero + One> $t<N> {
2013-08-05 15:44:56 +08:00
/// Create a unit vector with its `$comp0` component equal to 1.0.
#[inline]
2013-08-05 16:13:44 +08:00
pub fn $comp0() -> $t<N> {
2013-08-05 15:44:56 +08:00
let mut res: $t<N> = Zero::zero();
res.$comp0 = One::one();
2013-08-05 15:44:56 +08:00
res
}
2013-08-05 15:44:56 +08:00
$(
/// Create a unit vector with its `$compN` component equal to 1.0.
#[inline]
2013-08-05 16:13:44 +08:00
pub fn $compN() -> $t<N> {
2013-08-05 15:44:56 +08:00
let mut res: $t<N> = Zero::zero();
res.$compN = One::one();
res
}
)*
}
2013-08-05 15:44:56 +08:00
)
)
macro_rules! vec_cast_impl(
2013-08-05 15:44:56 +08:00
($t: ident, $comp0: ident $(,$compN: ident)*) => (
impl<Nin: NumCast + Clone, Nout: Clone + NumCast> VecCast<$t<Nout>> for $t<Nin> {
2013-08-05 15:44:56 +08:00
#[inline]
fn from(v: $t<Nin>) -> $t<Nout> {
2013-08-05 16:13:44 +08:00
$t::new(NumCast::from(v.$comp0.clone()) $(, NumCast::from(v.$compN.clone()))*)
}
2013-08-05 15:44:56 +08:00
}
)
)
2013-07-22 16:26:20 +08:00
macro_rules! indexable_impl(
2013-08-05 15:44:56 +08:00
($t: ident, $dim: expr) => (
2013-08-05 16:13:44 +08:00
impl<N: Clone> Indexable<uint, N> for $t<N> {
2013-08-05 15:44:56 +08:00
#[inline]
fn at(&self, i: uint) -> N {
2013-08-05 16:13:44 +08:00
unsafe {
cast::transmute::<&$t<N>, &[N, ..$dim]>(self)[i].clone()
}
}
2013-08-05 15:44:56 +08:00
#[inline]
fn set(&mut self, i: uint, val: N) {
2013-08-05 16:13:44 +08:00
unsafe {
cast::transmute::<&mut $t<N>, &mut [N, ..$dim]>(self)[i] = val
}
}
2013-08-05 15:44:56 +08:00
#[inline]
fn swap(&mut self, i1: uint, i2: uint) {
2013-08-05 16:13:44 +08:00
unsafe {
cast::transmute::<&mut $t<N>, &mut [N, ..$dim]>(self).swap(i1, i2)
}
}
2013-08-05 15:44:56 +08:00
}
)
2013-07-22 16:26:20 +08:00
)
macro_rules! new_repeat_impl(
2013-08-05 15:44:56 +08:00
($t: ident, $param: ident, $comp0: ident $(,$compN: ident)*) => (
2013-08-05 16:13:44 +08:00
impl<N: Clone> $t<N> {
2013-08-05 15:44:56 +08:00
/// Creates a new vector with all its components equal to a given value.
#[inline]
2013-08-05 16:13:44 +08:00
pub fn new_repeat($param: N) -> $t<N> {
2013-08-05 15:44:56 +08:00
$t{
$comp0: $param.clone()
$(, $compN: $param.clone() )*
}
}
2013-07-22 16:26:20 +08:00
}
2013-08-05 15:44:56 +08:00
)
2013-07-22 16:26:20 +08:00
)
macro_rules! iterable_impl(
2013-08-05 15:44:56 +08:00
($t: ident, $dim: expr) => (
2013-08-05 16:13:44 +08:00
impl<N> Iterable<N> for $t<N> {
2013-08-08 02:53:51 +08:00
#[inline]
2013-08-05 16:13:44 +08:00
fn iter<'l>(&'l self) -> VecIterator<'l, N> {
unsafe {
cast::transmute::<&'l $t<N>, &'l [N, ..$dim]>(self).iter()
}
}
2013-08-05 15:44:56 +08:00
}
)
2013-07-22 16:26:20 +08:00
)
macro_rules! iterable_mut_impl(
2013-08-05 15:44:56 +08:00
($t: ident, $dim: expr) => (
2013-08-05 16:13:44 +08:00
impl<N> IterableMut<N> for $t<N> {
2013-08-08 02:53:51 +08:00
#[inline]
2013-08-05 16:13:44 +08:00
fn mut_iter<'l>(&'l mut self) -> VecMutIterator<'l, N> {
unsafe {
cast::transmute::<&'l mut $t<N>, &'l mut [N, ..$dim]>(self).mut_iter()
}
}
2013-08-05 15:44:56 +08:00
}
)
2013-07-22 16:26:20 +08:00
)
macro_rules! dim_impl(
2013-08-05 15:44:56 +08:00
($t: ident, $dim: expr) => (
2013-08-05 16:13:44 +08:00
impl<N> Dim for $t<N> {
2013-08-05 15:44:56 +08:00
#[inline]
fn dim(_: Option<$t<N>>) -> uint {
2013-08-05 16:13:44 +08:00
$dim
}
2013-08-05 15:44:56 +08:00
}
)
2013-07-22 16:26:20 +08:00
)
macro_rules! basis_impl(
2013-08-05 15:44:56 +08:00
($t: ident, $dim: expr) => (
impl<N: Clone + Num + Algebraic + ApproxEq<N>> Basis for $t<N> {
2013-08-08 02:53:51 +08:00
#[inline]
fn canonical_basis(f: &fn($t<N>) -> bool) {
2013-08-05 16:13:44 +08:00
for i in range(0u, $dim) {
2013-08-05 15:44:56 +08:00
let mut basis_element : $t<N> = Zero::zero();
basis_element.set(i, One::one());
if !f(basis_element) { return }
2013-08-05 15:44:56 +08:00
}
}
2013-08-08 02:53:51 +08:00
#[inline]
fn orthonormal_subspace_basis(&self, f: &fn($t<N>) -> bool) {
2013-08-05 15:44:56 +08:00
// compute the basis of the orthogonal subspace using Gram-Schmidt
// orthogonalization algorithm
let mut basis: ~[$t<N>] = ~[];
2013-08-05 16:13:44 +08:00
for i in range(0u, $dim) {
2013-08-05 15:44:56 +08:00
let mut basis_element : $t<N> = Zero::zero();
basis_element.set(i, One::one());
2013-08-05 16:13:44 +08:00
if basis.len() == $dim - 1 {
break;
}
2013-08-05 15:44:56 +08:00
let mut elt = basis_element.clone();
elt = elt - *self * basis_element.dot(self);
2013-08-05 15:44:56 +08:00
2013-08-05 16:13:44 +08:00
for v in basis.iter() {
elt = elt - v * elt.dot(v)
2013-08-05 16:13:44 +08:00
};
2013-08-05 15:44:56 +08:00
2013-08-05 16:13:44 +08:00
if !elt.sqnorm().approx_eq(&Zero::zero()) {
2013-08-05 15:44:56 +08:00
let new_element = elt.normalized();
if !f(new_element.clone()) { return };
2013-08-05 15:44:56 +08:00
basis.push(new_element);
}
}
}
2013-07-22 16:26:20 +08:00
}
2013-08-05 15:44:56 +08:00
)
2013-07-22 16:26:20 +08:00
)
macro_rules! add_impl(
2013-08-05 15:44:56 +08:00
($t: ident, $comp0: ident $(,$compN: ident)*) => (
impl<N: Clone + Add<N, N>> Add<$t<N>, $t<N>> for $t<N> {
2013-08-05 15:44:56 +08:00
#[inline]
2013-08-05 16:13:44 +08:00
fn add(&self, other: &$t<N>) -> $t<N> {
$t::new(self.$comp0 + other.$comp0 $(, self.$compN + other.$compN)*)
}
2013-08-05 15:44:56 +08:00
}
)
2013-07-22 16:26:20 +08:00
)
macro_rules! sub_impl(
2013-08-05 15:44:56 +08:00
($t: ident, $comp0: ident $(,$compN: ident)*) => (
impl<N: Clone + Sub<N, N>> Sub<$t<N>, $t<N>> for $t<N> {
2013-08-05 15:44:56 +08:00
#[inline]
2013-08-05 16:13:44 +08:00
fn sub(&self, other: &$t<N>) -> $t<N> {
$t::new(self.$comp0 - other.$comp0 $(, self.$compN - other.$compN)*)
}
2013-08-05 15:44:56 +08:00
}
)
2013-07-22 16:26:20 +08:00
)
macro_rules! neg_impl(
2013-08-05 15:44:56 +08:00
($t: ident, $comp0: ident $(,$compN: ident)*) => (
impl<N: Clone + Neg<N>> Neg<$t<N>> for $t<N> {
2013-08-05 15:44:56 +08:00
#[inline]
2013-08-05 16:13:44 +08:00
fn neg(&self) -> $t<N> {
$t::new(-self.$comp0 $(, -self.$compN )*)
}
2013-08-05 15:44:56 +08:00
}
)
2013-07-22 16:26:20 +08:00
)
macro_rules! dot_impl(
2013-08-05 15:44:56 +08:00
($t: ident, $comp0: ident $(,$compN: ident)*) => (
impl<N: Num + Clone> Vec<N> for $t<N> {
2013-08-05 15:44:56 +08:00
#[inline]
2013-08-05 16:13:44 +08:00
fn dot(&self, other: &$t<N>) -> N {
self.$comp0 * other.$comp0 $(+ self.$compN * other.$compN )*
}
2013-07-22 16:26:20 +08:00
2013-08-05 15:44:56 +08:00
#[inline]
2013-08-05 16:13:44 +08:00
fn sub_dot(&self, a: &$t<N>, b: &$t<N>) -> N {
(self.$comp0 - a.$comp0) * b.$comp0 $(+ (self.$compN - a.$compN) * b.$compN )*
}
2013-08-05 15:44:56 +08:00
}
)
2013-07-22 16:26:20 +08:00
)
macro_rules! scalar_mul_impl(
2013-08-05 15:44:56 +08:00
($t: ident, $comp0: ident $(,$compN: ident)*) => (
impl<N: Clone + Mul<N, N>> Mul<N, $t<N>> for $t<N> {
2013-08-05 15:44:56 +08:00
#[inline]
fn mul(&self, s: &N) -> $t<N> {
2013-08-05 16:13:44 +08:00
$t::new(self.$comp0 * *s $(, self.$compN * *s)*)
}
2013-08-05 15:44:56 +08:00
}
)
2013-07-22 16:26:20 +08:00
)
macro_rules! scalar_div_impl(
2013-08-05 15:44:56 +08:00
($t: ident, $comp0: ident $(,$compN: ident)*) => (
impl<N: Clone + Div<N, N>> Div<N, $t<N>> for $t<N> {
2013-08-05 15:44:56 +08:00
#[inline]
fn div(&self, s: &N) -> $t<N> {
2013-08-05 16:13:44 +08:00
$t::new(self.$comp0 / *s $(, self.$compN / *s)*)
}
2013-08-05 15:44:56 +08:00
}
)
2013-07-22 16:26:20 +08:00
)
macro_rules! scalar_add_impl(
2013-08-05 15:44:56 +08:00
($t: ident, $comp0: ident $(,$compN: ident)*) => (
impl<N: Clone + Add<N, N>> ScalarAdd<N> for $t<N> {
2013-08-05 15:44:56 +08:00
#[inline]
2013-08-05 16:13:44 +08:00
fn scalar_add(&self, s: &N) -> $t<N> {
$t::new(self.$comp0 + *s $(, self.$compN + *s)*)
}
2013-08-05 15:44:56 +08:00
#[inline]
2013-08-05 16:13:44 +08:00
fn scalar_add_inplace(&mut self, s: &N) {
2013-08-05 15:44:56 +08:00
self.$comp0 = self.$comp0 + *s;
$(self.$compN = self.$compN + *s;)*
}
}
)
2013-07-22 16:26:20 +08:00
)
macro_rules! scalar_sub_impl(
2013-08-05 15:44:56 +08:00
($t: ident, $comp0: ident $(,$compN: ident)*) => (
impl<N: Clone + Sub<N, N>> ScalarSub<N> for $t<N> {
2013-08-05 15:44:56 +08:00
#[inline]
2013-08-05 16:13:44 +08:00
fn scalar_sub(&self, s: &N) -> $t<N> {
$t::new(self.$comp0 - *s $(, self.$compN - *s)*)
}
2013-08-05 15:44:56 +08:00
#[inline]
2013-08-05 16:13:44 +08:00
fn scalar_sub_inplace(&mut self, s: &N) {
2013-08-05 15:44:56 +08:00
self.$comp0 = self.$comp0 - *s;
$(self.$compN = self.$compN - *s;)*
}
}
)
2013-07-22 16:26:20 +08:00
)
macro_rules! translation_impl(
2013-08-05 15:44:56 +08:00
($t: ident) => (
2013-08-05 16:13:44 +08:00
impl<N: Clone + Add<N, N> + Neg<N>> Translation<$t<N>> for $t<N> {
2013-08-05 15:44:56 +08:00
#[inline]
2013-08-05 16:13:44 +08:00
fn translation(&self) -> $t<N> {
self.clone()
}
2013-08-05 15:44:56 +08:00
#[inline]
2013-08-05 16:13:44 +08:00
fn inv_translation(&self) -> $t<N> {
-self
}
2013-08-05 15:44:56 +08:00
#[inline]
2013-08-05 16:13:44 +08:00
fn translate_by(&mut self, t: &$t<N>) {
*self = *self + *t;
}
2013-07-22 16:26:20 +08:00
2013-08-05 15:44:56 +08:00
#[inline]
2013-08-05 16:13:44 +08:00
fn translated(&self, t: &$t<N>) -> $t<N> {
self + *t
}
2013-08-05 15:44:56 +08:00
}
)
2013-07-22 16:26:20 +08:00
)
macro_rules! norm_impl(
2013-08-05 15:44:56 +08:00
($t: ident) => (
impl<N: Clone + Num + Algebraic> AlgebraicVec<N> for $t<N> {
2013-08-05 15:44:56 +08:00
#[inline]
2013-08-05 16:13:44 +08:00
fn sqnorm(&self) -> N {
self.dot(self)
}
2013-08-05 15:44:56 +08:00
#[inline]
2013-08-05 16:13:44 +08:00
fn norm(&self) -> N {
self.sqnorm().sqrt()
}
2013-08-05 15:44:56 +08:00
#[inline]
2013-08-05 16:13:44 +08:00
fn normalized(&self) -> $t<N> {
2013-08-05 15:44:56 +08:00
let mut res : $t<N> = self.clone();
res.normalize();
res
}
#[inline]
2013-08-05 16:13:44 +08:00
fn normalize(&mut self) -> N {
2013-08-05 15:44:56 +08:00
let l = self.norm();
*self = *self / l;
2013-08-05 15:44:56 +08:00
l
}
}
)
2013-07-22 16:26:20 +08:00
)
2013-08-15 16:41:47 +08:00
macro_rules! round_impl(
($t: ident, $comp0: ident $(,$compN: ident)*) => (
impl<N: Clone + Round> Round for $t<N> {
2013-08-15 16:41:47 +08:00
fn floor(&self) -> $t<N> {
$t::new(self.$comp0.floor() $(, self.$compN.floor())*)
}
fn ceil(&self) -> $t<N> {
$t::new(self.$comp0.ceil() $(, self.$compN.ceil())*)
}
fn round(&self) -> $t<N> {
$t::new(self.$comp0.round() $(, self.$compN.round())*)
}
fn trunc(&self) -> $t<N> {
$t::new(self.$comp0.trunc() $(, self.$compN.trunc())*)
}
fn fract(&self) -> $t<N> {
$t::new(self.$comp0.fract() $(, self.$compN.fract())*)
}
}
)
)
2013-07-22 16:26:20 +08:00
macro_rules! approx_eq_impl(
2013-08-05 15:44:56 +08:00
($t: ident, $comp0: ident $(,$compN: ident)*) => (
2013-08-05 16:13:44 +08:00
impl<N: ApproxEq<N>> ApproxEq<N> for $t<N> {
2013-08-05 15:44:56 +08:00
#[inline]
2013-08-05 16:13:44 +08:00
fn approx_epsilon() -> N {
fail!("approx_epsilon is broken since rust revision 8693943676487c01fa09f5f3daf0df6a1f71e24d.")
// ApproxEq::<N>::approx_epsilon()
2013-08-05 16:13:44 +08:00
}
2013-08-05 15:44:56 +08:00
#[inline]
2013-08-05 16:13:44 +08:00
fn approx_eq(&self, other: &$t<N>) -> bool {
self.$comp0.approx_eq(&other.$comp0) $(&& self.$compN.approx_eq(&other.$compN))*
}
2013-08-05 15:44:56 +08:00
#[inline]
2013-08-05 16:13:44 +08:00
fn approx_eq_eps(&self, other: &$t<N>, eps: &N) -> bool {
self.$comp0.approx_eq_eps(&other.$comp0, eps) $(&& self.$compN.approx_eq_eps(&other.$compN, eps))*
}
2013-08-05 15:44:56 +08:00
}
)
2013-07-22 16:26:20 +08:00
)
macro_rules! one_impl(
2013-08-05 15:44:56 +08:00
($t: ident) => (
2013-08-05 16:13:44 +08:00
impl<N: Clone + One> One for $t<N> {
2013-08-05 15:44:56 +08:00
#[inline]
2013-08-05 16:13:44 +08:00
fn one() -> $t<N> {
$t::new_repeat(One::one())
}
2013-08-05 15:44:56 +08:00
}
)
2013-07-22 16:26:20 +08:00
)
macro_rules! from_iterator_impl(
2013-08-05 15:44:56 +08:00
($t: ident, $param0: ident $(, $paramN: ident)*) => (
impl<N: Clone> FromIterator<N> for $t<N> {
2013-08-08 02:53:51 +08:00
#[inline]
2013-08-16 16:14:01 +08:00
fn from_iterator<I: Iterator<N>>($param0: &mut I) -> $t<N> {
2013-08-05 16:13:44 +08:00
$t::new($param0.next().unwrap() $(, $paramN.next().unwrap())*)
}
2013-08-05 15:44:56 +08:00
}
)
2013-07-22 16:26:20 +08:00
)
macro_rules! bounded_impl(
2013-08-05 15:44:56 +08:00
($t: ident) => (
2013-08-05 16:13:44 +08:00
impl<N: Bounded + Clone> Bounded for $t<N> {
2013-08-05 15:44:56 +08:00
#[inline]
2013-08-05 16:13:44 +08:00
fn max_value() -> $t<N> {
$t::new_repeat(Bounded::max_value())
}
2013-08-05 15:44:56 +08:00
#[inline]
2013-08-05 16:13:44 +08:00
fn min_value() -> $t<N> {
$t::new_repeat(Bounded::min_value())
}
2013-08-05 15:44:56 +08:00
}
)
2013-07-22 16:26:20 +08:00
)
macro_rules! to_homogeneous_impl(
2013-08-05 15:44:56 +08:00
($t: ident, $t2: ident, $extra: ident, $comp0: ident $(,$compN: ident)*) => (
2013-08-05 16:13:44 +08:00
impl<N: Clone + One + Zero> ToHomogeneous<$t2<N>> for $t<N> {
fn to_homogeneous(&self) -> $t2<N> {
2013-08-05 15:44:56 +08:00
let mut res: $t2<N> = One::one();
res.$comp0 = self.$comp0.clone();
$( res.$compN = self.$compN.clone(); )*
res
}
}
)
2013-07-22 16:26:20 +08:00
)
macro_rules! from_homogeneous_impl(
2013-08-05 15:44:56 +08:00
($t: ident, $t2: ident, $extra: ident, $comp0: ident $(,$compN: ident)*) => (
2013-08-05 16:13:44 +08:00
impl<N: Clone + Div<N, N> + One + Zero> FromHomogeneous<$t2<N>> for $t<N> {
fn from(v: &$t2<N>) -> $t<N> {
2013-08-05 15:44:56 +08:00
let mut res: $t<N> = Zero::zero();
res.$comp0 = v.$comp0.clone();
$( res.$compN = v.$compN.clone(); )*
res = res / v.$extra;
2013-08-05 15:44:56 +08:00
res
}
}
)
2013-07-22 16:26:20 +08:00
)
macro_rules! translate_impl(
($t: ident) => (
impl<N: Clone + Add<N, N> + Sub<N, N>> Translate<$t<N>> for $t<N> {
fn translate(&self, other: &$t<N>) -> $t<N> {
*other + *self
}
fn inv_translate(&self, other: &$t<N>) -> $t<N> {
*other - *self
}
}
)
)
macro_rules! rotate_impl(
($t: ident) => (
impl<N, O: Clone> Rotate<O> for $t<N> {
fn rotate(&self, other: &O) -> O {
other.clone()
}
fn inv_rotate(&self, other: &O) -> O {
other.clone()
}
}
)
)
macro_rules! transform_impl(
($t: ident) => (
impl<N: Clone + Add<N, N> + Sub<N, N>> Transform<$t<N>> for $t<N> {
fn transform(&self, other: &$t<N>) -> $t<N> {
self.translate(other)
}
fn inv_transform(&self, other: &$t<N>) -> $t<N> {
self.inv_translate(other)
}
}
)
)