ivy_random/
traits.rs

1use glam::{Vec2, Vec3};
2use rand::Rng;
3
4pub trait Random {
5    // Generates a random unit vector
6    fn rand_unit<R: Rng>(rng: &mut R) -> Self;
7    // Generate a vector inside a unit spehre
8    fn rand_sphere<R: Rng>(rng: &mut R) -> Self;
9    /// Generate a vector withing a sphere with inner and outer radii
10    fn rand_constrained_sphere<R: Rng>(rng: &mut R, r1: f32, r2: f32) -> Self;
11    // Generates a vector with random components between -1 and 1
12    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}