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