Skip to content

Commit cb70675

Browse files
authored
Implement ShapeSample for CircularSector (#20095)
# Objective - Implement `ShapeSample for CircularSector` ## Testing - The results can be verified visually. --- ## Showcase ### Boundary <img width="661" height="383" alt="Circular Sector Boundary Sampling" src="https://github.com/user-attachments/assets/a08ee2eb-9b3d-4be1-8798-9317db337513" /> ### Interior <img width="665" height="386" alt="Circular Sector Interior Sampling" src="https://github.com/user-attachments/assets/bf71ce54-e73c-414c-899d-6402c0abd9e7" />
1 parent fae4489 commit cb70675

File tree

1 file changed

+26
-1
lines changed

1 file changed

+26
-1
lines changed

crates/bevy_math/src/sampling/shape_sampling.rs

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@
3838
//!
3939
//! In any case, the [`Rng`] used as the source of randomness must be provided explicitly.
4040
41-
use core::f32::consts::{PI, TAU};
41+
use core::f32::consts::{FRAC_PI_2, PI, TAU};
4242

4343
use crate::{ops, primitives::*, NormedVectorSpace, ScalarField, Vec2, Vec3};
4444
use rand::{
@@ -167,6 +167,31 @@ impl ShapeSample for Circle {
167167
}
168168
}
169169

170+
impl ShapeSample for CircularSector {
171+
type Output = Vec2;
172+
173+
fn sample_interior<R: Rng + ?Sized>(&self, rng: &mut R) -> Vec2 {
174+
let theta = rng.gen_range(-self.half_angle()..=self.half_angle());
175+
let r_squared = rng.gen_range(0.0..=(self.radius() * self.radius()));
176+
let r = ops::sqrt(r_squared);
177+
let (sin, cos) = ops::sin_cos(theta);
178+
Vec2::new(r * sin, r * cos)
179+
}
180+
181+
fn sample_boundary<R: Rng + ?Sized>(&self, rng: &mut R) -> Vec2 {
182+
if rng.gen_range(0.0..=1.0) <= self.arc_length() / self.perimeter() {
183+
// Sample on the arc
184+
let theta = FRAC_PI_2 + rng.gen_range(-self.half_angle()..self.half_angle());
185+
Vec2::from_angle(theta) * self.radius()
186+
} else {
187+
// Sample on the "inner" straight lines
188+
let dir = self.radius() * Vec2::from_angle(FRAC_PI_2 + self.half_angle());
189+
let r: f32 = rng.gen_range(-1.0..1.0);
190+
(-r).clamp(0.0, 1.0) * dir + r.clamp(0.0, 1.0) * dir * Vec2::new(-1.0, 1.0)
191+
}
192+
}
193+
}
194+
170195
/// Boundary sampling for unit-spheres
171196
#[inline]
172197
fn sample_unit_sphere_boundary<R: Rng + ?Sized>(rng: &mut R) -> Vec3 {

0 commit comments

Comments
 (0)