autd3_core/geometry/
transducer.rs1use getset::Getters;
2
3use super::{Isometry, Point3};
4
5#[derive(Clone, Debug, PartialEq, Getters)]
7pub struct Transducer {
8 idx: u8,
9 dev_idx: u16,
10 #[getset(get = "pub")]
11 position: Point3,
13}
14
15impl Transducer {
16 #[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 #[must_use]
28 pub const fn idx(&self) -> usize {
29 self.idx as _
30 }
31
32 #[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}