rand_distr/
unit_disc.rs

1// Copyright 2019 Developers of the Rand project.
2//
3// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
4// https://www.apache.org/licenses/LICENSE-2.0> or the MIT license
5// <LICENSE-MIT or https://opensource.org/licenses/MIT>, at your
6// option. This file may not be copied, modified, or distributed
7// except according to those terms.
8
9use num_traits::Float;
10use crate::{uniform::SampleUniform, Distribution, Uniform};
11use rand::Rng;
12
13/// Samples uniformly from the unit disc in two dimensions.
14///
15/// Implemented via rejection sampling.
16///
17///
18/// # Example
19///
20/// ```
21/// use rand_distr::{UnitDisc, Distribution};
22///
23/// let v: [f64; 2] = UnitDisc.sample(&mut rand::thread_rng());
24/// println!("{:?} is from the unit Disc.", v)
25/// ```
26#[derive(Clone, Copy, Debug)]
27#[cfg_attr(feature = "serde1", derive(serde::Serialize, serde::Deserialize))]
28pub struct UnitDisc;
29
30impl<F: Float + SampleUniform> Distribution<[F; 2]> for UnitDisc {
31    #[inline]
32    fn sample<R: Rng + ?Sized>(&self, rng: &mut R) -> [F; 2] {
33        let uniform = Uniform::new(F::from(-1.).unwrap(), F::from(1.).unwrap());
34        let mut x1;
35        let mut x2;
36        loop {
37            x1 = uniform.sample(rng);
38            x2 = uniform.sample(rng);
39            if x1 * x1 + x2 * x2 <= F::from(1.).unwrap() {
40                break;
41            }
42        }
43        [x1, x2]
44    }
45}