#![allow(dead_code)]
#[derive(Debug, Clone, PartialEq)]
pub struct HairlineMorph {
pub position: f32,
pub recession_left: f32,
pub recession_right: f32,
pub density: f32,
}
pub fn new_hairline_morph() -> HairlineMorph {
HairlineMorph {
position: 0.0,
recession_left: 0.0,
recession_right: 0.0,
density: 1.0,
}
}
pub fn hairline_set_position(m: &mut HairlineMorph, v: f32) {
m.position = v.clamp(0.0, 1.0);
}
pub fn hairline_recession_symmetric(m: &mut HairlineMorph, v: f32) {
let v = v.clamp(0.0, 1.0);
m.recession_left = v;
m.recession_right = v;
}
pub fn hairline_is_receded(m: &HairlineMorph) -> bool {
m.position > 0.5 || m.recession_left > 0.3 || m.recession_right > 0.3
}
pub fn hairline_overall_weight(m: &HairlineMorph) -> f32 {
(m.position + m.recession_left + m.recession_right) / 3.0
}
pub fn hairline_blend(a: &HairlineMorph, b: &HairlineMorph, t: f32) -> HairlineMorph {
let t = t.clamp(0.0, 1.0);
HairlineMorph {
position: a.position + (b.position - a.position) * t,
recession_left: a.recession_left + (b.recession_left - a.recession_left) * t,
recession_right: a.recession_right + (b.recession_right - a.recession_right) * t,
density: a.density + (b.density - a.density) * t,
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_new_defaults() {
let m = new_hairline_morph();
assert!((m.position - 0.0).abs() < 1e-6);
assert!((m.density - 1.0).abs() < 1e-6);
}
#[test]
fn test_set_position_clamps_max() {
let mut m = new_hairline_morph();
hairline_set_position(&mut m, 2.5);
assert!((m.position - 1.0).abs() < 1e-6);
}
#[test]
fn test_set_position_clamps_min() {
let mut m = new_hairline_morph();
hairline_set_position(&mut m, -1.0);
assert!((m.position - 0.0).abs() < 1e-6);
}
#[test]
fn test_recession_symmetric_sets_both() {
let mut m = new_hairline_morph();
hairline_recession_symmetric(&mut m, 0.5);
assert!((m.recession_left - 0.5).abs() < 1e-6);
assert!((m.recession_right - 0.5).abs() < 1e-6);
}
#[test]
fn test_is_receded_by_position() {
let mut m = new_hairline_morph();
hairline_set_position(&mut m, 0.8);
assert!(hairline_is_receded(&m));
}
#[test]
fn test_not_receded_default() {
let m = new_hairline_morph();
assert!(!hairline_is_receded(&m));
}
#[test]
fn test_blend_at_zero() {
let a = new_hairline_morph();
let mut b = new_hairline_morph();
hairline_set_position(&mut b, 1.0);
let r = hairline_blend(&a, &b, 0.0);
assert!((r.position - a.position).abs() < 1e-6);
}
}