use super::{super::ext::*, super::la, *}; pub trait TupleMath: TupleApply = Self> { fn clmp(self, l: LA, r: RA) -> Self where RA: Cast, { self.fmax(RA::to(l)).fmin(r) } fn mix(self, a: M, r: RA) -> Self where f32: Cast, { let a = f32(a); self.apply(r, |l, r| l.mix(a, r)) } fn sum(self, r: RA) -> Self { self.apply(r, |l, r| l + r) } fn sub(self, r: RA) -> Self { self.apply(r, |l, r| l - r) } fn mul(self, r: RA) -> Self { self.apply(r, |l, r| l * r) } fn div(self, r: RA) -> Self { self.apply(r, |l, r| l / r) } fn powi(self, r: RA) -> Self { self.apply(r, |l, r| l.power(r)) } fn fmin(self, r: RA) -> Self { self.apply(r, |l, r| if l < r { l } else { r }) } fn fmax(self, r: RA) -> Self { self.apply(r, |l, r| if l > r { l } else { r }) } fn rem_euc(self, r: RA) -> Self { self.apply(r, |l, r| l.euc_mod(r)) } } impl = Self>, RA, A: Number> TupleMath for S {} pub trait TupleSelf: TupleMap = Self> + TupleFold + TupleMath + TupleIdentity { fn round(self) -> Self { self.map(|v| v.round()) } fn abs(self) -> Self { self.map(|v| v.abs()) } fn sgn(self) -> Self { self.map(|v| A::to((v >= A::default()) as i32 * 2 - 1)) } fn pow2(self) -> Self { self.map(|v| v * v) } fn mag(self) -> A { self.pow2().fold(|l, r| l + r).root() } fn norm(self) -> Self { let l = self.mag(); if l.is_zero() { Self::default() } else { self.div(l) } } } impl = Self> + TupleFold + TupleMath + TupleIdentity, A: Number> TupleSelf for S {} pub trait TupleSigned>: TupleMap = Self> { fn neg(self) -> Self { self.map(|v| -v) } } impl = Self>, A: Neg> TupleSigned for S {} pub trait TupleComparison: TupleApply = B> { fn ls(self, r: RA) -> B { self.apply(r, |l, r| l < r) } fn gt(self, r: RA) -> B { self.apply(r, |l, r| l > r) } fn le(self, r: RA) -> B { self.apply(r, |l, r| l <= r) } fn ge(self, r: RA) -> B { self.apply(r, |l, r| l >= r) } fn eps_eq(self, r: RA) -> B { self.apply(r, |l, r| l.eps_eq(r)) } fn trsh_eq(self, r: RA, e: A) -> B { self.apply(r, |l, r| l.trsh_eq(r, e)) } } impl = (bool, bool)>, RA, A: EpsEq> TupleComparison<(bool, bool), RA, A> for S {} impl = (bool, bool, bool)>, RA, A: EpsEq> TupleComparison<(bool, bool, bool), RA, A> for S {} impl = (bool, bool, bool, bool)>, RA, A: EpsEq> TupleComparison<(bool, bool, bool, bool), RA, A> for S {} impl = [bool; N]>, RA, A: EpsEq> TupleComparison<[bool; N], RA, A> for S {} pub trait Tuple2Geometry { fn rotate(self, deg: A) -> Self; } impl, A> Tuple2Geometry for T where f32: Cast, Self: Cast, { fn rotate(self, rad: A) -> Self { let rad = std::f32::consts::PI * 2. * f32(rad); let rot = la::na::Rotation2::new(rad); Self::to(rot * la::V2::to(self.get())) } }