use types::*;
use consts::*;
const MIN_DISTANCE_WAVELENGTH_RATIO: f64 = 0.1;
pub fn fresnel_point(freq: Frequency, d1: Distance, d2: Distance, order: i64) -> Result<f64, &'static str> {
let wavelength = freq.to_wavelength();
if ((d1.0 * MIN_DISTANCE_WAVELENGTH_RATIO) < wavelength.0) || ((d2.0 * MIN_DISTANCE_WAVELENGTH_RATIO) < wavelength.0) {
return Err("Fresnel calculation valid only for distances >> wavelength");
}
return Ok((((order as f64) * wavelength.0 * d1.0 * d2.0) / (d1.0 + d2.0)).sqrt());
}
pub fn fresnel_first_zone(freq: Frequency, dist: Distance) -> Result<f64, &'static str> {
let wavelength = freq.to_wavelength();
if (dist.0 * MIN_DISTANCE_WAVELENGTH_RATIO) < wavelength.0 {
return Err("Fresnel calculation valid only for distance >> wavelength");
}
return Ok(0.5_f64 * (C * dist.0 / freq.0).sqrt());
}
pub fn fresnel_kirchoff_diffraction_param(freq: Frequency, d1: Distance, d2: Distance, h: Distance) -> f64 {
let wavelength = freq.to_wavelength();
return h.0 * ((2_f64 * (d1.0 + d2.0)) / (wavelength.0 * (d1.0 * d2.0))).sqrt();
}
pub fn fresnel_kirchoff_loss_approx(v: f64) -> Result<Attenuation, &'static str> {
if v < -0.7 {
return Err("Fresnel-Kirchoff loss approximation only valid for v >= -0.7");
}
let loss = 6.9_f64 + 20_f64 * (((v - 0.1_f64).powi(2) + 1_f64).sqrt() + v - 0.1_f64).log10();
return Ok(Attenuation(loss));
}
#[cfg(test)]
mod tests {
extern crate assert_approx_eq;
use super::*;
#[test]
fn test_fresnel_first_zone() {
let mut zone: f64;
zone = fresnel_first_zone(ghz(2.4), m(10e3)).unwrap();
assert_approx_eq::assert_approx_eq!(17.671776, zone, zone.abs() / 1000_f64);
zone = fresnel_first_zone(ghz(2.4), m(100e3)).unwrap();
assert_approx_eq::assert_approx_eq!(55.883, zone, zone.abs() / 1000_f64);
}
#[test]
fn test_fresnel_kirchoff_diffraction_param() {
let param: f64 = fresnel_kirchoff_diffraction_param(mhz(900_f64), km(8_f64), km(12_f64), m(-0.334_f64));
assert_approx_eq::assert_approx_eq!(-0.011812, param, param.abs() / 1000_f64);
}
#[test]
fn test_fresnel_kirchoff_loss_approx() {
let loss: Attenuation = fresnel_kirchoff_loss_approx(-0.012_f64).unwrap();
assert_approx_eq::assert_approx_eq!(5.93, loss.0, loss.0.abs() / 1000_f64);
}
}