ncollide3d/query/point/
point_ball.rs

1use na;
2use simba::scalar::RealField;
3
4use crate::math::{Isometry, Point};
5use crate::query::{PointProjection, PointQuery};
6use crate::shape::{Ball, FeatureId};
7
8impl<N: RealField + Copy> PointQuery<N> for Ball<N> {
9    #[inline]
10    fn project_point(&self, m: &Isometry<N>, pt: &Point<N>, solid: bool) -> PointProjection<N> {
11        let ls_pt = m.inverse_transform_point(pt);
12        let distance_squared = ls_pt.coords.norm_squared();
13
14        let inside = distance_squared <= self.radius * self.radius;
15
16        if inside && solid {
17            PointProjection::new(true, *pt)
18        } else {
19            let ls_proj = Point::from(ls_pt.coords * (self.radius / distance_squared.sqrt()));
20            PointProjection::new(inside, m * ls_proj)
21        }
22    }
23
24    #[inline]
25    fn project_point_with_feature(
26        &self,
27        m: &Isometry<N>,
28        pt: &Point<N>,
29    ) -> (PointProjection<N>, FeatureId) {
30        (self.project_point(m, pt, false), FeatureId::Face(0))
31    }
32
33    #[inline]
34    fn distance_to_point(&self, m: &Isometry<N>, pt: &Point<N>, solid: bool) -> N {
35        let dist = m.inverse_transform_point(pt).coords.norm() - self.radius;
36
37        if solid && dist < na::zero() {
38            na::zero()
39        } else {
40            dist
41        }
42    }
43
44    #[inline]
45    fn contains_point(&self, m: &Isometry<N>, pt: &Point<N>) -> bool {
46        m.inverse_transform_point(pt).coords.norm_squared() <= self.radius * self.radius
47    }
48}