1use crate::math::{Isometry, Point, Vector};
2use crate::shape::SupportMap;
3use na::{RealField, Unit};
4use std::ops::Sub;
56/// A point of a Configuration-Space Obstacle.
7///
8/// A Configuration-Space Obstacle (CSO) is the result of the
9/// Minkowski Difference of two solids. In other words, each of its
10/// points correspond to the difference of two point, each belonging
11/// to a different solid.
12#[derive(Copy, Clone, Debug, PartialEq)]
13pub struct CSOPoint<N: RealField + Copy> {
14/// The point on the CSO. This is equal to `self.orig1 - self.orig2`, unless this CSOPoint
15 /// has been translated with self.translate.
16pub point: Point<N>,
17/// The original point on the first shape used to compute `self.point`.
18pub orig1: Point<N>,
19/// The original point on the second shape used to compute `self.point`.
20pub orig2: Point<N>,
21}
2223impl<N: RealField + Copy> CSOPoint<N> {
24/// Initializes a CSO point with `orig1 - orig2`.
25pub fn new(orig1: Point<N>, orig2: Point<N>) -> Self {
26let point = Point::from(orig1 - orig2);
27Self::new_with_point(point, orig1, orig2)
28 }
2930/// Initializes a CSO point with all information provided.
31 ///
32 /// It is assumed, but not checked, that `point == orig1 - orig2`.
33pub fn new_with_point(point: Point<N>, orig1: Point<N>, orig2: Point<N>) -> Self {
34 CSOPoint {
35 point,
36 orig1,
37 orig2,
38 }
39 }
4041/// Initializes a CSO point where both original points are equal.
42pub fn single_point(point: Point<N>) -> Self {
43Self::new_with_point(point, point, Point::origin())
44 }
4546/// CSO point where all components are set to zero.
47pub fn origin() -> Self {
48 CSOPoint::new(Point::origin(), Point::origin())
49 }
5051/// Computes the support point of the CSO of `g1` and `g2` toward the unit direction `dir`.
52pub fn from_shapes_toward<G1: ?Sized, G2: ?Sized>(
53 m1: &Isometry<N>,
54 g1: &G1,
55 m2: &Isometry<N>,
56 g2: &G2,
57 dir: &Unit<Vector<N>>,
58 ) -> Self
59where
60G1: SupportMap<N>,
61 G2: SupportMap<N>,
62 {
63let sp1 = g1.support_point_toward(m1, dir);
64let sp2 = g2.support_point_toward(m2, &-*dir);
6566 CSOPoint::new(sp1, sp2)
67 }
6869/// Computes the support point of the CSO of `g1` and `g2` toward the direction `dir`.
70pub fn from_shapes<G1: ?Sized, G2: ?Sized>(
71 m1: &Isometry<N>,
72 g1: &G1,
73 m2: &Isometry<N>,
74 g2: &G2,
75 dir: &Vector<N>,
76 ) -> Self
77where
78G1: SupportMap<N>,
79 G2: SupportMap<N>,
80 {
81let sp1 = g1.support_point(m1, dir);
82let sp2 = g2.support_point(m2, &-*dir);
8384 CSOPoint::new(sp1, sp2)
85 }
8687/// Translate the CSO point.
88pub fn translate(&self, dir: &Vector<N>) -> Self {
89 CSOPoint::new_with_point(self.point + dir, self.orig1, self.orig2)
90 }
9192/// Translate in-place the CSO point.
93pub fn translate_mut(&mut self, dir: &Vector<N>) {
94self.point += dir;
95 }
96}
9798impl<N: RealField + Copy> Sub<CSOPoint<N>> for CSOPoint<N> {
99type Output = Vector<N>;
100101#[inline]
102fn sub(self, rhs: CSOPoint<N>) -> Vector<N> {
103self.point - rhs.point
104 }
105}