1use autd3_core::firmware::Intensity;
2
3#[derive(Clone, Copy, Debug, PartialEq)]
5pub enum EmissionConstraint {
6 Normalize,
8 Multiply(f32),
10 Uniform(Intensity),
12 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}