Skip to content

Commit 3dd4953

Browse files
authored
bevy_math: faster sphere sampling (#14168)
Uses fewer transcendental functions than the existing approach
1 parent da997dd commit 3dd4953

File tree

1 file changed

+15
-15
lines changed

1 file changed

+15
-15
lines changed

crates/bevy_math/src/sampling/shape_sampling.rs

Lines changed: 15 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -164,30 +164,30 @@ impl ShapeSample for Circle {
164164
}
165165
}
166166

167+
/// Boundary sampling for unit-spheres
168+
#[inline]
169+
fn sample_unit_sphere_boundary<R: Rng + ?Sized>(rng: &mut R) -> Vec3 {
170+
let z = rng.gen_range(-1f32..=1f32);
171+
let (a_sin, a_cos) = rng.gen_range(-PI..=PI).sin_cos();
172+
let c = (1f32 - z * z).sqrt();
173+
let x = a_sin * c;
174+
let y = a_cos * c;
175+
176+
Vec3::new(x, y, z)
177+
}
178+
167179
impl ShapeSample for Sphere {
168180
type Output = Vec3;
169181

170182
fn sample_interior<R: Rng + ?Sized>(&self, rng: &mut R) -> Vec3 {
171-
// https://mathworld.wolfram.com/SpherePointPicking.html
172-
let theta = rng.gen_range(0.0..TAU);
173-
let phi = rng.gen_range(-1.0_f32..1.0).acos();
174183
let r_cubed = rng.gen_range(0.0..=(self.radius * self.radius * self.radius));
175184
let r = r_cubed.cbrt();
176-
Vec3 {
177-
x: r * phi.sin() * theta.cos(),
178-
y: r * phi.sin() * theta.sin(),
179-
z: r * phi.cos(),
180-
}
185+
186+
r * sample_unit_sphere_boundary(rng)
181187
}
182188

183189
fn sample_boundary<R: Rng + ?Sized>(&self, rng: &mut R) -> Vec3 {
184-
let theta = rng.gen_range(0.0..TAU);
185-
let phi = rng.gen_range(-1.0_f32..1.0).acos();
186-
Vec3 {
187-
x: self.radius * phi.sin() * theta.cos(),
188-
y: self.radius * phi.sin() * theta.sin(),
189-
z: self.radius * phi.cos(),
190-
}
190+
self.radius * sample_unit_sphere_boundary(rng)
191191
}
192192
}
193193

0 commit comments

Comments
 (0)