oxihuman_morph/
sacrum_morph.rs1#![allow(dead_code)]
4
5#[derive(Debug, Clone)]
9pub struct SacrumMorph {
10 pub tilt: f32,
11 pub width: f32,
12 pub curvature: f32,
13 pub promontory_depth: f32,
14}
15
16impl SacrumMorph {
17 pub fn new() -> Self {
18 Self {
19 tilt: 0.5,
20 width: 0.5,
21 curvature: 0.5,
22 promontory_depth: 0.5,
23 }
24 }
25}
26
27impl Default for SacrumMorph {
28 fn default() -> Self {
29 Self::new()
30 }
31}
32
33pub fn new_sacrum_morph() -> SacrumMorph {
35 SacrumMorph::new()
36}
37
38pub fn sac_set_tilt(m: &mut SacrumMorph, v: f32) {
40 m.tilt = v.clamp(0.0, 1.0);
41}
42
43pub fn sac_set_width(m: &mut SacrumMorph, v: f32) {
45 m.width = v.clamp(0.0, 1.0);
46}
47
48pub fn sac_set_curvature(m: &mut SacrumMorph, v: f32) {
50 m.curvature = v.clamp(0.0, 1.0);
51}
52
53pub fn sac_set_promontory_depth(m: &mut SacrumMorph, v: f32) {
55 m.promontory_depth = v.clamp(0.0, 1.0);
56}
57
58pub fn sac_pelvic_inlet(m: &SacrumMorph) -> f32 {
60 m.width * (1.0 - (m.tilt - 0.5).abs() * 0.3)
61}
62
63pub fn sacrum_morph_to_json(m: &SacrumMorph) -> String {
65 format!(
66 r#"{{"tilt":{:.4},"width":{:.4},"curvature":{:.4},"promontory_depth":{:.4}}}"#,
67 m.tilt, m.width, m.curvature, m.promontory_depth
68 )
69}
70
71#[cfg(test)]
72mod tests {
73 use super::*;
74
75 #[test]
76 fn test_defaults() {
77 let m = new_sacrum_morph();
78 assert!((m.tilt - 0.5).abs() < 1e-6);
79 }
80
81 #[test]
82 fn test_tilt_clamp() {
83 let mut m = new_sacrum_morph();
84 sac_set_tilt(&mut m, -1.0);
85 assert_eq!(m.tilt, 0.0);
86 }
87
88 #[test]
89 fn test_width_set() {
90 let mut m = new_sacrum_morph();
91 sac_set_width(&mut m, 0.7);
92 assert!((m.width - 0.7).abs() < 1e-6);
93 }
94
95 #[test]
96 fn test_curvature_clamp() {
97 let mut m = new_sacrum_morph();
98 sac_set_curvature(&mut m, 3.0);
99 assert_eq!(m.curvature, 1.0);
100 }
101
102 #[test]
103 fn test_promontory_depth() {
104 let mut m = new_sacrum_morph();
105 sac_set_promontory_depth(&mut m, 0.6);
106 assert!((m.promontory_depth - 0.6).abs() < 1e-6);
107 }
108
109 #[test]
110 fn test_pelvic_inlet_range() {
111 let m = new_sacrum_morph();
112 let pi = sac_pelvic_inlet(&m);
113 assert!((0.0..=1.0).contains(&pi));
114 }
115
116 #[test]
117 fn test_json_keys() {
118 let m = new_sacrum_morph();
119 let s = sacrum_morph_to_json(&m);
120 assert!(s.contains("promontory_depth"));
121 }
122
123 #[test]
124 fn test_clone() {
125 let m = new_sacrum_morph();
126 let m2 = m.clone();
127 assert!((m2.width - m.width).abs() < 1e-6);
128 }
129
130 #[test]
131 fn test_pelvic_inlet_wide() {
132 let mut m = new_sacrum_morph();
133 sac_set_width(&mut m, 1.0);
134 sac_set_tilt(&mut m, 0.5); assert!(sac_pelvic_inlet(&m) > 0.9);
136 }
137}