1use std::ops::*;
2
3pub trait Scalar:
5 Copy
6 + PartialEq
7 + PartialOrd
8 + Add<Self, Output = Self>
9 + Sub<Self, Output = Self>
10 + Mul<Self, Output = Self>
11 + Div<Self, Output = Self>
12 + AddAssign<Self>
13 + SubAssign<Self>
14 + MulAssign<Self>
15 + DivAssign<Self>
16{
17 const ZERO: Self;
19 const ONE: Self;
21 const TWO: Self;
23 fn abs(self) -> Self;
25 fn maxx(self, other: Self) -> Self {
30 if self > other {
31 self
32 } else {
33 other
34 }
35 }
36 fn minn(self, other: Self) -> Self {
41 if self < other {
42 self
43 } else {
44 other
45 }
46 }
47}
48
49macro_rules! scalar_unsigned_impl {
50 ($type:ty) => {
51 impl Scalar for $type {
52 const ZERO: Self = 0;
53 const ONE: Self = 1;
54 const TWO: Self = 2;
55 fn abs(self) -> Self {
56 self
57 }
58 }
59 };
60}
61
62macro_rules! scalar_signed_impl {
63 ($type:ty) => {
64 impl Scalar for $type {
65 const ZERO: Self = 0;
66 const ONE: Self = 1;
67 const TWO: Self = 2;
68 fn abs(self) -> Self {
69 self.abs()
70 }
71 }
72 };
73}
74
75macro_rules! scalar_float_impl {
76 ($type:ty) => {
77 impl Scalar for $type {
78 const ZERO: Self = 0.0;
79 const ONE: Self = 1.0;
80 const TWO: Self = 2.0;
81 fn abs(self) -> Self {
82 self.abs()
83 }
84 }
85 };
86}
87
88scalar_unsigned_impl!(u8);
89scalar_unsigned_impl!(u16);
90scalar_unsigned_impl!(u32);
91scalar_unsigned_impl!(u64);
92scalar_unsigned_impl!(u128);
93scalar_unsigned_impl!(usize);
94
95scalar_signed_impl!(i8);
96scalar_signed_impl!(i16);
97scalar_signed_impl!(i32);
98scalar_signed_impl!(i64);
99scalar_signed_impl!(i128);
100scalar_signed_impl!(isize);
101
102scalar_float_impl!(f32);
103scalar_float_impl!(f64);
104
105pub trait FloatingScalar: Scalar {
107 const TAU: Self;
109 const PI: Self;
111 const EPSILON: Self;
113 fn sqrt(self) -> Self;
115 fn square(self) -> Self {
117 self * self
118 }
119 fn cos(self) -> Self;
121 fn sin(self) -> Self;
123 fn tan(self) -> Self {
125 self.sin() / self.cos()
126 }
127 fn atan2(self, other: Self) -> Self;
129 fn lerp(self, other: Self, t: Self) -> Self {
131 (Self::ONE - t) * self + t * other
132 }
133 fn angle_as_vector(self) -> [Self; 2] {
135 [self.cos(), self.sin()]
136 }
137 fn is_zero(self) -> bool {
139 self.is_near_zero(Self::ONE)
140 }
141 fn is_near_zero(self, n: Self) -> bool {
143 self.abs() < Self::EPSILON * n
144 }
145}
146
147macro_rules! floating_scalar_impl {
148 ($type:ty, $pi:expr, $epsilon:expr) => {
149 impl FloatingScalar for $type {
150 const PI: Self = $pi;
151 const TAU: Self = $pi * 2.0;
152 const EPSILON: Self = $epsilon;
153 fn sqrt(self) -> Self {
154 Self::sqrt(self)
155 }
156 fn cos(self) -> Self {
157 Self::cos(self)
158 }
159 fn sin(self) -> Self {
160 Self::sin(self)
161 }
162 fn atan2(self, other: Self) -> Self {
163 self.atan2(other)
164 }
165 }
166 };
167}
168
169floating_scalar_impl!(f32, std::f32::consts::PI, std::f32::EPSILON);
170floating_scalar_impl!(f64, std::f64::consts::PI, std::f64::EPSILON);