pub fn closest_points<G1, G2>(
pos12: &Isometry<f32>,
g1: &G1,
g2: &G2,
max_dist: f32,
exact_dist: bool,
simplex: &mut VoronoiSimplex,
) -> GJKResultExpand description
Computes the closest points between two shapes using the GJK algorithm.
This is the core function of the GJK implementation in Parry. It can compute:
- Whether two shapes are intersecting
- The distance between two separated shapes
- The closest points on both shapes
- An approximate separation axis when exact distance isn’t needed
§How It Works
The algorithm operates on the Minkowski difference (CSO) of the two shapes and iteratively builds a simplex that approximates the point closest to the origin. The algorithm terminates when:
- The shapes are proven to intersect (origin is inside the CSO)
- The minimum distance is found within the tolerance
- The shapes are proven to be farther than
max_distapart
§Parameters
pos12: The relative position of shape 2 with respect to shape 1. This is the isometry that transforms from shape 1’s space to shape 2’s space.g1: The first shape (must implementSupportMap)g2: The second shape (must implementSupportMap)max_dist: Maximum distance to check. If shapes are farther than this, the algorithm returnsGJKResult::NoIntersectionearly. UseReal::max_value()to disable this check.exact_dist: Whether to compute exact closest points:true: Computes exact distance and returnsGJKResult::ClosestPointsfalse: May returnGJKResult::Proximitywith only an approximate separation axis, which is faster when you only need to know if shapes are nearby
simplex: A reusable simplex structure. Initialize withVoronoiSimplex::new()before first use. Can be reused across calls for better performance.
§Returns
Returns a GJKResult which can be:
Intersection: The shapes are overlappingClosestPoints(p1, p2, normal): The closest points on each shape (whenexact_distis true)Proximity(axis): An approximate separation axis (whenexact_distis false)NoIntersection(axis): The shapes are farther thanmax_distapart
§Example: Basic Distance Query
use parry3d::shape::{Ball, Cuboid};
use parry3d::query::gjk::{closest_points, VoronoiSimplex};
use parry3d::math::{Isometry, Vector};
// Create two shapes
let ball = Ball::new(1.0);
let cuboid = Cuboid::new(Vector::new(1.0, 1.0, 1.0));
// Position them in space
let pos1 = Isometry::translation(0.0, 0.0, 0.0);
let pos2 = Isometry::translation(5.0, 0.0, 0.0);
// Compute relative position
let pos12 = pos1.inv_mul(&pos2);
// Run GJK
let mut simplex = VoronoiSimplex::new();
let result = closest_points(
&pos12,
&ball,
&cuboid,
f32::MAX, // No distance limit
true, // Compute exact distance
&mut simplex,
);
match result {
parry3d::query::gjk::GJKResult::ClosestPoints(p1, p2, normal) => {
println!("Closest point on ball: {:?}", p1);
println!("Closest point on cuboid: {:?}", p2);
println!("Separation direction: {:?}", normal);
let distance = (p2 - p1).norm();
println!("Distance: {}", distance);
}
parry3d::query::gjk::GJKResult::Intersection => {
println!("Shapes are intersecting!");
}
_ => {}
}§Example: Fast Proximity Check
use parry3d::shape::Ball;
use parry3d::query::gjk::{closest_points, VoronoiSimplex};
use parry3d::math::Isometry;
let ball1 = Ball::new(1.0);
let ball2 = Ball::new(1.0);
let pos12 = Isometry::translation(3.0, 0.0, 0.0);
let mut simplex = VoronoiSimplex::new();
let result = closest_points(
&pos12,
&ball1,
&ball2,
5.0, // Only check up to distance 5.0
false, // Don't compute exact distance
&mut simplex,
);
match result {
parry3d::query::gjk::GJKResult::Proximity(_axis) => {
println!("Shapes are close but not intersecting");
}
parry3d::query::gjk::GJKResult::Intersection => {
println!("Shapes are intersecting");
}
parry3d::query::gjk::GJKResult::NoIntersection(_) => {
println!("Shapes are too far apart (> 5.0 units)");
}
_ => {}
}§Performance Tips
- Reuse the
simplexacross multiple queries to avoid allocations - Set
exact_disttofalsewhen you only need proximity information - Use a reasonable
max_distto allow early termination - GJK converges fastest when shapes are well-separated
§Notes
- All returned points and vectors are in the local-space of shape 1
- The algorithm typically converges in 5-10 iterations for well-separated shapes
- Maximum iteration count is 100 to prevent infinite loops