grafix_toolbox/kit/policies/math/
math_ext.rs1pub use ops::Neg;
2
3trait_alias!(
4 pub Number,
5 Cast<i32>
6 + Default
7 + ops::Add<Output = Self>
8 + ops::Sub<Output = Self>
9 + ops::Mul<Output = Self>
10 + ops::Div<Output = Self>
11 + EpsEq
12 + Round
13 + Pow<Self>
14 + EucMod<Self>
15 + Precise
16);
17
18pub trait EpsEq: Copy + cmp::PartialOrd {
19 fn eps_eq(self, r: Self) -> bool {
20 self == r
21 }
22 fn trsh_eq(self, r: Self, _: Self) -> bool {
23 self == r
24 }
25}
26impl_trait_for!(EpsEq = bool, u8, u16, u32, u64, u128, usize, i8, i16, i32, i64, i128, isize);
27impl EpsEq for f16 {
28 fn eps_eq(self, r: Self) -> bool {
29 self.trsh_eq(r, f16::EPSILON)
30 }
31 fn trsh_eq(self, r: Self, e: Self) -> bool {
32 let (l, r) = Vec2((self, r));
33 (l - r).abs() <= f32(e)
34 }
35}
36impl EpsEq for f32 {
37 fn eps_eq(self, r: Self) -> bool {
38 self.trsh_eq(r, f32::EPSILON)
39 }
40 fn trsh_eq(self, r: Self, e: Self) -> bool {
41 (self - r).abs() <= e
42 }
43}
44impl EpsEq for f64 {
45 fn eps_eq(self, r: Self) -> bool {
46 self.trsh_eq(r, f64::EPSILON)
47 }
48 fn trsh_eq(self, r: Self, e: Self) -> bool {
49 (self - r).abs() <= e
50 }
51}
52
53pub trait Round: Copy + cmp::PartialOrd {
54 fn round(self) -> Self {
55 self
56 }
57 fn abs(self) -> Self {
58 self
59 }
60}
61impl_trait_for!(Round = u8, u16, u32, u64, u128, usize);
62macro_rules! rounding {
63 ($($t: ty),+) => {
64 $(impl Round for $t {
65 fn abs(self) -> Self {
66 self.abs()
67 }
68 })+
69 };
70}
71rounding!(i8, i16, i32, i64, i128, isize);
72impl Round for f16 {
73 fn round(self) -> Self {
74 f16(f32(self).round())
75 }
76 fn abs(self) -> Self {
77 f16(f32(self).abs())
78 }
79}
80macro_rules! rounding_f {
81 ($($t: ty),+) => {
82 $(impl Round for $t {
83 fn round(self) -> Self {
84 self.round()
85 }
86 fn abs(self) -> Self {
87 self.abs()
88 }
89 })+
90 };
91}
92rounding_f!(f32, f64);
93
94pub trait Pow<T> {
95 fn power(self, _: T) -> Self;
96}
97macro_rules! pow {
98 ($($t: ty),+) => {
99 $(impl<T> Pow<T> for $t
100 where
101 u32: Cast<T>,
102 {
103 fn power(self, r: T) -> Self {
104 self.pow(u32(r))
105 }
106 })+
107 };
108}
109pow!(u8, i8, u16, i16, u32, i32, u64, i64, u128, i128, usize, isize);
110impl<T> Pow<T> for f16
111where
112 i32: Cast<T>,
113{
114 fn power(self, r: T) -> Self {
115 f16(f32(self).powi(i32(r)))
116 }
117}
118macro_rules! powi {
119 ($($t: ty),+) => {
120 $(impl<T> Pow<T> for $t
121 where
122 i32: Cast<T>,
123 {
124 fn power(self, r: T) -> Self {
125 self.powi(i32(r))
126 }
127 })+
128 };
129}
130powi!(f32, f64);
131
132pub trait EucMod<T> {
133 fn euc_mod(self, _: T) -> Self;
134}
135macro_rules! euc_mod {
136 ($($t: ty),+) => {
137 $(impl<T> EucMod<T> for $t
138 where
139 Self: Cast<T>,
140 {
141 fn euc_mod(self, r: T) -> Self {
142 self.rem_euclid(Self::to(r))
143 }
144 })+
145 };
146}
147euc_mod!(u8, i8, u16, i16, u32, i32, u64, i64, u128, i128, f32, f64, usize, isize);
148impl<T> EucMod<T> for f16
149where
150 f32: Cast<T>,
151{
152 fn euc_mod(self, r: T) -> Self {
153 f16(self.to_f32().rem_euclid(f32(r)))
154 }
155}
156
157pub trait Precise: Default + PartialEq {
158 fn mix(self, a: f32, r: Self) -> Self;
159 fn root(self) -> Self;
160 fn is_zero(&self) -> bool {
161 self == &Default::default()
162 }
163}
164macro_rules! sqrt {
165 ($($t: ty),+) => {
166 $(impl Precise for $t {
167 fn mix(self, a: f32, r: Self) -> Self {
168 Self::to(f32(self) * (1. - a) + f32(r) * a)
169 }
170 fn root(self) -> Self {
171 Self::to(f32(self).sqrt())
172 }
173 })+
174 };
175}
176sqrt!(u8, i8, u16, i16, u32, i32, u64, i64, u128, i128, f16, f32, usize, isize);
177impl Precise for f64 {
178 fn mix(self, a: f32, r: Self) -> Self {
179 let a = f64(a);
180 self * (1. - a) + r * a
181 }
182 fn root(self) -> Self {
183 self.sqrt()
184 }
185}
186
187use super::pre::*;
188use std::{cmp, ops};