grafix_toolbox/kit/policies/math/tuple/
math.rs1use super::{super::ext::*, super::la};
2
3pub trait TupleMath<RA, A: Number>: TupleApply<RA, A, R<A> = Self> {
4 fn clmp<LA>(self, l: LA, r: RA) -> Self
5 where
6 RA: Cast<LA>,
7 {
8 self.fmax(RA::to(l)).fmin(r)
9 }
10 fn mix<M>(self, r: RA, a: M) -> Self
11 where
12 f32: Cast<M>,
13 {
14 let a = f32(a);
15 self.apply(r, |l, r| l.mix(r, a))
16 }
17 fn sum(self, r: RA) -> Self {
18 self.apply(r, |l, r| l + r)
19 }
20 fn sub(self, r: RA) -> Self {
21 self.apply(r, |l, r| l - r)
22 }
23 fn mul(self, r: RA) -> Self {
24 self.apply(r, |l, r| l * r)
25 }
26 fn div(self, r: RA) -> Self {
27 self.apply(r, |l, r| l / r)
28 }
29 fn powi(self, r: RA) -> Self {
30 self.apply(r, |l, r| l.power(r))
31 }
32 fn fmin(self, r: RA) -> Self {
33 self.apply(r, |l, r| if l < r { l } else { r })
34 }
35 fn fmax(self, r: RA) -> Self {
36 self.apply(r, |l, r| if l > r { l } else { r })
37 }
38 fn rem_euc(self, r: RA) -> Self {
39 self.apply(r, |l, r| l.euc_mod(r))
40 }
41}
42impl<S: TupleApply<RA, A, R<A> = Self>, RA, A: Number> TupleMath<RA, A> for S {}
43
44pub trait TupleSelf<A: Number>: TupleMap<A, R<A> = Self> + TupleFold<A> + TupleMath<A, A> + TupleIdentity {
45 fn round(self) -> Self {
46 self.map(|v| v.round())
47 }
48 fn abs(self) -> Self {
49 self.map(|v| v.abs())
50 }
51 fn sgn(self) -> Self {
52 self.map(|v| A::to((v >= A::default()) as i32 * 2 - 1))
53 }
54 fn pow2(self) -> Self {
55 self.map(|v| v * v)
56 }
57 fn mag(self) -> A {
58 self.pow2().fold(|l, r| l + r).root()
59 }
60 fn min_comp(self) -> A {
61 self.fold(|l, r| if l < r { l } else { r })
62 }
63 fn max_comp(self) -> A {
64 self.fold(|l, r| if l > r { l } else { r })
65 }
66 fn norm(self) -> Self {
67 let l = self.mag();
68 if l.is_zero() { Self::default() } else { self.div(l) }
69 }
70}
71impl<S: TupleMap<A, R<A> = Self> + TupleFold<A> + TupleMath<A, A> + TupleIdentity, A: Number> TupleSelf<A> for S {}
72
73pub trait TupleSigned<A: Neg<Output = A>>: TupleMap<A, R<A> = Self> {
74 fn neg(self) -> Self {
75 self.map(|v| -v)
76 }
77}
78impl<S: TupleMap<A, R<A> = Self>, A: Neg<Output = A>> TupleSigned<A> for S {}
79
80pub trait TupleComparison<B, RA, A: EpsEq>: TupleApply<RA, A, R<bool> = B> {
81 fn ls(self, r: RA) -> B {
82 self.apply(r, |l, r| l < r)
83 }
84 fn gt(self, r: RA) -> B {
85 self.apply(r, |l, r| l > r)
86 }
87 fn le(self, r: RA) -> B {
88 self.apply(r, |l, r| l <= r)
89 }
90 fn ge(self, r: RA) -> B {
91 self.apply(r, |l, r| l >= r)
92 }
93 fn eps_eq(self, r: RA) -> B {
94 self.apply(r, |l, r| l.eps_eq(r))
95 }
96 fn trsh_eq(self, r: RA, e: A) -> B {
97 self.apply(r, |l, r| l.trsh_eq(r, e))
98 }
99}
100impl<S: TupleApply<RA, A, R<bool> = (bool, bool)>, RA, A: EpsEq> TupleComparison<(bool, bool), RA, A> for S {}
101impl<S: TupleApply<RA, A, R<bool> = (bool, bool, bool)>, RA, A: EpsEq> TupleComparison<(bool, bool, bool), RA, A> for S {}
102impl<S: TupleApply<RA, A, R<bool> = (bool, bool, bool, bool)>, RA, A: EpsEq> TupleComparison<(bool, bool, bool, bool), RA, A> for S {}
103impl<const N: usize, S: TupleApply<RA, A, R<bool> = [bool; N]>, RA, A: EpsEq> TupleComparison<[bool; N], RA, A> for S {}
104
105pub trait Tuple2Geometry<A> {
106 fn rotate(self, deg: A) -> Self;
107}
108impl<A> Tuple2Geometry<A> for (A, A)
109where
110 f32: Cast<A>,
111 Self: Cast<la::V2>,
112{
113 fn rotate(self, rad: A) -> Self {
114 let rad = std::f32::consts::PI * 2. * f32(rad);
115 let rot = la::na::Rotation2::new(rad);
116 Self::to(rot * la::V2::to(Vec2(self)))
117 }
118}