autd3_core/geometry/
transducer.rs

1use getset::Getters;
2
3use super::{Isometry, Point3};
4
5/// A ultrasound transducer.
6#[derive(Clone, Debug, PartialEq, Getters)]
7pub struct Transducer {
8    idx: u8,
9    dev_idx: u16,
10    #[getset(get = "pub")]
11    /// The position of the transducer.
12    position: Point3,
13}
14
15impl Transducer {
16    /// Creates a new [`Transducer`].
17    #[must_use]
18    pub const fn new(idx: u8, dev_idx: u16, position: Point3) -> Self {
19        Self {
20            idx,
21            dev_idx,
22            position,
23        }
24    }
25
26    /// Gets the local index of the transducer.
27    #[must_use]
28    pub const fn idx(&self) -> usize {
29        self.idx as _
30    }
31
32    /// Gets the index of the device to which this transducer belongs.
33    #[must_use]
34    pub const fn dev_idx(&self) -> usize {
35        self.dev_idx as _
36    }
37
38    pub(super) fn affine(&mut self, isometry: &Isometry) {
39        self.position = isometry * self.position;
40    }
41}
42
43#[cfg(test)]
44mod tests {
45    use std::f32::consts::PI;
46
47    use crate::geometry::{Translation, UnitQuaternion, Vector3};
48
49    use super::*;
50
51    macro_rules! assert_vec3_approx_eq {
52        ($a:expr, $b:expr) => {
53            approx::assert_abs_diff_eq!($a.x, $b.x, epsilon = 1e-3);
54            approx::assert_abs_diff_eq!($a.y, $b.y, epsilon = 1e-3);
55            approx::assert_abs_diff_eq!($a.z, $b.z, epsilon = 1e-3);
56        };
57    }
58
59    #[test]
60    fn idx() {
61        let tr = Transducer::new(1, 2, Point3::origin());
62        assert_eq!(1, tr.idx());
63        assert_eq!(2, tr.dev_idx());
64    }
65
66    #[rstest::rstest]
67    #[test]
68    fn affine() {
69        let mut tr = Transducer::new(0, 0, Point3::origin());
70
71        let vector = Vector3::new(40., 50., 60.);
72        let rotation = UnitQuaternion::from_axis_angle(&Vector3::x_axis(), 0.)
73            * UnitQuaternion::from_axis_angle(&Vector3::y_axis(), 0.)
74            * UnitQuaternion::from_axis_angle(&Vector3::z_axis(), PI / 2.);
75        tr.affine(&Isometry {
76            translation: Translation { vector },
77            rotation,
78        });
79
80        let expect_pos = vector;
81        assert_vec3_approx_eq!(expect_pos, tr.position());
82    }
83}