#![allow(dead_code)]
pub fn mitchell_netravali(x: f32, b: f32, c: f32) -> f32 {
let ax = x.abs();
if ax < 1.0 {
((12.0 - 9.0 * b - 6.0 * c) * ax * ax * ax
+ (-18.0 + 12.0 * b + 6.0 * c) * ax * ax
+ (6.0 - 2.0 * b))
/ 6.0
} else if ax < 2.0 {
((-b - 6.0 * c) * ax * ax * ax
+ (6.0 * b + 30.0 * c) * ax * ax
+ (-12.0 * b - 48.0 * c) * ax
+ (8.0 * b + 24.0 * c))
/ 6.0
} else {
0.0
}
}
pub fn lanczos(x: f32, lobes: f32) -> f32 {
use std::f32::consts::PI;
if x.abs() < 1e-6 {
return 1.0;
}
if x.abs() >= lobes {
return 0.0;
}
let px = PI * x;
(px.sin() / px) * ((px / lobes).sin() / (px / lobes))
}
pub fn box_filter(x: f32) -> f32 {
if x.abs() <= 0.5 {
1.0
} else {
0.0
}
}
pub fn gaussian_filter(x: f32, sigma: f32) -> f32 {
use std::f32::consts::PI;
(-(x * x) / (2.0 * sigma * sigma)).exp() / (sigma * (2.0 * PI).sqrt())
}
pub fn filter_is_separable(_name: &str) -> bool {
true
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_mitchell_center() {
let v = mitchell_netravali(0.0, 1.0 / 3.0, 1.0 / 3.0);
assert!(v > 0.0);
}
#[test]
fn test_mitchell_zero_outside() {
let v = mitchell_netravali(3.0, 1.0 / 3.0, 1.0 / 3.0);
assert!(v.abs() < 1e-6);
}
#[test]
fn test_lanczos_center() {
let v = lanczos(0.0, 3.0);
assert!((v - 1.0).abs() < 1e-5);
}
#[test]
fn test_box_filter() {
assert!((box_filter(0.0) - 1.0).abs() < 1e-6);
assert!(box_filter(1.0).abs() < 1e-6);
}
#[test]
fn test_gaussian_positive() {
let g = gaussian_filter(0.5, 0.5);
assert!(g > 0.0);
}
}