use num::Float;
pub trait Density: Float {
fn to_normal(a: &Self, b: &Self, c: &Self) -> [f32; 3];
fn interp(a: &Self, b: &Self, threshold: &Self) -> Self;
fn as_f32(&self) -> f32;
}
impl Density for f32 {
fn interp(a: &Self, b: &Self, threshold: &Self) -> f32 {
if (b - a).abs() > f32::EPSILON {
(threshold - a) / (b - a)
} else {
0.5f32
}
}
fn as_f32(&self) -> f32 {
*self
}
fn to_normal(a: &Self, b: &Self, c: &Self) -> [f32; 3] {
let norm = (a * a + b * b + c * c).sqrt();
if norm > f32::EPSILON {
[-a / norm, -b / norm, -c / norm]
} else {
[0f32, 0f32, 0f32]
}
}
}
pub trait ScalarField<D> {
fn get_density(&mut self, x: f32, y: f32, z: f32) -> D;
}
impl<D, F> ScalarField<D> for &mut F
where
F: ScalarField<D> + ?Sized,
{
fn get_density(&mut self, x: f32, y: f32, z: f32) -> D {
(**self).get_density(x, y, z)
}
}
pub struct ScalarFieldForFn<F>(pub F);
impl<F, D> ScalarField<D> for ScalarFieldForFn<F>
where
F: FnMut(f32, f32, f32) -> D,
{
fn get_density(&mut self, x: f32, y: f32, z: f32) -> D {
self.0(x, y, z)
}
}