Skip to main content

oxihuman_morph/
thyroid_cartilage_morph.rs

1// Copyright (C) 2026 COOLJAPAN OU (Team KitaSan)
2// SPDX-License-Identifier: Apache-2.0
3#![allow(dead_code)]
4
5//! Thyroid cartilage shape morph — controls prominence and angle of the thyroid cartilage.
6
7/// Thyroid cartilage morph configuration.
8#[derive(Debug, Clone)]
9pub struct ThyroidCartilageMorph {
10    pub prominence: f32,
11    pub angle: f32,
12    pub width: f32,
13    pub height: f32,
14}
15
16impl ThyroidCartilageMorph {
17    pub fn new() -> Self {
18        Self {
19            prominence: 0.3,
20            angle: 0.5,
21            width: 0.5,
22            height: 0.5,
23        }
24    }
25}
26
27impl Default for ThyroidCartilageMorph {
28    fn default() -> Self {
29        Self::new()
30    }
31}
32
33/// Create a new thyroid cartilage morph.
34pub fn new_thyroid_cartilage_morph() -> ThyroidCartilageMorph {
35    ThyroidCartilageMorph::new()
36}
37
38/// Set thyroid prominence ("Adam's apple").
39pub fn thyroid_set_prominence(m: &mut ThyroidCartilageMorph, v: f32) {
40    m.prominence = v.clamp(0.0, 1.0);
41}
42
43/// Set laminar angle (smaller angle = more prominent).
44pub fn thyroid_set_angle(m: &mut ThyroidCartilageMorph, v: f32) {
45    m.angle = v.clamp(0.0, 1.0);
46}
47
48/// Set cartilage width.
49pub fn thyroid_set_width(m: &mut ThyroidCartilageMorph, v: f32) {
50    m.width = v.clamp(0.0, 1.0);
51}
52
53/// Set cartilage height.
54pub fn thyroid_set_height(m: &mut ThyroidCartilageMorph, v: f32) {
55    m.height = v.clamp(0.0, 1.0);
56}
57
58/// Serialize to JSON-like string.
59pub fn thyroid_cartilage_morph_to_json(m: &ThyroidCartilageMorph) -> String {
60    format!(
61        r#"{{"prominence":{:.4},"angle":{:.4},"width":{:.4},"height":{:.4}}}"#,
62        m.prominence, m.angle, m.width, m.height
63    )
64}
65
66#[cfg(test)]
67mod tests {
68    use super::*;
69
70    #[test]
71    fn test_defaults() {
72        let m = new_thyroid_cartilage_morph();
73        assert!((m.prominence - 0.3).abs() < 1e-6);
74    }
75
76    #[test]
77    fn test_prominence_clamp() {
78        let mut m = new_thyroid_cartilage_morph();
79        thyroid_set_prominence(&mut m, 2.0);
80        assert_eq!(m.prominence, 1.0);
81    }
82
83    #[test]
84    fn test_set_angle() {
85        let mut m = new_thyroid_cartilage_morph();
86        thyroid_set_angle(&mut m, 0.2);
87        assert!((m.angle - 0.2).abs() < 1e-6);
88    }
89
90    #[test]
91    fn test_set_width() {
92        let mut m = new_thyroid_cartilage_morph();
93        thyroid_set_width(&mut m, 0.7);
94        assert!((m.width - 0.7).abs() < 1e-6);
95    }
96
97    #[test]
98    fn test_set_height() {
99        let mut m = new_thyroid_cartilage_morph();
100        thyroid_set_height(&mut m, 0.6);
101        assert!((m.height - 0.6).abs() < 1e-6);
102    }
103
104    #[test]
105    fn test_angle_clamp_low() {
106        let mut m = new_thyroid_cartilage_morph();
107        thyroid_set_angle(&mut m, -1.0);
108        assert_eq!(m.angle, 0.0);
109    }
110
111    #[test]
112    fn test_json_keys() {
113        let m = new_thyroid_cartilage_morph();
114        let s = thyroid_cartilage_morph_to_json(&m);
115        assert!(s.contains("prominence"));
116    }
117
118    #[test]
119    fn test_clone() {
120        let m = new_thyroid_cartilage_morph();
121        let m2 = m.clone();
122        assert!((m2.angle - m.angle).abs() < 1e-6);
123    }
124
125    #[test]
126    fn test_width_zero() {
127        let mut m = new_thyroid_cartilage_morph();
128        thyroid_set_width(&mut m, 0.0);
129        assert_eq!(m.width, 0.0);
130    }
131}