use num_traits::AsPrimitive;
pub fn length_<T, const N: usize>(
p0: &[T],
p1: &[T]) -> T
where T: num_traits::Float + std::ops::AddAssign
{
let mut x = T::zero();
for i in 0..N {
x += (p0[i]-p1[i])*(p0[i]-p1[i]);
}
x.sqrt()
}
pub fn nearest_to_origin<T, const X: usize>(
p0: &nalgebra::base::SVector<T,X>, p1: &nalgebra::base::SVector<T,X>) -> nalgebra::base::SVector<T,X>
where T: nalgebra::RealField + 'static + Copy,
f64: num_traits::AsPrimitive<T>
{
let d = p1 - p0;
let a: T = d.dot(&d);
if a < 1.0e-20_f64.as_() {
return (p0 + p1) * 0.5_f64.as_();
}
let b = d.dot(p0);
let mut r0: T = -b / a;
if r0 < T::zero() { r0 = T::zero(); }
if r0 > T::one() { r0 = T::one(); }
p0.scale(T::one() - r0) + p1.scale(r0)
}
pub fn distance_to_point<T, const X: usize>(
po_c: &nalgebra::base::SVector<T,X>,
po_s: &nalgebra::base::SVector<T,X>,
po_e: &nalgebra::base::SVector<T,X>) -> T
where T: nalgebra::RealField + 'static + Copy,
f64: num_traits::AsPrimitive<T>
{
crate::edge::nearest_to_origin(&(po_s - po_c), &(po_e - po_c)).norm()
}