autd3_core/acoustics/directivity/
mod.rs

1mod sphere;
2mod t4010a1;
3
4use crate::{
5    defined::{Angle, rad},
6    geometry::{UnitVector3, Vector3},
7};
8
9pub use sphere::Sphere;
10pub use t4010a1::T4010A1;
11
12/// A trait representing the directivity of ultrasound transducer.
13pub trait Directivity: Send + Sync {
14    /// Calculates the directivity based on the given angle.
15    ///
16    /// # Arguments
17    ///
18    /// * `theta` - The angle between the axial direction and the target direction.
19    #[must_use]
20    fn directivity(theta: Angle) -> f32;
21
22    /// Calculates the directivity based on the axial direction and target direction.
23    #[must_use]
24    fn directivity_from_dir(axial_direction: &UnitVector3, target: &Vector3) -> f32 {
25        Self::directivity(
26            (axial_direction.cross(target).norm()).atan2(axial_direction.dot(target)) * rad,
27        )
28    }
29}
30
31#[cfg(test)]
32pub(crate) mod tests {
33    use super::*;
34
35    pub(crate) struct TestDirectivity {}
36
37    impl Directivity for TestDirectivity {
38        fn directivity(t: Angle) -> f32 {
39            t.degree()
40        }
41    }
42
43    #[rstest::rstest]
44    #[test]
45    #[case::dir_x(90., Vector3::x(), Vector3::z_axis())]
46    #[case::dir_y(90., Vector3::y(), Vector3::z_axis())]
47    #[case::dir_z(0., Vector3::z(), Vector3::z_axis())]
48    fn test_directivity_from_dir(
49        #[case] expected: f32,
50        #[case] target: Vector3,
51        #[case] dir: UnitVector3,
52    ) {
53        approx::assert_abs_diff_eq!(
54            expected,
55            TestDirectivity::directivity_from_dir(&dir, &target)
56        );
57    }
58}