use crate::bessel_utils::{ Jn };
use crate::helix::Helix;
use crate::wavefront::Wavefront;
use ndarray::{Array2, Array1, Array, ArrayView};
use std::f64::consts::PI;
use num:: {Complex, complex::Complex64, traits::Pow };
pub fn diff_analytic(helices: Vec<Helix>, n_range: u8, m_range: u8, scale: f64, raster_size: u32) -> Wavefront {
let num_pix: usize = (raster_size * raster_size) as usize;
let mut m_vals: Vec<f64> = Vec::new();
for i in 0..=m_range {
if i == 0 { m_vals.push(i as f64) } else {
m_vals.push(i as f64);
m_vals.push(-(i as f64));
}
};
let mut image: Array2<Complex64> = Array::zeros((raster_size as usize, raster_size as usize));
let coords: Array1<f64> = Array::range(0., raster_size as f64, 1 as f64) - (raster_size / 2) as f64;
let mut z_line: f64; let mut z_draw_coord: f64; let mut bessel: Array1<f64> = Array::zeros(raster_size as usize);
let mut Ufac: Array1<Complex64> = Array::zeros(raster_size as usize);
let mut phi_j: f64; let mut phi_z: f64;
for helix in &helices {
let pitch: f64 = helix.pitch();
let midpoint: f64 = raster_size as f64 / 2.;
phi_j = helix.rotation_to_rad();
for n in 0..=n_range {
for index in 0..raster_size as usize {
bessel[index] = Jn(n.into(), 2. * PI * coords[index].abs() * helix.radius * scale);
}
for m in &m_vals {
z_line = (n as f64) / (pitch * scale) + m / (helix.rise * scale);
z_draw_coord = z_line.round();
phi_z = 2. * PI * z_line * helix.offset * scale;
for index in 0..raster_size as usize {
Ufac[index] = bessel[index] * (Complex::new(0.0, (n as f64) * (PI / 2. - phi_j) + phi_z)).exp();
}
if z_draw_coord > -(raster_size as f64) / 2. && z_draw_coord < (raster_size as f64) / 2. {
let mut line = image.slice_mut(s![(midpoint + z_draw_coord) as usize, ..]);
line += &ArrayView::from(&Ufac);
if n != 0 {
let mut line = image.slice_mut(s![(midpoint - z_draw_coord) as usize, ..]);
line += &ArrayView::from(&Ufac);
}
}
}
}
}
return Wavefront::new(image );
}