use crate::math::consts::ConstSqrt2;
use crate::math::mla;
use num_traits::{AsPrimitive, MulAdd};
use std::ops::{Add, Div, Mul, Neg, Sub};
#[inline]
fn bc_spline<
V: Copy
+ Add<Output = V>
+ Mul<Output = V>
+ Sub<Output = V>
+ Div<Output = V>
+ 'static
+ PartialEq
+ PartialOrd
+ Neg<Output = V>
+ MulAdd<Output = V>,
>(
d: V,
b: V,
c: V,
) -> V
where
f32: AsPrimitive<V>,
{
let mut x = d;
if x < 0.0f32.as_() {
x = -x;
}
let dp = x * x;
let tp = dp * x;
if x < 1f32.as_() {
return (mla(-6f32.as_(), c, mla(-9f32.as_(), b, 12f32.as_())) * tp
+ mla(6f32.as_(), c, mla(12f32.as_(), b, -18f32.as_())) * dp
+ mla(-2f32.as_(), b, 6f32.as_()))
* (1f32.as_() / 6f32.as_());
} else if x < 2f32.as_() {
return (mla(-6f32.as_(), c, -b) * tp
+ mla(6f32.as_(), b, 30f32.as_() * c) * dp
+ mla((-12f32).as_(), b, -48f32.as_() * c) * x
+ mla(8f32.as_(), b, 24f32.as_() * c))
* (1f32.as_() / 6f32.as_());
}
0f32.as_()
}
pub(crate) fn hermite_spline<
V: Copy
+ Add<Output = V>
+ Mul<Output = V>
+ Sub<Output = V>
+ Div<Output = V>
+ 'static
+ PartialEq
+ PartialOrd
+ Neg<Output = V>
+ MulAdd<Output = V>,
>(
x: V,
) -> V
where
f32: AsPrimitive<V>,
{
bc_spline(x, 0f32.as_(), 0f32.as_())
}
pub(crate) fn b_spline<
V: Copy
+ Add<Output = V>
+ Mul<Output = V>
+ Sub<Output = V>
+ Div<Output = V>
+ 'static
+ PartialEq
+ PartialOrd
+ Neg<Output = V>
+ MulAdd<Output = V>,
>(
x: V,
) -> V
where
f32: AsPrimitive<V>,
{
bc_spline(x, 1f32.as_(), 0f32.as_())
}
pub(crate) fn mitchell_netravalli<
V: Copy
+ Add<Output = V>
+ Mul<Output = V>
+ Sub<Output = V>
+ Div<Output = V>
+ 'static
+ PartialEq
+ PartialOrd
+ Neg<Output = V>
+ MulAdd<Output = V>,
>(
x: V,
) -> V
where
f32: AsPrimitive<V>,
{
bc_spline(x, 1f32.as_() / 3f32.as_(), 1f32.as_() / 3f32.as_())
}
pub(crate) fn catmull_rom<
V: Copy
+ Add<Output = V>
+ Mul<Output = V>
+ Sub<Output = V>
+ Div<Output = V>
+ 'static
+ PartialEq
+ PartialOrd
+ Neg<Output = V>
+ MulAdd<Output = V>,
>(
x: V,
) -> V
where
f32: AsPrimitive<V>,
{
bc_spline(x, 0f32.as_(), 0.5f32.as_())
}
pub(crate) fn robidoux<
V: Copy
+ Add<Output = V>
+ Mul<Output = V>
+ Sub<Output = V>
+ Div<Output = V>
+ 'static
+ PartialEq
+ PartialOrd
+ Neg<Output = V>
+ ConstSqrt2
+ MulAdd<Output = V>,
>(
x: V,
) -> V
where
f32: AsPrimitive<V>,
{
bc_spline(
x,
12f32.as_() / mla(9f32.as_(), V::const_sqrt2(), 19f32.as_()),
13f32.as_() / mla(216f32.as_(), V::const_sqrt2(), 58f32.as_()),
)
}
pub(crate) fn robidoux_sharp<
V: Copy
+ Add<Output = V>
+ Mul<Output = V>
+ Sub<Output = V>
+ Div<Output = V>
+ 'static
+ PartialEq
+ PartialOrd
+ Neg<Output = V>
+ ConstSqrt2
+ MulAdd<Output = V>,
>(
x: V,
) -> V
where
f32: AsPrimitive<V>,
{
bc_spline(
x,
6f32.as_() / mla(7f32.as_(), V::const_sqrt2(), 13f32.as_()),
7f32.as_() / mla(12f32.as_(), V::const_sqrt2(), 2f32.as_()),
)
}