1use glam::{Vec2, Vec3};
2use rand::Rng;
3
4pub trait Random {
5 fn rand_unit<R: Rng>(rng: &mut R) -> Self;
7 fn rand_sphere<R: Rng>(rng: &mut R) -> Self;
9 fn rand_constrained_sphere<R: Rng>(rng: &mut R, r1: f32, r2: f32) -> Self;
11 fn rand_uniform<R: Rng>(rng: &mut R) -> Self;
13}
14
15impl Random for Vec3 {
16 fn rand_unit<R: Rng>(rng: &mut R) -> Self {
17 let phi = rng.gen_range(0.0..std::f32::consts::TAU);
18 let costheta: f32 = rng.gen_range(-1.0..=1.0);
19 let theta = costheta.acos();
20
21 Vec3::new(
22 theta.sin() * phi.cos(),
23 theta.sin() * phi.sin(),
24 theta.cos(),
25 )
26 }
27
28 fn rand_sphere<R: Rng>(rng: &mut R) -> Self {
29 let length = rng.gen_range(0.0..=1.0);
30 Self::rand_unit(rng) * length
31 }
32
33 fn rand_constrained_sphere<R: Rng>(rng: &mut R, r1: f32, r2: f32) -> Self {
34 let length = rng.gen_range(r1..=r2);
35 Self::rand_unit(rng) * length
36 }
37
38 fn rand_uniform<R: Rng>(rng: &mut R) -> Self {
39 Vec3::new(
40 rng.gen_range(-1.0..=1.0),
41 rng.gen_range(-1.0..=1.0),
42 rng.gen_range(-1.0..=1.0),
43 )
44 }
45}
46
47impl Random for Vec2 {
48 fn rand_unit<R: Rng>(rng: &mut R) -> Self {
49 let phi = rng.gen_range(0.0..std::f32::consts::TAU);
50
51 Vec2::new(phi.cos(), phi.sin())
52 }
53
54 fn rand_sphere<R: Rng>(rng: &mut R) -> Self {
55 let length = rng.gen_range(0.0..=1.0);
56 Self::rand_unit(rng) * length
57 }
58
59 fn rand_constrained_sphere<R: Rng>(rng: &mut R, r1: f32, r2: f32) -> Self {
60 let length = rng.gen_range(r1..=r2);
61 Self::rand_unit(rng) * length
62 }
63
64 fn rand_uniform<R: Rng>(rng: &mut R) -> Self {
65 Vec2::new(rng.gen_range(-1.0..=1.0), rng.gen_range(-1.0..=1.0))
66 }
67}
68
69impl Random for f32 {
70 fn rand_unit<R: Rng>(rng: &mut R) -> Self {
71 if rng.gen_bool(0.5) {
72 1.0
73 } else {
74 -1.0
75 }
76 }
77
78 fn rand_sphere<R: Rng>(rng: &mut R) -> Self {
79 rng.gen_range(0.0..=1.0)
80 }
81
82 fn rand_constrained_sphere<R: Rng>(rng: &mut R, r1: f32, r2: f32) -> Self {
83 rng.gen_range(r1..=r2)
84 }
85
86 fn rand_uniform<R: Rng>(rng: &mut R) -> Self {
87 Self::rand_sphere(rng)
88 }
89}
90
91impl Random for f64 {
92 fn rand_unit<R: Rng>(rng: &mut R) -> Self {
93 if rng.gen_bool(0.5) {
94 1.0
95 } else {
96 -1.0
97 }
98 }
99
100 fn rand_sphere<R: Rng>(rng: &mut R) -> Self {
101 rng.gen_range(0.0..=1.0)
102 }
103
104 fn rand_constrained_sphere<R: Rng>(rng: &mut R, r1: f32, r2: f32) -> Self {
105 rng.gen_range(r1..=r2) as f64
106 }
107
108 fn rand_uniform<R: Rng>(rng: &mut R) -> Self {
109 Self::rand_sphere(rng)
110 }
111}