diff --git a/crates/bevy_math/src/primitives/dim2.rs b/crates/bevy_math/src/primitives/dim2.rs index 6e44d8bc04..597fe8e891 100644 --- a/crates/bevy_math/src/primitives/dim2.rs +++ b/crates/bevy_math/src/primitives/dim2.rs @@ -1817,6 +1817,28 @@ impl Capsule2d { half_length: length / 2.0, } } + + /// Get the part connecting the semicircular ends of the capsule as a [`Rectangle`] + #[inline] + pub fn to_inner_rectangle(&self) -> Rectangle { + Rectangle::new(self.radius * 2.0, self.half_length * 2.0) + } +} + +impl Measured2d for Capsule2d { + /// Get the area of the capsule + #[inline] + fn area(&self) -> f32 { + // pi*r^2 + (2r)*l + PI * self.radius.squared() + self.to_inner_rectangle().area() + } + + /// Get the perimeter of the capsule + #[inline] + fn perimeter(&self) -> f32 { + // 2pi*r + 2l + 2.0 * PI * self.radius + 4.0 * self.half_length + } } #[cfg(test)] @@ -1892,6 +1914,18 @@ mod tests { assert_eq!(circle.perimeter(), 18.849556, "incorrect perimeter"); } + #[test] + fn capsule_math() { + let capsule = Capsule2d::new(2.0, 9.0); + assert_eq!( + capsule.to_inner_rectangle(), + Rectangle::new(4.0, 9.0), + "rectangle wasn't created correctly from a capsule" + ); + assert_eq!(capsule.area(), 48.566371, "incorrect area"); + assert_eq!(capsule.perimeter(), 30.566371, "incorrect perimeter"); + } + #[test] fn annulus_math() { let annulus = Annulus::new(2.5, 3.5); diff --git a/crates/bevy_math/src/sampling/shape_sampling.rs b/crates/bevy_math/src/sampling/shape_sampling.rs index 7e8c672a6b..e1fb0aef7d 100644 --- a/crates/bevy_math/src/sampling/shape_sampling.rs +++ b/crates/bevy_math/src/sampling/shape_sampling.rs @@ -450,8 +450,7 @@ impl ShapeSample for Capsule2d { if capsule_area > 0.0 { // Check if the random point should be inside the rectangle if rng.gen_bool((rectangle_area / capsule_area) as f64) { - let rectangle = Rectangle::new(self.radius * 2.0, self.half_length * 2.0); - rectangle.sample_interior(rng) + self.to_inner_rectangle().sample_interior(rng) } else { let circle = Circle::new(self.radius); let point = circle.sample_interior(rng);