use std::f64::consts::PI;
#[must_use]
#[inline]
pub fn bessel_j1(x: f64) -> f64 {
let ax = x.abs();
if ax < 8.0 {
let y = x * x;
let num = x
* (72362614232.0
+ y * (-7895059235.0
+ y * (242396853.1
+ y * (-2972611.439 + y * (15704.48260 + y * (-30.16036606))))));
let den = 144725228442.0
+ y * (2300535178.0 + y * (18583304.74 + y * (99447.43394 + y * (376.9991397 + y))));
num / den
} else {
let z = 8.0 / ax;
let z2 = z * z;
let theta = ax - 2.356_194_490_2; let p1 = 1.0
+ z2 * (0.183_105_e-2
+ z2 * (-0.3516396496e-4 + z2 * (0.2457520174e-5 + z2 * (-0.240337019e-6))));
let q1 = 0.04687499995
+ z2 * (-0.2002690873e-3
+ z2 * (0.8449199096e-5 + z2 * (-0.88228987e-6 + z2 * 0.105787412e-6)));
let result =
(std::f64::consts::FRAC_2_PI / ax).sqrt() * (theta.cos() * p1 - z * theta.sin() * q1);
if x < 0.0 { -result } else { result }
}
}
#[must_use]
#[inline]
pub fn airy_pattern(wavelength: f64, aperture_diameter: f64, angle: f64, i0: f64) -> f64 {
let x = PI * aperture_diameter * angle.sin() / wavelength;
if x.abs() < 1e-10 {
return i0; }
let jinc = 2.0 * bessel_j1(x) / x;
i0 * jinc * jinc
}
#[must_use]
#[inline]
pub fn airy_first_zero(wavelength: f64, aperture_diameter: f64) -> f64 {
1.219_670_5 * wavelength / aperture_diameter
}
#[must_use]
#[inline]
pub fn rayleigh_criterion(wavelength: f64, aperture_diameter: f64) -> f64 {
1.22 * wavelength / aperture_diameter
}