autd3-rs-core 0.9.0

Core types and link abstraction shared across the AUTD3 phased-array sdk crates.
Documentation
use nalgebra::{Isometry3, Point3, Translation3, UnitQuaternion, UnitVector3, Vector3};

#[derive(Clone, Debug)]
pub struct Device {
    idx: usize,
    rotation: UnitQuaternion<f32>,
    positions: Vec<Point3<f32>>,
    directions: Vec<UnitVector3<f32>>,
    inv: Isometry3<f32>,
}

impl Device {
    pub(super) fn new(
        rotation: UnitQuaternion<f32>,
        positions: Vec<Point3<f32>>,
        directions: Vec<UnitVector3<f32>>,
    ) -> Self {
        debug_assert_eq!(positions.len(), directions.len());
        let origin = positions.first().copied().unwrap_or_else(Point3::origin);
        let inv = (Translation3::from(origin) * rotation).inverse();
        Self {
            idx: 0,
            rotation,
            positions,
            directions,
            inv,
        }
    }

    #[must_use]
    pub fn to_local(&self, p: Point3<f32>) -> Point3<f32> {
        self.inv * p
    }

    pub(super) fn set_idx(&mut self, idx: usize) {
        self.idx = idx;
    }

    #[must_use]
    pub const fn idx(&self) -> usize {
        self.idx
    }

    #[must_use]
    pub const fn rotation(&self) -> UnitQuaternion<f32> {
        self.rotation
    }

    #[must_use]
    pub fn x_direction(&self) -> UnitVector3<f32> {
        self.rotation * Vector3::x_axis()
    }

    #[must_use]
    pub fn y_direction(&self) -> UnitVector3<f32> {
        self.rotation * Vector3::y_axis()
    }

    #[must_use]
    pub fn axial_direction(&self) -> UnitVector3<f32> {
        self.rotation * Vector3::z_axis()
    }

    #[must_use]
    pub const fn num_transducers(&self) -> usize {
        self.positions.len()
    }

    #[must_use]
    pub const fn is_empty(&self) -> bool {
        self.positions.is_empty()
    }

    #[must_use]
    pub fn positions(&self) -> &[Point3<f32>] {
        &self.positions
    }

    #[must_use]
    pub fn directions(&self) -> &[UnitVector3<f32>] {
        &self.directions
    }

    #[must_use]
    pub fn position(&self, index: usize) -> Point3<f32> {
        self.positions[index]
    }

    #[must_use]
    pub fn direction(&self, index: usize) -> UnitVector3<f32> {
        self.directions[index]
    }

    #[must_use]
    pub fn center(&self) -> Point3<f32> {
        let n = self.positions.len() as f32;
        let sum = self
            .positions
            .iter()
            .fold(Vector3::zeros(), |acc, p| acc + p.coords);
        Point3::from(sum / n)
    }
}