use alloc::vec::Vec;
pub type Coord<const D: usize> = [f64; D];
pub(crate) type MatrixRxX<const D: usize> = na::OMatrix<f64, na::Const<D>, na::Dyn>;
pub(crate) fn to_mat<C, const D: usize>(curve: C) -> MatrixRxX<D>
where
C: Curve<D>,
{
MatrixRxX::from_iterator(curve.len(), curve.as_curve().iter().flatten().copied())
}
pub trait Curve<const D: usize>: Sized {
#[must_use]
fn to_curve(self) -> Vec<Coord<D>>;
#[must_use]
fn as_curve(&self) -> &[Coord<D>];
fn len(&self) -> usize {
self.as_curve().len()
}
fn is_empty(&self) -> bool {
self.as_curve().is_empty()
}
#[must_use]
fn closed_lin(self) -> Vec<Coord<D>> {
let mut c = self.to_curve();
c.push(c[0]);
c
}
#[must_use]
fn popped_last(self) -> Vec<Coord<D>> {
let mut curve = self.to_curve();
curve.pop();
curve
}
#[must_use]
fn is_closed(&self) -> bool {
let curve = self.as_curve();
match (curve.first(), curve.last()) {
(Some(a), Some(b)) => a == b,
_ => false,
}
}
}
impl<const D: usize> Curve<D> for Vec<Coord<D>> {
fn to_curve(self) -> Vec<Coord<D>> {
self
}
fn as_curve(&self) -> &[Coord<D>] {
self
}
}
macro_rules! impl_slice {
() => {
fn to_curve(self) -> Vec<Coord<D>> {
self.to_vec()
}
fn as_curve(&self) -> &[Coord<D>] {
self
}
};
}
impl<const D: usize, const N: usize> Curve<D> for [Coord<D>; N] {
impl_slice!();
}
impl<const D: usize> Curve<D> for &[Coord<D>] {
impl_slice!();
}
impl<const D: usize> Curve<D> for alloc::borrow::Cow<'_, [Coord<D>]> {
impl_slice!();
}
impl<const D: usize, T: Curve<D> + Clone> Curve<D> for &T {
fn to_curve(self) -> Vec<Coord<D>> {
self.clone().to_curve()
}
fn as_curve(&self) -> &[Coord<D>] {
(*self).as_curve()
}
}