autd3-rs-core 0.9.0

Core types and link abstraction shared across the AUTD3 phased-array sdk crates.
Documentation
use super::{Focus, Intensity, Phase};
use crate::geometry::{Device, Point3};

const FOCUS_UNIT_MM: f32 = 0.025;

#[allow(clippy::cast_possible_truncation, clippy::cast_sign_loss)]
fn to_fixed(mm: f32) -> i32 {
    (mm / FOCUS_UNIT_MM).round() as i32
}

#[derive(Clone, Copy, Debug, PartialEq)]
pub struct ControlPoint {
    pub point: Point3<f32>,
    pub phase_offset: Phase,
}

impl ControlPoint {
    #[must_use]
    pub const fn new(point: Point3<f32>, phase_offset: Phase) -> Self {
        Self {
            point,
            phase_offset,
        }
    }
}

impl From<Point3<f32>> for ControlPoint {
    fn from(point: Point3<f32>) -> Self {
        Self {
            point,
            phase_offset: Phase::ZERO,
        }
    }
}

#[derive(Clone, Copy, Debug, PartialEq)]
pub struct ControlPoints<const N: usize> {
    pub points: [ControlPoint; N],
    pub intensity: Intensity,
}

impl<const N: usize> ControlPoints<N> {
    #[must_use]
    pub const fn new(points: [ControlPoint; N], intensity: Intensity) -> Self {
        Self { points, intensity }
    }

    #[doc(hidden)]
    #[must_use]
    pub fn focus(&self, device: &Device, j: usize) -> Focus {
        let cp = self.points[j];
        let p = device.to_local(cp.point);
        Focus {
            x: to_fixed(p.x),
            y: to_fixed(p.y),
            z: to_fixed(p.z),
            intensity_or_offset: if j == 0 {
                self.intensity.0
            } else {
                (cp.phase_offset - self.points[0].phase_offset).0
            },
        }
    }
}

impl From<Point3<f32>> for ControlPoints<1> {
    fn from(point: Point3<f32>) -> Self {
        Self {
            points: [ControlPoint::from(point)],
            intensity: Intensity::MAX,
        }
    }
}

impl From<ControlPoint> for ControlPoints<1> {
    fn from(point: ControlPoint) -> Self {
        Self {
            points: [point],
            intensity: Intensity::MAX,
        }
    }
}

impl<const N: usize> From<[Point3<f32>; N]> for ControlPoints<N> {
    fn from(points: [Point3<f32>; N]) -> Self {
        Self {
            points: points.map(ControlPoint::from),
            intensity: Intensity::MAX,
        }
    }
}