@@ -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+
167179impl 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