use std::cmp::Ordering;
use nalgebra::{allocator::Allocator, DefaultAllocator, DimName, DimNameDiff, DimNameSub, U1};
use crate::{curve::NurbsCurve, misc::FloatingPoint};
#[derive(Clone, Copy, Debug)]
pub enum CurveDirection {
Forward, Backward, Facing, Opposite, }
impl CurveDirection {
pub fn new<T: FloatingPoint, D>(
a: &NurbsCurve<T, D>,
b: &NurbsCurve<T, D>,
epsilon: T,
) -> Option<Self>
where
D: DimName + DimNameSub<U1>,
DefaultAllocator: Allocator<D>,
DefaultAllocator: Allocator<DimNameDiff<D, U1>>,
{
let ad = a.knots_domain();
let bd = b.knots_domain();
let (a0, a1) = (a.point_at(ad.0), a.point_at(ad.1));
let (b0, b1) = (b.point_at(bd.0), b.point_at(bd.1));
let directions = [
((&a1 - &b0).norm(), Self::Forward),
((&a0 - &b1).norm(), Self::Backward),
((&a1 - &b1).norm(), Self::Facing),
((&a0 - &b0).norm(), Self::Opposite),
];
directions
.iter()
.min_by(|a, b| a.0.partial_cmp(&b.0).unwrap_or(Ordering::Equal))
.and_then(|min| if min.0 < epsilon { Some(min.1) } else { None })
}
}