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}