Add random_distributions::LinearWeighted
This commit is contained in:
parent
1f84cde760
commit
ed224b18cb
|
|
@ -1,6 +1,6 @@
|
||||||
use crate::math::Vec3;
|
|
||||||
use crate::colour::{ColourRgbF, Photon, Spectrum};
|
use crate::colour::{ColourRgbF, Photon, Spectrum};
|
||||||
use crate::materials::MaterialSampleResult;
|
use crate::materials::MaterialSampleResult;
|
||||||
|
use crate::math::Vec3;
|
||||||
use crate::raycasting::{IntersectionInfo, Ray};
|
use crate::raycasting::{IntersectionInfo, Ray};
|
||||||
use crate::sampler::Sampler;
|
use crate::sampler::Sampler;
|
||||||
use crate::util::algebra_utils::try_change_of_basis_matrix;
|
use crate::util::algebra_utils::try_change_of_basis_matrix;
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
use crate::math::Vec3;
|
|
||||||
use crate::colour::{Photon, Spectrum};
|
use crate::colour::{Photon, Spectrum};
|
||||||
use crate::materials::MaterialSampleResult;
|
use crate::materials::MaterialSampleResult;
|
||||||
|
use crate::math::Vec3;
|
||||||
use crate::raycasting::{IntersectionInfo, Ray};
|
use crate::raycasting::{IntersectionInfo, Ray};
|
||||||
use crate::sampler::Sampler;
|
use crate::sampler::Sampler;
|
||||||
use crate::util::algebra_utils::try_change_of_basis_matrix;
|
use crate::util::algebra_utils::try_change_of_basis_matrix;
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,67 @@
|
||||||
|
use rand::distributions::Open01;
|
||||||
|
use rand::{thread_rng, Rng};
|
||||||
|
|
||||||
|
use super::RandomDistribution;
|
||||||
|
|
||||||
|
pub struct LinearWeighted {
|
||||||
|
max_value: f64,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl LinearWeighted {
|
||||||
|
pub fn new(max_value: f64) -> LinearWeighted {
|
||||||
|
LinearWeighted { max_value }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl RandomDistribution<f64> for LinearWeighted {
|
||||||
|
fn value(&self) -> f64 {
|
||||||
|
let mut rng = thread_rng();
|
||||||
|
rng.sample::<f64, _>(Open01).sqrt() * self.max_value
|
||||||
|
}
|
||||||
|
|
||||||
|
fn pdf(&self, value: f64) -> f64 {
|
||||||
|
2.0 * value / (self.max_value * self.max_value)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
#[ignore]
|
||||||
|
fn print_values() {
|
||||||
|
let target = LinearWeighted::new(2.0);
|
||||||
|
for _ in 0..1000 {
|
||||||
|
let value = target.value();
|
||||||
|
println!("{}", value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
#[ignore]
|
||||||
|
fn print_buckets() {
|
||||||
|
let mut buckets = [0; 20];
|
||||||
|
let target = LinearWeighted::new(20.0);
|
||||||
|
for _ in 0..10000 {
|
||||||
|
let value = target.value();
|
||||||
|
let i = value as usize;
|
||||||
|
buckets[i] += 1;
|
||||||
|
}
|
||||||
|
for count in buckets {
|
||||||
|
println!("{}", count);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
#[ignore]
|
||||||
|
fn integral_is_near_area() {
|
||||||
|
let target = LinearWeighted::new(2.0);
|
||||||
|
let integral = (0..100000)
|
||||||
|
.map(|_| target.value())
|
||||||
|
.map(|value| 1.0 / target.pdf(value))
|
||||||
|
.sum::<f64>()
|
||||||
|
/ 100000.0;
|
||||||
|
println!("Area: {}\nIntegral: {}", 2.0, integral);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -10,6 +10,9 @@ pub use uniform_hemisphere::UniformHemisphere;
|
||||||
mod cosine_weighted_hemisphere;
|
mod cosine_weighted_hemisphere;
|
||||||
pub use cosine_weighted_hemisphere::CosineWeightedHemisphere;
|
pub use cosine_weighted_hemisphere::CosineWeightedHemisphere;
|
||||||
|
|
||||||
|
mod linear_weighted;
|
||||||
|
pub use linear_weighted::LinearWeighted;
|
||||||
|
|
||||||
pub trait RandomDistribution<T> {
|
pub trait RandomDistribution<T> {
|
||||||
fn value(&self) -> T;
|
fn value(&self) -> T;
|
||||||
fn pdf(&self, value: T) -> f64;
|
fn pdf(&self, value: T) -> f64;
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue