From 9ec3525b1550f108179390ef23269419fbfff9df Mon Sep 17 00:00:00 2001 From: Matthew Gordon Date: Sun, 3 Oct 2021 11:01:34 -0400 Subject: [PATCH] Add random_distributions::UnitDisc --- src/random_distributions/mod.rs | 3 ++ src/random_distributions/unit_disc.rs | 49 +++++++++++++++++++++++++++ 2 files changed, 52 insertions(+) create mode 100644 src/random_distributions/unit_disc.rs diff --git a/src/random_distributions/mod.rs b/src/random_distributions/mod.rs index 0df18b3..d74beca 100644 --- a/src/random_distributions/mod.rs +++ b/src/random_distributions/mod.rs @@ -1,6 +1,9 @@ mod uniform_square; pub use uniform_square::UniformSquare; +mod unit_disc; +pub use unit_disc::UnitDisc; + pub trait RandomDistribution { fn value(&self) -> T; } diff --git a/src/random_distributions/unit_disc.rs b/src/random_distributions/unit_disc.rs new file mode 100644 index 0000000..84ce12c --- /dev/null +++ b/src/random_distributions/unit_disc.rs @@ -0,0 +1,49 @@ +use std::f64::consts::PI; + +use crate::math::Vec2; + +use super::{RandomDistribution, UniformSquare}; + +#[derive(Debug)] +pub struct UnitDisc { + square_distribution: UniformSquare, +} + +impl UnitDisc { + pub fn new() -> UnitDisc { + let square_distribution = UniformSquare::new(Vec2::new(-1.0, -1.0), 2.0); + UnitDisc { + square_distribution, + } + } +} + +impl RandomDistribution for UnitDisc { + fn value(&self) -> Vec2 { + let offset = self.square_distribution.value(); + if offset.x() == 0.0 && offset.y() == 0.0 { + offset + } else { + let (radius, angle) = if offset.x().abs() > offset.y().abs() { + (offset.x(), (PI / 4.0) * offset.y() / offset.x()) + } else { + (offset.y(), PI / 2.0 - (PI / 4.0) * offset.x() / offset.y()) + }; + Vec2::new(angle.cos(), angle.sin()) * radius + } + } +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn print_values() { + let target = UnitDisc::new(); + for _ in 0..1000 { + let value = target.value(); + println!("{}, {}", value.x(), value.y()); + } + } +}