Add scale_around_center
method to BoundingVolume
trait (#12142)
# Objective Add a `scale_around_center` method to the `BoundingVolume` trait, as per #12130. ## Solution Added `scale_around_center` to the `BoundingVolume` trait, implemented in `Aabb2d`, `Aabb3d`, `BoundingCircle`, and `BoundingSphere` (with tests).
This commit is contained in:
parent
d0f24aa902
commit
686d354d28
@ -152,6 +152,16 @@ impl BoundingVolume for Aabb2d {
|
||||
b
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
fn scale_around_center(&self, scale: Self::HalfSize) -> Self {
|
||||
let b = Self {
|
||||
min: self.center() - (self.half_size() * scale),
|
||||
max: self.center() + (self.half_size() * scale),
|
||||
};
|
||||
debug_assert!(b.min.x <= b.max.x && b.min.y <= b.max.y);
|
||||
b
|
||||
}
|
||||
|
||||
/// Transforms the bounding volume by first rotating it around the origin and then applying a translation.
|
||||
///
|
||||
/// The result is an Axis-Aligned Bounding Box that encompasses the rotated shape.
|
||||
@ -352,6 +362,19 @@ mod aabb2d_tests {
|
||||
assert!(!shrunk.contains(&a));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn scale_around_center() {
|
||||
let a = Aabb2d {
|
||||
min: Vec2::NEG_ONE,
|
||||
max: Vec2::ONE,
|
||||
};
|
||||
let scaled = a.scale_around_center(Vec2::splat(2.));
|
||||
assert!((scaled.min - Vec2::splat(-2.)).length() < std::f32::EPSILON);
|
||||
assert!((scaled.max - Vec2::splat(2.)).length() < std::f32::EPSILON);
|
||||
assert!(!a.contains(&scaled));
|
||||
assert!(scaled.contains(&a));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn transform() {
|
||||
let a = Aabb2d {
|
||||
@ -546,6 +569,12 @@ impl BoundingVolume for BoundingCircle {
|
||||
Self::new(self.center, self.radius() - amount)
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
fn scale_around_center(&self, scale: Self::HalfSize) -> Self {
|
||||
debug_assert!(scale >= 0.);
|
||||
Self::new(self.center, self.radius() * scale)
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
fn translate_by(&mut self, translation: Self::Translation) {
|
||||
self.center += translation;
|
||||
@ -658,6 +687,15 @@ mod bounding_circle_tests {
|
||||
assert!(!shrunk.contains(&a));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn scale_around_center() {
|
||||
let a = BoundingCircle::new(Vec2::ONE, 5.);
|
||||
let scaled = a.scale_around_center(2.);
|
||||
assert!((scaled.radius() - 10.).abs() < std::f32::EPSILON);
|
||||
assert!(!a.contains(&scaled));
|
||||
assert!(scaled.contains(&a));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn transform() {
|
||||
let a = BoundingCircle::new(Vec2::ONE, 5.0);
|
||||
|
@ -147,6 +147,16 @@ impl BoundingVolume for Aabb3d {
|
||||
b
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
fn scale_around_center(&self, scale: Self::HalfSize) -> Self {
|
||||
let b = Self {
|
||||
min: self.center() - (self.half_size() * scale),
|
||||
max: self.center() + (self.half_size() * scale),
|
||||
};
|
||||
debug_assert!(b.min.x <= b.max.x && b.min.y <= b.max.y);
|
||||
b
|
||||
}
|
||||
|
||||
/// Transforms the bounding volume by first rotating it around the origin and then applying a translation.
|
||||
///
|
||||
/// The result is an Axis-Aligned Bounding Box that encompasses the rotated shape.
|
||||
@ -348,6 +358,19 @@ mod aabb3d_tests {
|
||||
assert!(!shrunk.contains(&a));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn scale_around_center() {
|
||||
let a = Aabb3d {
|
||||
min: Vec3::NEG_ONE,
|
||||
max: Vec3::ONE,
|
||||
};
|
||||
let scaled = a.scale_around_center(Vec3::splat(2.));
|
||||
assert!((scaled.min - Vec3::splat(-2.)).length() < std::f32::EPSILON);
|
||||
assert!((scaled.max - Vec3::splat(2.)).length() < std::f32::EPSILON);
|
||||
assert!(!a.contains(&scaled));
|
||||
assert!(scaled.contains(&a));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn transform() {
|
||||
let a = Aabb3d {
|
||||
@ -549,6 +572,12 @@ impl BoundingVolume for BoundingSphere {
|
||||
}
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
fn scale_around_center(&self, scale: Self::HalfSize) -> Self {
|
||||
debug_assert!(scale >= 0.);
|
||||
Self::new(self.center, self.radius() * scale)
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
fn translate_by(&mut self, translation: Self::Translation) {
|
||||
self.center += translation;
|
||||
@ -663,6 +692,15 @@ mod bounding_sphere_tests {
|
||||
assert!(!shrunk.contains(&a));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn scale_around_center() {
|
||||
let a = BoundingSphere::new(Vec3::ONE, 5.);
|
||||
let scaled = a.scale_around_center(2.);
|
||||
assert!((scaled.radius() - 10.).abs() < std::f32::EPSILON);
|
||||
assert!(!a.contains(&scaled));
|
||||
assert!(scaled.contains(&a));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn transform() {
|
||||
let a = BoundingSphere::new(Vec3::ONE, 5.0);
|
||||
|
@ -48,6 +48,9 @@ pub trait BoundingVolume: Sized {
|
||||
/// Decreases the size of the bounding volume in each direction by the given amount.
|
||||
fn shrink(&self, amount: Self::HalfSize) -> Self;
|
||||
|
||||
/// Scale the size of the bounding volume around its center by the given amount
|
||||
fn scale_around_center(&self, scale: Self::HalfSize) -> Self;
|
||||
|
||||
/// Transforms the bounding volume by first rotating it around the origin and then applying a translation.
|
||||
fn transformed_by(
|
||||
mut self,
|
||||
|
Loading…
Reference in New Issue
Block a user