pub enum ClosestPoints {
Intersecting,
WithinMargin(Point<f32>, Point<f32>),
Disjoint,
}Expand description
Result of a closest points query between two shapes.
This enum represents the outcome of computing closest points between two shapes, taking into account a user-defined maximum search distance. It’s useful for proximity-based gameplay mechanics, AI perception systems, and efficient spatial queries where you only care about nearby objects.
§Variants
The result depends on the relationship between the shapes and the max_dist parameter:
Intersecting: Shapes are overlapping (penetrating or touching)WithinMargin: Shapes are separated but within the search distanceDisjoint: Shapes are too far apart (beyond the search distance)
§Use Cases
- AI perception: Find nearest enemy within detection range
- Trigger zones: Detect objects approaching a threshold distance
- LOD systems: Compute detailed interactions only for nearby objects
- Physics optimization: Skip expensive computations for distant pairs
§Example
use parry3d::query::{closest_points, ClosestPoints};
use parry3d::shape::Ball;
use nalgebra::Isometry3;
let ball1 = Ball::new(1.0);
let ball2 = Ball::new(1.0);
let pos1 = Isometry3::translation(0.0, 0.0, 0.0);
let pos2 = Isometry3::translation(5.0, 0.0, 0.0);
// Search for closest points within 10.0 units
let result = closest_points(&pos1, &ball1, &pos2, &ball2, 10.0).unwrap();
match result {
ClosestPoints::Intersecting => {
println!("Shapes are overlapping!");
}
ClosestPoints::WithinMargin(pt1, pt2) => {
println!("Closest point on shape1: {:?}", pt1);
println!("Closest point on shape2: {:?}", pt2);
let distance = (pt2 - pt1).norm();
println!("Distance between shapes: {}", distance);
}
ClosestPoints::Disjoint => {
println!("Shapes are more than 10.0 units apart");
}
}§See Also
closest_points- Main function to compute this resultdistance- For just the distance valuecontact- For detailed contact information when intersecting
Variants§
Intersecting
The two shapes are intersecting (overlapping or touching).
When shapes intersect, their closest points are not well-defined, as there
are infinitely many contact points. Use contact
instead to get penetration depth and contact normals.
§Example
use parry3d::query::{closest_points, ClosestPoints};
use parry3d::shape::Ball;
use nalgebra::Isometry3;
let ball1 = Ball::new(2.0);
let ball2 = Ball::new(2.0);
// Overlapping balls (centers 3.0 apart, combined radii 4.0)
let pos1 = Isometry3::translation(0.0, 0.0, 0.0);
let pos2 = Isometry3::translation(3.0, 0.0, 0.0);
let result = closest_points(&pos1, &ball1, &pos2, &ball2, 10.0).unwrap();
assert_eq!(result, ClosestPoints::Intersecting);WithinMargin(Point<f32>, Point<f32>)
The shapes are separated but within the specified maximum distance.
Contains the two closest points in world-space coordinates:
- First point: Closest point on the surface of the first shape
- Second point: Closest point on the surface of the second shape
The distance between the shapes equals the distance between these two points.
§Example
use parry3d::query::{closest_points, ClosestPoints};
use parry3d::shape::Ball;
use nalgebra::Isometry3;
let ball1 = Ball::new(1.0);
let ball2 = Ball::new(1.0);
// Balls separated by 3.0 units (centers 5.0 apart, combined radii 2.0)
let pos1 = Isometry3::translation(0.0, 0.0, 0.0);
let pos2 = Isometry3::translation(5.0, 0.0, 0.0);
let result = closest_points(&pos1, &ball1, &pos2, &ball2, 10.0).unwrap();
if let ClosestPoints::WithinMargin(pt1, pt2) = result {
// Points are on the surface, facing each other
assert!((pt1.x - 1.0).abs() < 1e-5); // ball1 surface at x=1.0
assert!((pt2.x - 4.0).abs() < 1e-5); // ball2 surface at x=4.0
// Distance between points
let dist = (pt2 - pt1).norm();
assert!((dist - 3.0).abs() < 1e-5);
} else {
panic!("Expected WithinMargin");
}Disjoint
The shapes are separated by more than the specified maximum distance.
The actual distance between shapes is unknown (could be much larger than max_dist),
and no closest points are computed. This saves computation when you only care
about nearby objects.
§Example
use parry3d::query::{closest_points, ClosestPoints};
use parry3d::shape::Ball;
use nalgebra::Isometry3;
let ball1 = Ball::new(1.0);
let ball2 = Ball::new(1.0);
// Balls separated by 8.0 units
let pos1 = Isometry3::translation(0.0, 0.0, 0.0);
let pos2 = Isometry3::translation(10.0, 0.0, 0.0);
// Only search within 5.0 units
let result = closest_points(&pos1, &ball1, &pos2, &ball2, 5.0).unwrap();
assert_eq!(result, ClosestPoints::Disjoint);
// With larger search distance, we get the points
let result2 = closest_points(&pos1, &ball1, &pos2, &ball2, 10.0).unwrap();
assert!(matches!(result2, ClosestPoints::WithinMargin(_, _)));Implementations§
Source§impl ClosestPoints
impl ClosestPoints
Sourcepub fn flip(&mut self)
pub fn flip(&mut self)
Swaps the two closest points in-place.
This is useful when you need to reverse the perspective of the query result.
If the result is WithinMargin, the two points are swapped. For Intersecting
and Disjoint, this operation has no effect.
§Example
use parry3d::query::{closest_points, ClosestPoints};
use parry3d::shape::Ball;
use nalgebra::Isometry3;
let ball1 = Ball::new(1.0);
let ball2 = Ball::new(2.0);
let pos1 = Isometry3::translation(0.0, 0.0, 0.0);
let pos2 = Isometry3::translation(5.0, 0.0, 0.0);
let mut result = closest_points(&pos1, &ball1, &pos2, &ball2, 10.0).unwrap();
if let ClosestPoints::WithinMargin(pt1_before, pt2_before) = result {
result.flip();
if let ClosestPoints::WithinMargin(pt1_after, pt2_after) = result {
assert_eq!(pt1_before, pt2_after);
assert_eq!(pt2_before, pt1_after);
}
}Sourcepub fn flipped(&self) -> Self
pub fn flipped(&self) -> Self
Returns a copy with the two closest points swapped.
This is the non-mutating version of flip. It returns a new
ClosestPoints with swapped points if the result is WithinMargin, or returns
self unchanged for Intersecting and Disjoint.
§Example
use parry3d::query::{closest_points, ClosestPoints};
use parry3d::shape::Ball;
use nalgebra::Isometry3;
let ball1 = Ball::new(1.0);
let ball2 = Ball::new(2.0);
let pos1 = Isometry3::translation(0.0, 0.0, 0.0);
let pos2 = Isometry3::translation(5.0, 0.0, 0.0);
let result = closest_points(&pos1, &ball1, &pos2, &ball2, 10.0).unwrap();
let flipped = result.flipped();
// Original is unchanged
if let ClosestPoints::WithinMargin(pt1_orig, pt2_orig) = result {
if let ClosestPoints::WithinMargin(pt1_flip, pt2_flip) = flipped {
assert_eq!(pt1_orig, pt2_flip);
assert_eq!(pt2_orig, pt1_flip);
}
}Sourcepub fn transform_by(self, pos1: &Isometry<f32>, pos2: &Isometry<f32>) -> Self
pub fn transform_by(self, pos1: &Isometry<f32>, pos2: &Isometry<f32>) -> Self
Transforms the closest points from local space to world space.
Applies the isometry transformations to convert closest points from their respective local coordinate frames to world-space coordinates. This is used internally by the query system.
- Point 1 is transformed by
pos1 - Point 2 is transformed by
pos2 IntersectingandDisjointvariants are returned unchanged
§Arguments
pos1- Transformation for the first shapepos2- Transformation for the second shape
§Example
use parry3d::query::ClosestPoints;
use nalgebra::{Isometry3, Point3};
// Points in local space
let local_result = ClosestPoints::WithinMargin(
Point3::new(1.0, 0.0, 0.0),
Point3::new(-1.0, 0.0, 0.0),
);
// Transform to world space
let pos1 = Isometry3::translation(10.0, 0.0, 0.0);
let pos2 = Isometry3::translation(20.0, 0.0, 0.0);
let world_result = local_result.transform_by(&pos1, &pos2);
if let ClosestPoints::WithinMargin(pt1, pt2) = world_result {
assert!((pt1.x - 11.0).abs() < 1e-5); // 10.0 + 1.0
assert!((pt2.x - 19.0).abs() < 1e-5); // 20.0 + (-1.0)
}Trait Implementations§
Source§impl Clone for ClosestPoints
impl Clone for ClosestPoints
Source§fn clone(&self) -> ClosestPoints
fn clone(&self) -> ClosestPoints
1.0.0 · Source§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
source. Read moreSource§impl Debug for ClosestPoints
impl Debug for ClosestPoints
Source§impl PartialEq for ClosestPoints
impl PartialEq for ClosestPoints
impl Copy for ClosestPoints
impl StructuralPartialEq for ClosestPoints
Auto Trait Implementations§
impl Freeze for ClosestPoints
impl RefUnwindSafe for ClosestPoints
impl Send for ClosestPoints
impl Sync for ClosestPoints
impl Unpin for ClosestPoints
impl UnwindSafe for ClosestPoints
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
Source§impl<T> Downcast for Twhere
T: Any,
impl<T> Downcast for Twhere
T: Any,
Source§fn into_any(self: Box<T>) -> Box<dyn Any>
fn into_any(self: Box<T>) -> Box<dyn Any>
Box<dyn Trait> (where Trait: Downcast) to Box<dyn Any>, which can then be
downcast into Box<dyn ConcreteType> where ConcreteType implements Trait.Source§fn into_any_rc(self: Rc<T>) -> Rc<dyn Any>
fn into_any_rc(self: Rc<T>) -> Rc<dyn Any>
Rc<Trait> (where Trait: Downcast) to Rc<Any>, which can then be further
downcast into Rc<ConcreteType> where ConcreteType implements Trait.Source§fn as_any(&self) -> &(dyn Any + 'static)
fn as_any(&self) -> &(dyn Any + 'static)
&Trait (where Trait: Downcast) to &Any. This is needed since Rust cannot
generate &Any’s vtable from &Trait’s.Source§fn as_any_mut(&mut self) -> &mut (dyn Any + 'static)
fn as_any_mut(&mut self) -> &mut (dyn Any + 'static)
&mut Trait (where Trait: Downcast) to &Any. This is needed since Rust cannot
generate &mut Any’s vtable from &mut Trait’s.Source§impl<T> DowncastSend for T
impl<T> DowncastSend for T
Source§impl<T> DowncastSync for T
impl<T> DowncastSync for T
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self>
fn into_either(self, into_left: bool) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§impl<SS, SP> SupersetOf<SS> for SPwhere
SS: SubsetOf<SP>,
impl<SS, SP> SupersetOf<SS> for SPwhere
SS: SubsetOf<SP>,
Source§fn to_subset(&self) -> Option<SS>
fn to_subset(&self) -> Option<SS>
self from the equivalent element of its
superset. Read moreSource§fn is_in_subset(&self) -> bool
fn is_in_subset(&self) -> bool
self is actually part of its subset T (and can be converted to it).Source§fn to_subset_unchecked(&self) -> SS
fn to_subset_unchecked(&self) -> SS
self.to_subset but without any property checks. Always succeeds.Source§fn from_subset(element: &SS) -> SP
fn from_subset(element: &SS) -> SP
self to the equivalent element of its superset.