use std::borrow::{Borrow, Cow};
use nalgebra::{
allocator::Allocator, DefaultAllocator, DimName, DimNameDiff, DimNameSub, OPoint, U1,
};
use crate::{
curve::NurbsCurve,
misc::FloatingPoint,
prelude::{HasIntersection, HasIntersectionParameter},
};
use super::CurveCurveIntersection;
type Intersection<'a, T, D> = (Cow<'a, NurbsCurve<T, D>>, OPoint<T, DimNameDiff<D, U1>>, T);
#[derive(Debug, Clone)]
pub struct CompoundCurveIntersection<'a, T: FloatingPoint, D: DimName>
where
D: DimNameSub<U1>,
DefaultAllocator: Allocator<D>,
DefaultAllocator: Allocator<DimNameDiff<D, U1>>,
{
a: Intersection<'a, T, D>,
b: Intersection<'a, T, D>,
}
impl<'a, T: FloatingPoint, D: DimName> CompoundCurveIntersection<'a, T, D>
where
D: DimNameSub<U1>,
DefaultAllocator: Allocator<D>,
DefaultAllocator: Allocator<DimNameDiff<D, U1>>,
{
pub fn new(
a: &'a NurbsCurve<T, D>,
b: &'a NurbsCurve<T, D>,
intersection: CurveCurveIntersection<OPoint<T, DimNameDiff<D, U1>>, T>,
) -> Self {
let ((pa, ta), (pb, tb)) = intersection.as_tuple();
Self {
a: (Cow::Borrowed(a), pa, ta),
b: (Cow::Borrowed(b), pb, tb),
}
}
pub fn a_curve(&self) -> &NurbsCurve<T, D> {
self.a.0.borrow()
}
pub fn b_curve(&self) -> &NurbsCurve<T, D> {
self.b.0.borrow()
}
pub fn swap(&mut self) {
std::mem::swap(&mut self.a, &mut self.b);
}
}
impl<T: FloatingPoint, D: DimName> HasIntersectionParameter<T, T>
for CompoundCurveIntersection<'_, T, D>
where
D: DimNameSub<U1>,
DefaultAllocator: Allocator<D>,
DefaultAllocator: Allocator<DimNameDiff<D, U1>>,
{
fn a_parameter(&self) -> T {
self.a.2
}
fn b_parameter(&self) -> T {
self.b.2
}
}
impl<'a, T: FloatingPoint, D: DimName>
HasIntersection<Intersection<'a, T, D>, Intersection<'a, T, D>, T, T>
for CompoundCurveIntersection<'a, T, D>
where
D: DimNameSub<U1>,
DefaultAllocator: Allocator<D>,
DefaultAllocator: Allocator<DimNameDiff<D, U1>>,
{
fn a(&self) -> &Intersection<'a, T, D> {
&self.a
}
fn b(&self) -> &Intersection<'a, T, D> {
&self.b
}
}