fn split_volume_sample(
a: f32,
c: f32, zf: f32,
zb: f32, z: f32, ) -> ((f32, f32), (f32, f32)) {
assert!(zb > zf && z >= zf && z <= zb);
let a = a.clamp(0.0, 1.0);
if a == 1.0f32 {
((1.0f32, c), (1.0f32, c))
} else {
let xf = (z - zf) / (zb - zf);
let xb = (zb - z) / (zb - zf);
if a > f32::MIN_POSITIVE {
let af = -((-a).ln_1p() * xf).exp_m1();
let cf = (af / a) * c;
let ab = -((-a).ln_1p() * xb).exp_m1();
let cb = (ab / a) * c;
((af, cf), (ab, cb))
} else {
((a * xf, c * xf), (a * xb, c * xb))
}
}
}
fn main() {
let a = 0.5f32;
let c = 1.0f32;
let zf = 0.0f32;
let zb = 1.0f32;
assert_eq!(
split_volume_sample(a, c, zf, zb, 0.5),
((0.29289323, 0.58578646), (0.29289323, 0.58578646))
);
assert_eq!(
split_volume_sample(a, c, zf, zb, 1.0e-7),
(
(0.000000069314716, 0.00000013862943),
(0.49999997, 0.99999994)
)
);
}