use math::Vec3;
pub trait Source {
fn sample(&self, x: f32, y: f32, z: f32) -> f32;
}
pub trait HermiteSource: Source {
fn sample_normal(&self, x: f32, y: f32, z: f32) -> Vec3;
}
pub struct CentralDifference {
source: Box<Source>,
epsilon: f32,
}
impl CentralDifference {
pub fn new(source: Box<Source>) -> CentralDifference {
CentralDifference {
source,
epsilon: 0.0001,
}
}
pub fn new_with_epsilon(source: Box<Source>, epsilon: f32) -> CentralDifference {
CentralDifference { source, epsilon }
}
}
impl Source for CentralDifference {
fn sample(&self, x: f32, y: f32, z: f32) -> f32 {
self.source.sample(x, y, z)
}
}
impl HermiteSource for CentralDifference {
fn sample_normal(&self, x: f32, y: f32, z: f32) -> Vec3 {
let v = self.sample(x, y, z);
let vx = self.sample(x + self.epsilon, y, z);
let vy = self.sample(x, y + self.epsilon, z);
let vz = self.sample(x, y, z + self.epsilon);
Vec3::new(vx - v, vy - v, vz - v)
}
}