Add PDF to RandomDistribution
This commit is contained in:
parent
8badbaa3ca
commit
8459f3110f
|
|
@ -9,4 +9,5 @@ pub use uniform_hemisphere::UniformHemisphere;
|
|||
|
||||
pub trait RandomDistribution<T> {
|
||||
fn value(&self) -> T;
|
||||
fn pdf(&self, value: T) -> f64;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,3 +1,5 @@
|
|||
use std::f64::consts::PI;
|
||||
|
||||
use rand::distributions::{Open01, OpenClosed01};
|
||||
use rand::{thread_rng, Rng};
|
||||
|
||||
|
|
@ -30,6 +32,10 @@ impl RandomDistribution<Vec3> for UniformHemisphere {
|
|||
}
|
||||
result.normalize()
|
||||
}
|
||||
|
||||
fn pdf(&self, _: Vec3) -> f64 {
|
||||
1.0 / (2.0 * PI)
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
|
|
@ -45,4 +51,16 @@ mod tests {
|
|||
println!("{}, {}, {}", value.x(), value.y(), value.z());
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[ignore]
|
||||
fn integral_is_near_area() {
|
||||
let target = UniformHemisphere::new();
|
||||
let integral = (0..1000)
|
||||
.map(|_| target.value())
|
||||
.map(|value| 1.0 / target.pdf(value))
|
||||
.sum::<f64>()
|
||||
/ 1000.0;
|
||||
println!("Area: {}\nIntegral: {}", 2.0 * PI, integral);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -23,6 +23,10 @@ impl RandomDistribution<Vec2> for UniformSquare {
|
|||
self.corner
|
||||
+ Vec2::new(rng.sample::<f64, _>(Open01), rng.sample::<f64, _>(Open01)) * self.size
|
||||
}
|
||||
|
||||
fn pdf(&self, _value: Vec2) -> f64 {
|
||||
1.0 / (self.size * self.size)
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
|
|
@ -41,4 +45,19 @@ mod tests {
|
|||
println!("{}, {}", value.x(), value.y());
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[ignore]
|
||||
fn integral_is_near_area() {
|
||||
let target = UniformSquare {
|
||||
corner: Vec2::new(1.5, -2.5),
|
||||
size: 3.0,
|
||||
};
|
||||
let integral = (0..1000)
|
||||
.map(|_| target.value())
|
||||
.map(|value| 1.0 / target.pdf(value))
|
||||
.sum::<f64>()
|
||||
/ 1000.0;
|
||||
println!("Area: {}\nIntegral: {}", 3.0 * 3.0, integral);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -32,6 +32,10 @@ impl RandomDistribution<Vec2> for UnitDisc {
|
|||
Vec2::new(angle.cos(), angle.sin()) * radius
|
||||
}
|
||||
}
|
||||
|
||||
fn pdf(&self, _: Vec2) -> f64 {
|
||||
1.0 / PI
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
|
|
@ -47,4 +51,16 @@ mod tests {
|
|||
println!("{}, {}", value.x(), value.y());
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[ignore]
|
||||
fn integral_is_near_area() {
|
||||
let target = UnitDisc::new();
|
||||
let integral = (0..1000)
|
||||
.map(|_| target.value())
|
||||
.map(|value| 1.0 / target.pdf(value))
|
||||
.sum::<f64>()
|
||||
/ 1000.0;
|
||||
println!("Area: {}\nIntegral: {}", PI, integral);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue