#[repr(C)]pub struct BoundingSphere {
pub center: Point<f32>,
pub radius: f32,
}Expand description
A Bounding Sphere.
A bounding sphere is a spherical bounding volume defined by a center point and a radius. Unlike an AABB, a bounding sphere is rotation-invariant, meaning it doesn’t need to be recomputed when an object rotates.
§Structure
- center: The center point of the sphere
- radius: The distance from the center to any point on the sphere’s surface
§Properties
- Rotation-invariant: Remains valid under rotation transformations
- Simple: Only 4 values (3D: x, y, z, radius; 2D: x, y, radius)
- Conservative: Often larger than the actual shape, especially for elongated objects
- Fast intersection tests: Only requires distance comparison
§Use Cases
Bounding spheres are useful for:
- Rotating objects: No recomputation needed when objects rotate
- Broad-phase culling: Quick rejection of distant object pairs
- View frustum culling: Simple sphere-frustum tests
- Level of detail (LOD): Distance-based detail switching
- Physics simulations: Fast bounds checking for moving/rotating bodies
§Performance
- Intersection test: O(1) - Single distance comparison
- Rotation: O(1) - Only center needs transformation
- Contains test: O(1) - Distance plus radius comparison
§Comparison to AABB
When to use BoundingSphere:
- Objects rotate frequently
- Objects are roughly spherical or evenly distributed
- Memory is tight (fewer values to store)
- Rotation-invariant bounds are required
When to use AABB:
- Objects are axis-aligned or rarely rotate
- Objects are elongated or box-like
- Tighter bounds are critical
- Building spatial hierarchies (BVH, octree)
§Example
use parry3d::bounding_volume::BoundingSphere;
use nalgebra::Point3;
// Create a bounding sphere with center at origin and radius 2.0
let sphere = BoundingSphere::new(Point3::origin(), 2.0);
// Check basic properties
assert_eq!(*sphere.center(), Point3::origin());
assert_eq!(sphere.radius(), 2.0);
// Test if a point is within the sphere
let point = Point3::new(1.0, 1.0, 0.0);
let distance = (point - sphere.center()).norm();
assert!(distance <= sphere.radius());use parry3d::bounding_volume::BoundingSphere;
use nalgebra::{Point3, Vector3, Translation3};
// Create a sphere and translate it
let sphere = BoundingSphere::new(Point3::new(1.0, 2.0, 3.0), 1.5);
let translation = Vector3::new(5.0, 0.0, 0.0);
let moved = sphere.translated(&translation);
assert_eq!(*moved.center(), Point3::new(6.0, 2.0, 3.0));
assert_eq!(moved.radius(), 1.5); // Radius unchanged by translationuse parry3d::bounding_volume::{BoundingSphere, BoundingVolume};
use nalgebra::Point3;
// Merge two bounding spheres
let sphere1 = BoundingSphere::new(Point3::origin(), 1.0);
let sphere2 = BoundingSphere::new(Point3::new(4.0, 0.0, 0.0), 1.0);
let merged = sphere1.merged(&sphere2);
// The merged sphere contains both original spheres
assert!(merged.contains(&sphere1));
assert!(merged.contains(&sphere2));Fields§
§center: Point<f32>The center point of the bounding sphere.
radius: f32The radius of the bounding sphere.
This is the distance from the center to any point on the sphere’s surface. All points within the bounded object should satisfy: distance(point, center) <= radius
Implementations§
Source§impl BoundingSphere
impl BoundingSphere
Sourcepub fn new(center: Point<f32>, radius: f32) -> BoundingSphere
pub fn new(center: Point<f32>, radius: f32) -> BoundingSphere
Creates a new bounding sphere from a center point and radius.
§Arguments
center- The center point of the sphereradius- The radius of the sphere (must be non-negative)
§Example
use parry3d::bounding_volume::BoundingSphere;
use nalgebra::Point3;
// Create a sphere centered at (1, 2, 3) with radius 5.0
let sphere = BoundingSphere::new(
Point3::new(1.0, 2.0, 3.0),
5.0
);
assert_eq!(*sphere.center(), Point3::new(1.0, 2.0, 3.0));
assert_eq!(sphere.radius(), 5.0);Sourcepub fn center(&self) -> &Point<f32>
pub fn center(&self) -> &Point<f32>
Returns a reference to the center point of this bounding sphere.
§Example
use parry3d::bounding_volume::BoundingSphere;
use nalgebra::Point3;
let sphere = BoundingSphere::new(Point3::new(1.0, 2.0, 3.0), 5.0);
let center = sphere.center();
assert_eq!(*center, Point3::new(1.0, 2.0, 3.0));Sourcepub fn radius(&self) -> f32
pub fn radius(&self) -> f32
Returns the radius of this bounding sphere.
The radius is the distance from the center to any point on the sphere’s surface.
§Example
use parry3d::bounding_volume::BoundingSphere;
use nalgebra::Point3;
let sphere = BoundingSphere::new(Point3::origin(), 10.0);
assert_eq!(sphere.radius(), 10.0);Sourcepub fn transform_by(&self, m: &Isometry<f32>) -> BoundingSphere
pub fn transform_by(&self, m: &Isometry<f32>) -> BoundingSphere
Transforms this bounding sphere by the given isometry.
For a bounding sphere, only the center point is affected by the transformation. The radius remains unchanged because spheres are rotation-invariant and isometries preserve distances.
§Arguments
m- The isometry (rigid transformation) to apply
§Example
use parry3d::bounding_volume::BoundingSphere;
use nalgebra::{Point3, Vector3, Isometry3, UnitQuaternion};
let sphere = BoundingSphere::new(Point3::new(1.0, 0.0, 0.0), 2.0);
// Create a transformation: translate by (5, 0, 0) and rotate 90 degrees around Z
let translation = Vector3::new(5.0, 0.0, 0.0);
let rotation = UnitQuaternion::from_euler_angles(0.0, 0.0, std::f32::consts::FRAC_PI_2);
let transform = Isometry3::from_parts(translation.into(), rotation);
let transformed = sphere.transform_by(&transform);
// The center is transformed
assert!((*transformed.center() - Point3::new(5.0, 1.0, 0.0)).norm() < 1e-5);
// The radius is unchanged
assert_eq!(transformed.radius(), 2.0);Sourcepub fn translated(&self, translation: &Vector<f32>) -> BoundingSphere
pub fn translated(&self, translation: &Vector<f32>) -> BoundingSphere
Translates this bounding sphere by the given vector.
This is equivalent to transform_by with a pure translation, but more efficient
as it doesn’t involve rotation.
§Arguments
translation- The translation vector to add to the center
§Example
use parry3d::bounding_volume::BoundingSphere;
use nalgebra::{Point3, Vector3};
let sphere = BoundingSphere::new(Point3::origin(), 1.0);
let translation = Vector3::new(10.0, 5.0, -3.0);
let moved = sphere.translated(&translation);
assert_eq!(*moved.center(), Point3::new(10.0, 5.0, -3.0));
assert_eq!(moved.radius(), 1.0); // Radius unchangedTrait Implementations§
Source§impl BoundingVolume for BoundingSphere
impl BoundingVolume for BoundingSphere
Source§fn center(&self) -> Point<f32>
fn center(&self) -> Point<f32>
Returns the center point of this bounding sphere.
§Example
use parry3d::bounding_volume::{BoundingSphere, BoundingVolume};
use nalgebra::Point3;
let sphere = BoundingSphere::new(Point3::new(1.0, 2.0, 3.0), 5.0);
// BoundingVolume::center() returns a Point by value
assert_eq!(BoundingVolume::center(&sphere), Point3::new(1.0, 2.0, 3.0));Source§fn intersects(&self, other: &BoundingSphere) -> bool
fn intersects(&self, other: &BoundingSphere) -> bool
Tests if this bounding sphere intersects another bounding sphere.
Two spheres intersect if the distance between their centers is less than or equal to the sum of their radii.
§Arguments
other- The other bounding sphere to test against
§Example
use parry3d::bounding_volume::{BoundingSphere, BoundingVolume};
use nalgebra::Point3;
let sphere1 = BoundingSphere::new(Point3::origin(), 2.0);
let sphere2 = BoundingSphere::new(Point3::new(3.0, 0.0, 0.0), 2.0);
let sphere3 = BoundingSphere::new(Point3::new(10.0, 0.0, 0.0), 1.0);
assert!(sphere1.intersects(&sphere2)); // Distance 3.0 <= sum of radii 4.0
assert!(!sphere1.intersects(&sphere3)); // Distance 10.0 > sum of radii 3.0Source§fn contains(&self, other: &BoundingSphere) -> bool
fn contains(&self, other: &BoundingSphere) -> bool
Tests if this bounding sphere fully contains another bounding sphere.
A sphere fully contains another sphere if the distance between their centers plus the other’s radius is less than or equal to this sphere’s radius.
§Arguments
other- The other bounding sphere to test
§Example
use parry3d::bounding_volume::{BoundingSphere, BoundingVolume};
use nalgebra::Point3;
let large = BoundingSphere::new(Point3::origin(), 10.0);
let small = BoundingSphere::new(Point3::new(2.0, 0.0, 0.0), 1.0);
let outside = BoundingSphere::new(Point3::new(15.0, 0.0, 0.0), 2.0);
assert!(large.contains(&small)); // Small sphere is inside large sphere
assert!(!large.contains(&outside)); // Outside sphere extends beyond large sphere
assert!(!small.contains(&large)); // Small cannot contain largeSource§fn merge(&mut self, other: &BoundingSphere)
fn merge(&mut self, other: &BoundingSphere)
Merges this bounding sphere with another in-place.
After this operation, this sphere will be the smallest sphere that contains both the original sphere and the other sphere.
§Arguments
other- The other bounding sphere to merge with
§Example
use parry3d::bounding_volume::{BoundingSphere, BoundingVolume};
use nalgebra::Point3;
let mut sphere1 = BoundingSphere::new(Point3::origin(), 1.0);
let sphere2 = BoundingSphere::new(Point3::new(4.0, 0.0, 0.0), 1.0);
sphere1.merge(&sphere2);
// The merged sphere now contains both original spheres
assert!(sphere1.contains(&BoundingSphere::new(Point3::origin(), 1.0)));
assert!(sphere1.contains(&sphere2));Source§fn merged(&self, other: &BoundingSphere) -> BoundingSphere
fn merged(&self, other: &BoundingSphere) -> BoundingSphere
Returns a new bounding sphere that is the merge of this sphere and another.
The returned sphere is the smallest sphere that contains both input spheres.
This is the non-mutating version of merge.
§Arguments
other- The other bounding sphere to merge with
§Example
use parry3d::bounding_volume::{BoundingSphere, BoundingVolume};
use nalgebra::Point3;
let sphere1 = BoundingSphere::new(Point3::origin(), 1.0);
let sphere2 = BoundingSphere::new(Point3::new(4.0, 0.0, 0.0), 1.0);
let merged = sphere1.merged(&sphere2);
// Original spheres are unchanged
assert_eq!(sphere1.radius(), 1.0);
// Merged sphere contains both
assert!(merged.contains(&sphere1));
assert!(merged.contains(&sphere2));Source§fn loosen(&mut self, amount: f32)
fn loosen(&mut self, amount: f32)
Increases the radius of this bounding sphere by the given amount in-place.
This creates a larger sphere with the same center. Useful for adding safety margins or creating conservative bounds.
§Arguments
amount- The amount to increase the radius (must be non-negative)
§Panics
Panics if amount is negative.
§Example
use parry3d::bounding_volume::{BoundingSphere, BoundingVolume};
use nalgebra::Point3;
let mut sphere = BoundingSphere::new(Point3::origin(), 5.0);
sphere.loosen(2.0);
assert_eq!(sphere.radius(), 7.0);
assert_eq!(*sphere.center(), Point3::origin()); // Center unchangedSource§fn loosened(&self, amount: f32) -> BoundingSphere
fn loosened(&self, amount: f32) -> BoundingSphere
Returns a new bounding sphere with increased radius.
This is the non-mutating version of loosen. The returned sphere has the same
center but a larger radius.
§Arguments
amount- The amount to increase the radius (must be non-negative)
§Panics
Panics if amount is negative.
§Example
use parry3d::bounding_volume::{BoundingSphere, BoundingVolume};
use nalgebra::Point3;
let sphere = BoundingSphere::new(Point3::origin(), 5.0);
let larger = sphere.loosened(3.0);
assert_eq!(sphere.radius(), 5.0); // Original unchanged
assert_eq!(larger.radius(), 8.0);
assert_eq!(*larger.center(), Point3::origin());Source§fn tighten(&mut self, amount: f32)
fn tighten(&mut self, amount: f32)
Decreases the radius of this bounding sphere by the given amount in-place.
This creates a smaller sphere with the same center. Useful for conservative collision detection or creating inner bounds.
§Arguments
amount- The amount to decrease the radius (must be non-negative and ≤ radius)
§Panics
Panics if amount is negative or greater than the current radius.
§Example
use parry3d::bounding_volume::{BoundingSphere, BoundingVolume};
use nalgebra::Point3;
let mut sphere = BoundingSphere::new(Point3::origin(), 10.0);
sphere.tighten(3.0);
assert_eq!(sphere.radius(), 7.0);
assert_eq!(*sphere.center(), Point3::origin()); // Center unchangedSource§fn tightened(&self, amount: f32) -> BoundingSphere
fn tightened(&self, amount: f32) -> BoundingSphere
Returns a new bounding sphere with decreased radius.
This is the non-mutating version of tighten. The returned sphere has the same
center but a smaller radius.
§Arguments
amount- The amount to decrease the radius (must be non-negative and ≤ radius)
§Panics
Panics if amount is negative or greater than the current radius.
§Example
use parry3d::bounding_volume::{BoundingSphere, BoundingVolume};
use nalgebra::Point3;
let sphere = BoundingSphere::new(Point3::origin(), 10.0);
let smaller = sphere.tightened(4.0);
assert_eq!(sphere.radius(), 10.0); // Original unchanged
assert_eq!(smaller.radius(), 6.0);
assert_eq!(*smaller.center(), Point3::origin());Source§impl Clone for BoundingSphere
impl Clone for BoundingSphere
Source§fn clone(&self) -> BoundingSphere
fn clone(&self) -> BoundingSphere
1.0.0 · Source§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
source. Read moreSource§impl Debug for BoundingSphere
impl Debug for BoundingSphere
Source§impl PartialEq for BoundingSphere
impl PartialEq for BoundingSphere
Source§impl PointQuery for BoundingSphere
impl PointQuery for BoundingSphere
Source§fn project_local_point(&self, pt: &Point<f32>, solid: bool) -> PointProjection
fn project_local_point(&self, pt: &Point<f32>, solid: bool) -> PointProjection
self. Read moreSource§fn project_local_point_and_get_feature(
&self,
pt: &Point<f32>,
) -> (PointProjection, FeatureId)
fn project_local_point_and_get_feature( &self, pt: &Point<f32>, ) -> (PointProjection, FeatureId)
self and returns the id of the
feature the point was projected on.Source§fn distance_to_local_point(&self, pt: &Point<f32>, solid: bool) -> f32
fn distance_to_local_point(&self, pt: &Point<f32>, solid: bool) -> f32
self.Source§fn contains_local_point(&self, pt: &Point<f32>) -> bool
fn contains_local_point(&self, pt: &Point<f32>) -> bool
self.Source§fn project_local_point_with_max_dist(
&self,
pt: &Point<f32>,
solid: bool,
max_dist: f32,
) -> Option<PointProjection>
fn project_local_point_with_max_dist( &self, pt: &Point<f32>, solid: bool, max_dist: f32, ) -> Option<PointProjection>
Source§fn project_point_with_max_dist(
&self,
m: &Isometry<f32>,
pt: &Point<f32>,
solid: bool,
max_dist: f32,
) -> Option<PointProjection>
fn project_point_with_max_dist( &self, m: &Isometry<f32>, pt: &Point<f32>, solid: bool, max_dist: f32, ) -> Option<PointProjection>
self transformed by m, unless the projection lies further than the given max distance.Source§fn project_point(
&self,
m: &Isometry<f32>,
pt: &Point<f32>,
solid: bool,
) -> PointProjection
fn project_point( &self, m: &Isometry<f32>, pt: &Point<f32>, solid: bool, ) -> PointProjection
self transformed by m.Source§fn distance_to_point(
&self,
m: &Isometry<f32>,
pt: &Point<f32>,
solid: bool,
) -> f32
fn distance_to_point( &self, m: &Isometry<f32>, pt: &Point<f32>, solid: bool, ) -> f32
self transformed by m.Source§fn project_point_and_get_feature(
&self,
m: &Isometry<f32>,
pt: &Point<f32>,
) -> (PointProjection, FeatureId)
fn project_point_and_get_feature( &self, m: &Isometry<f32>, pt: &Point<f32>, ) -> (PointProjection, FeatureId)
self transformed by m and returns the id of the
feature the point was projected on.Source§impl RayCast for BoundingSphere
impl RayCast for BoundingSphere
Source§fn cast_local_ray(
&self,
ray: &Ray,
max_time_of_impact: f32,
solid: bool,
) -> Option<f32>
fn cast_local_ray( &self, ray: &Ray, max_time_of_impact: f32, solid: bool, ) -> Option<f32>
Source§fn cast_local_ray_and_get_normal(
&self,
ray: &Ray,
max_time_of_impact: f32,
solid: bool,
) -> Option<RayIntersection>
fn cast_local_ray_and_get_normal( &self, ray: &Ray, max_time_of_impact: f32, solid: bool, ) -> Option<RayIntersection>
Source§fn intersects_local_ray(&self, ray: &Ray, max_time_of_impact: f32) -> bool
fn intersects_local_ray(&self, ray: &Ray, max_time_of_impact: f32) -> bool
Source§fn cast_ray(
&self,
m: &Isometry<f32>,
ray: &Ray,
max_time_of_impact: f32,
solid: bool,
) -> Option<f32>
fn cast_ray( &self, m: &Isometry<f32>, ray: &Ray, max_time_of_impact: f32, solid: bool, ) -> Option<f32>
Source§fn cast_ray_and_get_normal(
&self,
m: &Isometry<f32>,
ray: &Ray,
max_time_of_impact: f32,
solid: bool,
) -> Option<RayIntersection>
fn cast_ray_and_get_normal( &self, m: &Isometry<f32>, ray: &Ray, max_time_of_impact: f32, solid: bool, ) -> Option<RayIntersection>
impl Copy for BoundingSphere
impl StructuralPartialEq for BoundingSphere
Auto Trait Implementations§
impl Freeze for BoundingSphere
impl RefUnwindSafe for BoundingSphere
impl Send for BoundingSphere
impl Sync for BoundingSphere
impl Unpin for BoundingSphere
impl UnwindSafe for BoundingSphere
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.