use crate::optics::birefringence::BirefringenceParams;
use glam::Vec3;
#[cfg(test)]
mod walk_off_symmetry_tests {
use super::*;
#[test]
fn extraordinary_poynting_dir_is_axis_direction_symmetric() {
let n_o = 1.658f32;
let n_e = 1.486f32;
let c_axis = Vec3::new(0.2, 0.9, -0.35).normalize(); let perp = {
let p = c_axis.cross(Vec3::X);
if p.length_squared() < 1e-6 {
c_axis.cross(Vec3::Y).normalize()
} else {
p.normalize()
}
};
for i in 0..37 {
let theta = (i as f32) / 36.0 * std::f32::consts::PI; let wave_normal = (theta.cos() * c_axis + theta.sin() * perp).normalize();
let s_pos =
BirefringenceParams::extraordinary_poynting_dir(wave_normal, c_axis, n_o, n_e);
let s_neg =
BirefringenceParams::extraordinary_poynting_dir(wave_normal, -c_axis, n_o, n_e);
assert!(
(s_pos - s_neg).length() < 1e-4,
"S(c) must equal S(-c) at theta={} deg (got s_pos={s_pos:?}, s_neg={s_neg:?})",
theta.to_degrees()
);
}
}
#[test]
fn extraordinary_poynting_dir_matches_analytic_walk_off_both_hemispheres() {
let n_o = 1.658f32;
let n_e = 1.486f32;
let c_axis = Vec3::Y;
let theta = 45.0f32.to_radians();
let wave_normal = Vec3::new(theta.sin(), theta.cos(), 0.0);
for c in [c_axis, -c_axis] {
let s = BirefringenceParams::extraordinary_poynting_dir(wave_normal, c, n_o, n_e);
let angle_from_axis = s.dot(c_axis).clamp(-1.0, 1.0).abs().acos().to_degrees();
assert!(
(angle_from_axis - 51.23).abs() < 0.05,
"expected walk-off to land at 51.23 deg from the axis for c={c:?}, got {angle_from_axis}"
);
}
}
}