Skip to main content

lbf/samplers/
uniform_rect_sampler.rs

1use crate::samplers::rotation_distr::UniformRotDistr;
2use jagua_rs::entities::Item;
3use jagua_rs::geometry::DTransformation;
4use jagua_rs::geometry::primitives::Rect;
5use rand::{Rng, RngExt};
6use rand_distr::Distribution;
7use rand_distr::Uniform;
8
9/// Samples a [`DTransformation`] uniformly at random in a given [`Rect`] and [`UniformRotDistr`].
10pub struct UniformRectSampler {
11    pub bbox: Rect,
12    pub uniform_x: Uniform<f32>,
13    pub uniform_y: Uniform<f32>,
14    pub uniform_r: UniformRotDistr,
15    pub uniform_reflected_r: Option<UniformRotDistr>,
16}
17
18impl UniformRectSampler {
19    pub fn new(bbox: Rect, item: &Item) -> Self {
20        let uniform_x = Uniform::new(bbox.x_min, bbox.x_max).unwrap();
21        let uniform_y = Uniform::new(bbox.y_min, bbox.y_max).unwrap();
22        let uniform_r = UniformRotDistr::new(item.allowed_orientations().rotations());
23        let uniform_reflected_r = item
24            .allowed_orientations()
25            .rotations_after_reflection()
26            .map(UniformRotDistr::new);
27        Self {
28            bbox,
29            uniform_x,
30            uniform_y,
31            uniform_r,
32            uniform_reflected_r,
33        }
34    }
35
36    pub fn sample(&self, rng: &mut impl Rng) -> DTransformation {
37        let reflected = self.uniform_reflected_r.is_some() && rng.random_bool(0.5);
38        let r_sample = if reflected {
39            self.uniform_reflected_r.as_ref().unwrap().sample(rng)
40        } else {
41            self.uniform_r.sample(rng)
42        };
43        let x_sample = self.uniform_x.sample(rng);
44        let y_sample = self.uniform_y.sample(rng);
45
46        DTransformation::new(r_sample, (x_sample, y_sample)).with_reflection(reflected)
47    }
48}