#![allow(dead_code)]
#[allow(dead_code)]
#[derive(Debug, Clone, PartialEq)]
pub struct BrowArch {
pub left_arch: f32,
pub right_arch: f32,
pub peak_offset: f32,
}
#[allow(dead_code)]
pub fn default_brow_arch() -> BrowArch {
BrowArch {
left_arch: 0.5,
right_arch: 0.5,
peak_offset: 0.0,
}
}
#[allow(dead_code)]
pub fn apply_brow_arch(weights: &mut [f32], ba: &BrowArch) {
if !weights.is_empty() {
weights[0] = ba.left_arch;
}
if weights.len() >= 2 {
weights[1] = ba.right_arch;
}
if weights.len() >= 3 {
weights[2] = ba.peak_offset;
}
}
#[allow(dead_code)]
pub fn brow_arch_blend(a: &BrowArch, b: &BrowArch, t: f32) -> BrowArch {
let lerp = |x: f32, y: f32| x + (y - x) * t;
BrowArch {
left_arch: lerp(a.left_arch, b.left_arch),
right_arch: lerp(a.right_arch, b.right_arch),
peak_offset: lerp(a.peak_offset, b.peak_offset),
}
}
#[allow(dead_code)]
pub fn arch_symmetry(ba: &BrowArch) -> f32 {
let diff = (ba.left_arch - ba.right_arch).abs();
(1.0 - diff).clamp(0.0, 1.0)
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_default_values() {
let ba = default_brow_arch();
assert_eq!(ba.left_arch, 0.5);
assert_eq!(ba.right_arch, 0.5);
assert_eq!(ba.peak_offset, 0.0);
}
#[test]
fn test_apply_full() {
let ba = BrowArch { left_arch: 0.7, right_arch: 0.8, peak_offset: -0.2 };
let mut w = [0.0f32; 3];
apply_brow_arch(&mut w, &ba);
assert_eq!(w[0], 0.7);
assert_eq!(w[1], 0.8);
assert_eq!(w[2], -0.2);
}
#[test]
fn test_apply_empty() {
let ba = default_brow_arch();
let mut w: [f32; 0] = [];
apply_brow_arch(&mut w, &ba);
}
#[test]
fn test_blend_zero() {
let a = BrowArch { left_arch: 0.2, right_arch: 0.3, peak_offset: -0.5 };
let b = BrowArch { left_arch: 0.8, right_arch: 0.7, peak_offset: 0.5 };
let r = brow_arch_blend(&a, &b, 0.0);
assert!((r.left_arch - 0.2).abs() < 1e-6);
}
#[test]
fn test_blend_one() {
let a = BrowArch { left_arch: 0.2, right_arch: 0.3, peak_offset: -0.5 };
let b = BrowArch { left_arch: 0.8, right_arch: 0.7, peak_offset: 0.5 };
let r = brow_arch_blend(&a, &b, 1.0);
assert!((r.peak_offset - 0.5).abs() < 1e-6);
}
#[test]
fn test_arch_symmetry_perfect() {
let ba = BrowArch { left_arch: 0.5, right_arch: 0.5, peak_offset: 0.0 };
assert!((arch_symmetry(&ba) - 1.0).abs() < 1e-6);
}
#[test]
fn test_arch_symmetry_asymmetric() {
let ba = BrowArch { left_arch: 0.0, right_arch: 1.0, peak_offset: 0.0 };
assert!((arch_symmetry(&ba)).abs() < 1e-6);
}
#[test]
fn test_arch_symmetry_partial() {
let ba = BrowArch { left_arch: 0.3, right_arch: 0.7, peak_offset: 0.0 };
let sym = arch_symmetry(&ba);
assert!(sym > 0.0 && sym < 1.0);
}
}