//! Minkowski sum. use std::ops::{Index, IndexMut, Add, Sub, Mul, Div, AddAssign, MulAssign, DivAssign, Neg}; use na::{Dimension, ApproxEq, Origin, PointAsVector, Axpy, Translate, NumPoint, PartialOrder, PartialOrdering, FloatPoint, Bounded, Repeat}; use na; use shape::Reflection; use math::{Scalar, Point, Vector}; /// Type of an implicit representation of the Configuration Space Obstacle /// formed by two geometric objects. pub type CSO<'a, M, G1, G2> = MinkowskiSum<'a, M, G1, Reflection<'a, G2>>; pub type AnnotatedCSO<'a, M, G1, G2> = AnnotatedMinkowskiSum<'a, M, G1, Reflection<'a, G2>>; /** * SupportMap representation of the Minkowski sum of two shapes. * * The only way to obtain the sum points is to use its support mapping * function. * * - `G1`: type of the first object involved on the sum. * - `G2`: type of the second object involved on the sum. */ #[derive(Debug)] pub struct MinkowskiSum<'a, M: 'a, G1: ?Sized + 'a, G2: ?Sized + 'a> { m1: &'a M, g1: &'a G1, m2: &'a M, g2: &'a G2 } impl<'a, M, G1: ?Sized, G2: ?Sized> MinkowskiSum<'a, M, G1, G2> { /** * Builds the Minkowski sum of two shapes. Since the representation is * implicit, this is done in constant time. */ #[inline] pub fn new(m1: &'a M, g1: &'a G1, m2: &'a M, g2: &'a G2) -> MinkowskiSum<'a, M, G1, G2> { MinkowskiSum { m1: m1, g1: g1, m2: m2, g2: g2 } } /// The transformation matrix of the first shape of this Minkowski Sum. #[inline] pub fn m1(&self) -> &'a M { self.m1 } /// The transformation matrix of the second shape of this Minkowski Sum. #[inline] pub fn m2(&self) -> &'a M { self.m2 } /// The first shape of this Minkowski Sum. #[inline] pub fn g1(&self) -> &'a G1 { self.g1 } /// The second shape of this Minkowski Sum. #[inline] pub fn g2(&self) -> &'a G2 { self.g2 } } /** * Same as the MinkowskiSum but with a support mapping which keeps track of the * original supports points from the two wrapped shapes. * * * `G1`: type of the first object involved on the sum. * * `G2`: type of the second object involved on the sum. */ #[derive(Debug)] pub struct AnnotatedMinkowskiSum<'a, M: 'a, G1: ?Sized + 'a, G2: ?Sized + 'a> { m1: &'a M, g1: &'a G1, m2: &'a M, g2: &'a G2 } impl<'a, M, G1: ?Sized, G2: ?Sized> AnnotatedMinkowskiSum<'a, M, G1, G2> { /** * Builds the Minkowski sum of two shapes. Since the representation is * implicit, this is done in constant time. */ #[inline] pub fn new(m1: &'a M, g1: &'a G1, m2: &'a M, g2: &'a G2) -> AnnotatedMinkowskiSum<'a, M, G1, G2> { AnnotatedMinkowskiSum { m1: m1, g1: g1, m2: m2, g2: g2 } } /// The transformation matrix of the first shape of this Minkowski Sum. #[inline] pub fn m1(&self) -> &'a M { self.m1 } /// The transformation matrix of the second shape of this Minkowski Sum. #[inline] pub fn m2(&self) -> &'a M { self.m2 } /// The first shape of this Minkowski Sum. #[inline] pub fn g1(&self) -> &'a G1 { self.g1 } /// The second shape of this Minkowski Sum. #[inline] pub fn g2(&self) -> &'a G2 { self.g2 } } // FIXME: AnnotatedPoint is not a good name. // XXX: do not hide the documentation! #[doc(hidden)] #[derive(Clone, Copy, Debug, RustcEncodable, RustcDecodable)] pub struct AnnotatedPoint

{ orig1: P, orig2: P, point: P } impl

AnnotatedPoint

{ #[doc(hidden)] #[inline] pub fn new(orig1: P, orig2: P, point: P) -> AnnotatedPoint

{ AnnotatedPoint { orig1: orig1, orig2: orig2, point: point } } #[doc(hidden)] #[inline] pub fn point<'r>(&'r self) -> &'r P { &self.point } #[doc(hidden)] #[inline] pub fn orig1(&self) -> &P { &self.orig1 } #[doc(hidden)] #[inline] pub fn orig2(&self) -> &P { &self.orig2 } #[doc(hidden)] #[inline] pub fn translate_1>(&mut self, t: &V) { self.orig1 = na::translate(t, &self.orig1); self.point = na::translate(t, &self.point); } #[doc(hidden)] #[inline] pub fn translate_2>(&mut self, t: &V) { self.orig2 = na::translate(t, &self.orig2); self.point = na::translate(t, &self.point); } } impl PointAsVector for AnnotatedPoint

{ type Vector = P::Vector; #[inline] fn to_vector(self) -> P::Vector { self.point.to_vector() } #[inline] fn as_vector<'a>(&'a self) -> &'a P::Vector { self.point.as_vector() } #[inline] fn set_coords(&mut self, _: P::Vector) { panic!(".set_coords is not implemented for annotated points.") } } impl> Index for AnnotatedPoint

{ type Output = P::Output; #[inline] fn index(&self, i: usize) -> &P::Output { &self.point[i] } } impl> IndexMut for AnnotatedPoint

{ #[inline] fn index_mut(&mut self, _: usize) -> &mut P::Output { unimplemented!() } } impl

PartialOrder for AnnotatedPoint

{ fn inf(&self, _: &AnnotatedPoint

) -> AnnotatedPoint

{ unimplemented!() } fn sup(&self, _: &AnnotatedPoint

) -> AnnotatedPoint

{ unimplemented!() } fn partial_cmp(&self, _: &AnnotatedPoint

) -> PartialOrdering { unimplemented!() } } impl Origin for AnnotatedPoint

{ #[inline] fn origin() -> AnnotatedPoint

{ AnnotatedPoint::new(na::origin(), na::origin(), na::origin()) } #[inline] fn is_origin(&self) -> bool { self.point.is_origin() } } impl

Add for AnnotatedPoint

where P: Point { type Output = AnnotatedPoint

; #[inline] fn add(self, other: P::Vect) -> AnnotatedPoint

{ let _0_5: ::Scalar = na::cast(0.5f64); AnnotatedPoint::new( self.orig1 + other * _0_5, self.orig2 + other * _0_5, self.point + other ) } } impl

AddAssign for AnnotatedPoint

where P: Point { #[inline] fn add_assign(&mut self, other: P::Vect) { let _0_5: ::Scalar = na::cast(0.5f64); self.orig1 += other * _0_5; self.orig2 += other * _0_5; self.point += other; } } impl> Axpy for AnnotatedPoint

{ #[inline] fn axpy(&mut self, a: &N, x: &AnnotatedPoint

) { self.orig1.axpy(a, &x.orig1); self.orig2.axpy(a, &x.orig2); self.point.axpy(a, &x.point); } } impl> Sub> for AnnotatedPoint

{ type Output = P::Output; #[inline] fn sub(self, other: AnnotatedPoint

) -> P::Output { self.point - other.point } } impl> Neg for AnnotatedPoint

{ type Output = AnnotatedPoint

; #[inline] fn neg(self) -> AnnotatedPoint

{ AnnotatedPoint::new(-self.orig1, -self.orig2, -self.point) } } impl Dimension for AnnotatedPoint

{ #[inline] fn dimension(_: Option>) -> usize { na::dimension::

() } } impl> Div for AnnotatedPoint

{ type Output = AnnotatedPoint

; #[inline] fn div(self, n: N) -> AnnotatedPoint

{ AnnotatedPoint::new(self.orig1 / n, self.orig2 / n, self.point / n) } } impl> DivAssign for AnnotatedPoint

{ #[inline] fn div_assign(&mut self, n: N) { self.orig1 /= n; self.orig2 /= n; self.point /= n; } } impl> Mul for AnnotatedPoint

{ type Output = AnnotatedPoint

; #[inline] fn mul(self, n: N) -> AnnotatedPoint

{ AnnotatedPoint::new(self.orig1 * n, self.orig2 * n, self.point * n) } } impl> MulAssign for AnnotatedPoint

{ #[inline] fn mul_assign(&mut self, n: N) { self.orig1 *= n; self.orig2 *= n; self.point *= n; } } impl PartialEq for AnnotatedPoint

{ #[inline] fn eq(&self, other: &AnnotatedPoint

) -> bool { self.point == other.point } #[inline] fn ne(&self, other: &AnnotatedPoint

) -> bool { self.point != other.point } } impl ApproxEq for AnnotatedPoint

where N: Scalar, P: ApproxEq { #[inline] fn approx_epsilon(_: Option>) -> N { ApproxEq::approx_epsilon(None::) } #[inline] fn approx_eq_eps(&self, other: &AnnotatedPoint

, eps: &N) -> bool { self.point.approx_eq_eps(&other.point, eps) } #[inline] fn approx_ulps(_: Option>) -> u32 { ApproxEq::approx_ulps(None::) } #[inline] fn approx_eq_ulps(&self, other: &AnnotatedPoint

, ulps: u32) -> bool { self.point.approx_eq_ulps(&other.point, ulps) } } impl

Bounded for AnnotatedPoint

{ fn min_value() -> AnnotatedPoint

{ unimplemented!() } fn max_value() -> AnnotatedPoint

{ unimplemented!() } } impl Repeat<::Scalar> for AnnotatedPoint

{ fn repeat(_: ::Scalar) -> AnnotatedPoint

{ panic!("`Repeat` is not implemented for `AnnotatedPoint`."); } } impl

NumPoint<::Scalar> for AnnotatedPoint

where P: Point { } impl

FloatPoint<::Scalar> for AnnotatedPoint

where P: Point { } impl

Point for AnnotatedPoint

where P: Point { type Vect = P::Vect; }