mirror of
https://github.com/bevyengine/bevy
synced 2024-11-10 07:04:33 +00:00
bevy_math: faster sphere sampling (#14168)
Uses fewer transcendental functions than the existing approach
This commit is contained in:
parent
da997dd0ea
commit
3dd4953b97
1 changed files with 15 additions and 15 deletions
|
@ -164,30 +164,30 @@ impl ShapeSample for Circle {
|
|||
}
|
||||
}
|
||||
|
||||
/// Boundary sampling for unit-spheres
|
||||
#[inline]
|
||||
fn sample_unit_sphere_boundary<R: Rng + ?Sized>(rng: &mut R) -> Vec3 {
|
||||
let z = rng.gen_range(-1f32..=1f32);
|
||||
let (a_sin, a_cos) = rng.gen_range(-PI..=PI).sin_cos();
|
||||
let c = (1f32 - z * z).sqrt();
|
||||
let x = a_sin * c;
|
||||
let y = a_cos * c;
|
||||
|
||||
Vec3::new(x, y, z)
|
||||
}
|
||||
|
||||
impl ShapeSample for Sphere {
|
||||
type Output = Vec3;
|
||||
|
||||
fn sample_interior<R: Rng + ?Sized>(&self, rng: &mut R) -> Vec3 {
|
||||
// https://mathworld.wolfram.com/SpherePointPicking.html
|
||||
let theta = rng.gen_range(0.0..TAU);
|
||||
let phi = rng.gen_range(-1.0_f32..1.0).acos();
|
||||
let r_cubed = rng.gen_range(0.0..=(self.radius * self.radius * self.radius));
|
||||
let r = r_cubed.cbrt();
|
||||
Vec3 {
|
||||
x: r * phi.sin() * theta.cos(),
|
||||
y: r * phi.sin() * theta.sin(),
|
||||
z: r * phi.cos(),
|
||||
}
|
||||
|
||||
r * sample_unit_sphere_boundary(rng)
|
||||
}
|
||||
|
||||
fn sample_boundary<R: Rng + ?Sized>(&self, rng: &mut R) -> Vec3 {
|
||||
let theta = rng.gen_range(0.0..TAU);
|
||||
let phi = rng.gen_range(-1.0_f32..1.0).acos();
|
||||
Vec3 {
|
||||
x: self.radius * phi.sin() * theta.cos(),
|
||||
y: self.radius * phi.sin() * theta.sin(),
|
||||
z: self.radius * phi.cos(),
|
||||
}
|
||||
self.radius * sample_unit_sphere_boundary(rng)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue