autd3_gain_holo/
constraint.rs

1use autd3_core::firmware::Intensity;
2
3/// Emission constraint of transducers.
4#[derive(Clone, Copy, Debug, PartialEq)]
5pub enum EmissionConstraint {
6    /// Normalize the value.
7    Normalize,
8    /// Normalize the value and then multiply by the given value.
9    Multiply(f32),
10    /// Ignore the value calculated and use the given value.
11    Uniform(Intensity),
12    /// Clamp the value between the given values.
13    Clamp(Intensity, Intensity),
14}
15
16impl EmissionConstraint {
17    #[doc(hidden)]
18    #[must_use]
19    pub fn convert(&self, value: f32, max_value: f32) -> Intensity {
20        match self {
21            EmissionConstraint::Normalize => Intensity((value / max_value * 255.).round() as u8),
22            EmissionConstraint::Multiply(v) => {
23                Intensity((value / max_value * 255. * v).round().clamp(0., 255.) as u8)
24            }
25            EmissionConstraint::Uniform(v) => *v,
26            EmissionConstraint::Clamp(min, max) => {
27                Intensity((value * 255.).round().clamp(min.0 as f32, max.0 as f32) as u8)
28            }
29        }
30    }
31}
32
33#[cfg(test)]
34mod tests {
35    use super::*;
36
37    #[rstest::rstest]
38    #[case(Intensity::MIN, 0.0, 1.0)]
39    #[case(Intensity(128), 0.5, 1.0)]
40    #[case(Intensity(128), 1.0, 2.0)]
41    #[case(Intensity(191), 1.5, 2.0)]
42    fn normalize(#[case] expect: Intensity, #[case] value: f32, #[case] max_value: f32) {
43        assert_eq!(
44            expect,
45            EmissionConstraint::Normalize.convert(value, max_value)
46        );
47    }
48
49    #[rstest::rstest]
50    #[case(Intensity::MIN, 0.0, 1.0, 0.5)]
51    #[case(Intensity(64), 0.5, 1.0, 0.5)]
52    #[case(Intensity(64), 1.0, 2.0, 0.5)]
53    #[case(Intensity(96), 1.5, 2.0, 0.5)]
54    fn multiply(
55        #[case] expect: Intensity,
56        #[case] value: f32,
57        #[case] max_value: f32,
58        #[case] mul: f32,
59    ) {
60        assert_eq!(
61            expect,
62            EmissionConstraint::Multiply(mul).convert(value, max_value)
63        );
64    }
65
66    #[rstest::rstest]
67    #[case(Intensity::MIN, 0.0, 1.0)]
68    #[case(Intensity::MAX, 0.0, 1.0)]
69    #[case(Intensity::MIN, 0.5, 1.0)]
70    #[case(Intensity::MAX, 0.5, 1.0)]
71    #[case(Intensity::MIN, 1.0, 2.0)]
72    #[case(Intensity::MAX, 1.0, 2.0)]
73    #[case(Intensity::MIN, 1.5, 2.0)]
74    #[case(Intensity::MAX, 1.5, 2.0)]
75    fn uniform(#[case] expect: Intensity, #[case] value: f32, #[case] max_value: f32) {
76        assert_eq!(
77            expect,
78            EmissionConstraint::Uniform(expect).convert(value, max_value)
79        );
80    }
81
82    #[rstest::rstest]
83    #[case(Intensity(64), 0.0, 1.0, Intensity(64), Intensity(192))]
84    #[case(Intensity(128), 0.5, 1.0, Intensity(64), Intensity(192))]
85    #[case(Intensity(192), 1.0, 1.0, Intensity(64), Intensity(192))]
86    #[case(Intensity(192), 1.5, 1.0, Intensity(64), Intensity(192))]
87    fn clamp(
88        #[case] expect: Intensity,
89        #[case] value: f32,
90        #[case] max_value: f32,
91        #[case] min: Intensity,
92        #[case] max: Intensity,
93    ) {
94        assert_eq!(
95            expect,
96            EmissionConstraint::Clamp(min, max).convert(value, max_value)
97        );
98    }
99}