grafix_toolbox/kit/policies/math/tuple/
math.rs

1use 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, a: M, r: RA) -> Self
11	where
12		f32: Cast<M>,
13	{
14		let a = f32(a);
15		self.apply(r, |l, r| l.mix(a, r))
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 norm(self) -> Self {
61		let l = self.mag();
62		if l.is_zero() {
63			Self::default()
64		} else {
65			self.div(l)
66		}
67	}
68}
69impl<S: TupleMap<A, R<A> = Self> + TupleFold<A> + TupleMath<A, A> + TupleIdentity, A: Number> TupleSelf<A> for S {}
70
71pub trait TupleSigned<A: Neg<Output = A>>: TupleMap<A, R<A> = Self> {
72	fn neg(self) -> Self {
73		self.map(|v| -v)
74	}
75}
76impl<S: TupleMap<A, R<A> = Self>, A: Neg<Output = A>> TupleSigned<A> for S {}
77
78pub trait TupleComparison<B, RA, A: EpsEq>: TupleApply<RA, A, R<bool> = B> {
79	fn ls(self, r: RA) -> B {
80		self.apply(r, |l, r| l < r)
81	}
82	fn gt(self, r: RA) -> B {
83		self.apply(r, |l, r| l > r)
84	}
85	fn le(self, r: RA) -> B {
86		self.apply(r, |l, r| l <= r)
87	}
88	fn ge(self, r: RA) -> B {
89		self.apply(r, |l, r| l >= r)
90	}
91	fn eps_eq(self, r: RA) -> B {
92		self.apply(r, |l, r| l.eps_eq(r))
93	}
94	fn trsh_eq(self, r: RA, e: A) -> B {
95		self.apply(r, |l, r| l.trsh_eq(r, e))
96	}
97}
98impl<S: TupleApply<RA, A, R<bool> = (bool, bool)>, RA, A: EpsEq> TupleComparison<(bool, bool), RA, A> for S {}
99impl<S: TupleApply<RA, A, R<bool> = (bool, bool, bool)>, RA, A: EpsEq> TupleComparison<(bool, bool, bool), RA, A> for S {}
100impl<S: TupleApply<RA, A, R<bool> = (bool, bool, bool, bool)>, RA, A: EpsEq> TupleComparison<(bool, bool, bool, bool), RA, A> for S {}
101impl<const N: usize, S: TupleApply<RA, A, R<bool> = [bool; N]>, RA, A: EpsEq> TupleComparison<[bool; N], RA, A> for S {}
102
103pub trait Tuple2Geometry<A> {
104	fn rotate(self, deg: A) -> Self;
105}
106impl<T: Tuple2<f32>, A> Tuple2Geometry<A> for T
107where
108	f32: Cast<A>,
109	Self: Cast<la::V2>,
110{
111	fn rotate(self, rad: A) -> Self {
112		let rad = std::f32::consts::PI * 2. * f32(rad);
113		let rot = la::na::Rotation2::new(rad);
114		Self::to(rot * la::V2::to(self.get()))
115	}
116}