#![macro_use] macro_rules! origin_impl( ($t: ident, $($compN: ident),+) => ( impl Origin for $t { #[inline] fn origin() -> $t { $t { $($compN: ::zero() ),+ } } #[inline] fn is_origin(&self) -> bool { $(self.$compN.is_zero() )&&+ } } ) ); macro_rules! point_sub_impl( ($t: ident, $tv: ident) => ( impl> Sub<$t> for $t { type Output = $tv; #[inline] fn sub(self, right: $t) -> $tv { *self.as_vector() - *right.as_vector() } } ) ); macro_rules! point_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),+) } } impl> AddAssign<$tv> for $t { #[inline] fn add_assign(&mut self, right: $tv) { $( self.$compN += right.$compN; )+ } } ) ); macro_rules! point_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),+) } } impl> SubAssign<$tv> for $t { #[inline] fn sub_assign(&mut self, right: $tv) { $( self.$compN -= right.$compN; )+ } } ) ); macro_rules! point_as_vec_impl( ($t: ident, $tv: ident, $($compN: ident),+) => ( impl $t { /// Converts this point to its associated vector. #[inline] pub fn to_vector(self) -> $tv { $tv::new( $(self.$compN),+ ) } /// Converts a reference to this point to a reference to its associated vector. #[inline] pub fn as_vector<'a>(&'a self) -> &'a $tv { unsafe { mem::transmute(self) } } #[inline] fn set_coords(&mut self, v: $tv) { $(self.$compN = v.$compN;)+ } } impl PointAsVector for $t { type Vector = $tv; #[inline] fn to_vector(self) -> $tv { self.to_vector() } #[inline] fn as_vector<'a>(&'a self) -> &'a $tv { self.as_vector() } #[inline] fn set_coords(&mut self, v: $tv) { self.set_coords(v) } } ) ); macro_rules! point_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 = Origin::origin(); $( res.$compN = self.$compN; )+ res.$extra = ::one(); res } } ) ); macro_rules! point_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 = Origin::origin(); $( res.$compN = v.$compN / v.$extra; )+ res } } ) ); macro_rules! num_float_point_impl( ($t: ident, $tv: ident) => ( impl NumPoint for $t where N: BaseNum { } impl FloatPoint for $t where N: BaseFloat + ApproxEq { } ) ); macro_rules! arbitrary_point_impl( ($t: ident, $($compN: ident),*) => ( #[cfg(feature="arbitrary")] impl Arbitrary for $t { #[inline] fn arbitrary(g: &mut G) -> $t { $t { $($compN: Arbitrary::arbitrary(g),)* } } } ) ); macro_rules! point_display_impl( ($t: ident) => ( impl fmt::Display for $t { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { // FIXME: differenciate them from vectors ? try!(write!(f, "(")); let mut it = self.iter(); try!(write!(f, "{}", *it.next().unwrap())); for comp in it { try!(write!(f, ", {}", *comp)); } write!(f, ")") } } ) );