use glam::Vec3;
use crate::optics::{birefringence::BiaxialIndicatrix, materials::GemMaterial};
mod assigned_mode_alpha;
mod eigen_polarization;
mod mode_poynting;
mod pleochroic;
mod resolve_entry_mode;
mod wave_indices;
pub use assigned_mode_alpha::{AssignedModeAlphaBiaxialCase, run_assigned_mode_alpha_biaxial};
pub use eigen_polarization::{BiaxialEigenPolarizationCase, run_biaxial_eigen_polarization};
pub use mode_poynting::{BiaxialModePoyntingCase, run_biaxial_mode_poynting};
pub use pleochroic::{BiaxialPleochroicCase, run_biaxial_pleochroic};
pub use resolve_entry_mode::{BiaxialResolveEntryModeCase, run_biaxial_resolve_entry_mode};
pub use wave_indices::{BiaxialWaveIndicesCase, run_biaxial_wave_indices};
fn biaxial_test_indicatrices() -> Vec<(&'static str, f32, f32, f32, Vec3)> {
const D_LINE_NM: f32 = 589.3;
let materials = GemMaterial::all_materials();
let mut out = Vec::new();
for name in ["Alexandrite", "Topaz", "Tanzanite"] {
let material = materials
.iter()
.find(|m| m.name == name)
.unwrap_or_else(|| panic!("\"{name}\" must be a built-in biaxial material"));
let ind = material
.biaxial_indicatrix(D_LINE_NM)
.unwrap_or_else(|| panic!("\"{name}\" must expose a BiaxialIndicatrix"));
out.push((name, ind.n_alpha, ind.n_beta, ind.n_gamma, ind.axes.z_axis));
}
out.push((
"synthetic",
1.60,
1.65,
1.75,
Vec3::new(0.35, 0.82, -0.45).normalize(),
));
out
}
fn biaxial_test_directions_unfiltered(gamma_axis: Vec3) -> Vec<Vec3> {
vec![
Vec3::X,
Vec3::Y,
Vec3::Z,
gamma_axis,
Vec3::new(0.2, 0.9, 0.1).normalize(),
Vec3::new(-0.5, 0.3, 0.8).normalize(),
Vec3::new(0.7, -0.6, 0.2).normalize(),
Vec3::new(0.1, 0.1, 0.99).normalize(),
Vec3::new(-0.9, -0.3, 0.2).normalize(),
]
}
fn biaxial_test_directions(n_alpha: f32, n_beta: f32, n_gamma: f32, gamma_axis: Vec3) -> Vec<Vec3> {
biaxial_test_directions_filtered(n_alpha, n_beta, n_gamma, gamma_axis, 1e-4)
}
fn biaxial_test_directions_index_stable(
n_alpha: f32,
n_beta: f32,
n_gamma: f32,
gamma_axis: Vec3,
) -> Vec<Vec3> {
biaxial_test_directions_filtered(n_alpha, n_beta, n_gamma, gamma_axis, 0.02)
}
fn biaxial_test_directions_filtered(
n_alpha: f32,
n_beta: f32,
n_gamma: f32,
gamma_axis: Vec3,
min_relative_mode_separation: f32,
) -> Vec<Vec3> {
let ind = BiaxialIndicatrix::from_gamma_axis(n_alpha, n_beta, n_gamma, gamma_axis);
biaxial_test_directions_unfiltered(gamma_axis)
.into_iter()
.filter(|&d| {
let (n_slow, n_fast) = ind.wave_indices(d);
(n_slow - n_fast) / n_slow >= min_relative_mode_separation
})
.collect()
}