Skip to main content

autd3_rs_core/geometry/
device.rs

1use nalgebra::{Isometry3, Point3, Translation3, UnitQuaternion, UnitVector3, Vector3};
2
3#[derive(Clone, Debug)]
4pub struct Device {
5    idx: usize,
6    rotation: UnitQuaternion<f32>,
7    positions: Vec<Point3<f32>>,
8    directions: Vec<UnitVector3<f32>>,
9    inv: Isometry3<f32>,
10}
11
12impl Device {
13    pub(super) fn new(
14        rotation: UnitQuaternion<f32>,
15        positions: Vec<Point3<f32>>,
16        directions: Vec<UnitVector3<f32>>,
17    ) -> Self {
18        debug_assert_eq!(positions.len(), directions.len());
19        let origin = positions.first().copied().unwrap_or_else(Point3::origin);
20        let inv = (Translation3::from(origin) * rotation).inverse();
21        Self {
22            idx: 0,
23            rotation,
24            positions,
25            directions,
26            inv,
27        }
28    }
29
30    #[must_use]
31    pub fn to_local(&self, p: Point3<f32>) -> Point3<f32> {
32        self.inv * p
33    }
34
35    pub(super) fn set_idx(&mut self, idx: usize) {
36        self.idx = idx;
37    }
38
39    #[must_use]
40    pub const fn idx(&self) -> usize {
41        self.idx
42    }
43
44    #[must_use]
45    pub const fn rotation(&self) -> UnitQuaternion<f32> {
46        self.rotation
47    }
48
49    #[must_use]
50    pub fn x_direction(&self) -> UnitVector3<f32> {
51        self.rotation * Vector3::x_axis()
52    }
53
54    #[must_use]
55    pub fn y_direction(&self) -> UnitVector3<f32> {
56        self.rotation * Vector3::y_axis()
57    }
58
59    #[must_use]
60    pub fn axial_direction(&self) -> UnitVector3<f32> {
61        self.rotation * Vector3::z_axis()
62    }
63
64    #[must_use]
65    pub const fn num_transducers(&self) -> usize {
66        self.positions.len()
67    }
68
69    #[must_use]
70    pub const fn is_empty(&self) -> bool {
71        self.positions.is_empty()
72    }
73
74    #[must_use]
75    pub fn positions(&self) -> &[Point3<f32>] {
76        &self.positions
77    }
78
79    #[must_use]
80    pub fn directions(&self) -> &[UnitVector3<f32>] {
81        &self.directions
82    }
83
84    #[must_use]
85    pub fn position(&self, index: usize) -> Point3<f32> {
86        self.positions[index]
87    }
88
89    #[must_use]
90    pub fn direction(&self, index: usize) -> UnitVector3<f32> {
91        self.directions[index]
92    }
93
94    #[must_use]
95    pub fn center(&self) -> Point3<f32> {
96        let n = self.positions.len() as f32;
97        let sum = self
98            .positions
99            .iter()
100            .fold(Vector3::zeros(), |acc, p| acc + p.coords);
101        Point3::from(sum / n)
102    }
103}