#![macro_use] macro_rules! orig_impl( ($t: ident, $($compN: ident),+) => ( impl Orig for $t { #[inline] fn orig() -> $t { $t { $($compN: ::zero() ),+ } } #[inline] fn is_orig(&self) -> bool { $(self.$compN.is_zero() )&&+ } } ) ); macro_rules! pnt_sub_impl( ($t: ident, $tv: ident) => ( impl> Sub<$t> for $t { type Output = $tv; #[inline] fn sub(self, right: $t) -> $tv { *self.as_vec() - *right.as_vec() } } ) ); macro_rules! pnt_add_vec_impl( ($t: ident, $tv: ident, $($compN: ident),+) => ( impl> Add<$tv> for $t { type Output = $t; #[inline] fn add(self, right: $tv) -> $t { $t::new($(self.$compN + right.$compN),+) } } ) ); macro_rules! pnt_sub_vec_impl( ($t: ident, $tv: ident, $($compN: ident),+) => ( impl> Sub<$tv> for $t { type Output = $t; #[inline] fn sub(self, right: $tv) -> $t { $t::new($(self.$compN - right.$compN),+) } } ) ); macro_rules! pnt_as_vec_impl( ($t: ident, $tv: ident, $($compN: ident),+) => ( impl $t { /// Converts this point to its associated vector. #[inline] pub fn to_vec(self) -> $tv { $tv::new( $(self.$compN),+ ) } /// Converts a reference to this point to a reference to its associated vector. #[inline] pub fn as_vec<'a>(&'a self) -> &'a $tv { unsafe { mem::transmute(self) } } #[inline] fn set_coords(&mut self, v: $tv) { $(self.$compN = v.$compN;)+ } } impl PntAsVec<$tv> for $t { #[inline] fn to_vec(self) -> $tv { self.to_vec() } #[inline] fn as_vec<'a>(&'a self) -> &'a $tv { self.as_vec() } #[inline] fn set_coords(&mut self, v: $tv) { self.set_coords(v) } } ) ); macro_rules! pnt_to_homogeneous_impl( ($t: ident, $t2: ident, $extra: ident, $($compN: ident),+) => ( impl ToHomogeneous<$t2> for $t { fn to_homogeneous(&self) -> $t2 { let mut res: $t2 = Orig::orig(); $( res.$compN = self.$compN; )+ res.$extra = ::one(); res } } ) ); macro_rules! pnt_from_homogeneous_impl( ($t: ident, $t2: ident, $extra: ident, $($compN: ident),+) => ( impl + One + Zero> FromHomogeneous<$t2> for $t { fn from(v: &$t2) -> $t { let mut res: $t = Orig::orig(); $( res.$compN = v.$compN / v.$extra; )+ res } } ) ); macro_rules! num_float_pnt_impl( ($t: ident, $tv: ident) => ( impl NumPnt> for $t where N: BaseNum { } impl FloatPnt> for $t where N: BaseFloat + ApproxEq { } ) );