1
+ #pragma once
2
+ namespace ZEngine ::Core::Maths
3
+ {
4
+ template <typename T>
5
+ constexpr T DEG_TO_RAD = T(0.017453292519943295769236907684886127 );
6
+
7
+ template <typename T>
8
+ constexpr T RAD_TO_DEG = T(57.295779513082320876798154814105170332 );
9
+
10
+ template <typename T>
11
+ constexpr T PI = T(3.141592653589793238462643383279502884 );
12
+
13
+ template <typename T>
14
+ constexpr T TWO_PI = T(6.283185307179586476925286766559005768 );
15
+
16
+ template <typename T>
17
+ constexpr T HALF_PI = T(1.570796326794896619231321691639751442 );
18
+
19
+ template <typename T>
20
+ constexpr T clamp (T value, T minVal, T maxVal)
21
+ {
22
+ return (value < minVal) ? minVal : (value > maxVal) ? maxVal : value;
23
+ }
24
+
25
+ template <typename T>
26
+ constexpr T min (T a, T b)
27
+ {
28
+ return (a < b) ? a : b;
29
+ }
30
+
31
+ template <typename T>
32
+ constexpr T max (T a, T b)
33
+ {
34
+ return (a > b) ? a : b;
35
+ }
36
+
37
+ template <typename T>
38
+ constexpr T abs (T value)
39
+ {
40
+ return (value < T (0 )) ? -value : value;
41
+ }
42
+
43
+ template <typename T>
44
+ constexpr T radians (T degrees)
45
+ {
46
+ return degrees * DEG_TO_RAD<T>;
47
+ }
48
+
49
+ template <typename T>
50
+ constexpr T degrees (T radians)
51
+ {
52
+ return radians * RAD_TO_DEG<T>;
53
+ }
54
+
55
+ template <typename T>
56
+ constexpr T floor (T x)
57
+ {
58
+ T intPart = static_cast <T>(static_cast <long long >(x));
59
+ return (x < T (0 ) && x != intPart) ? intPart - T (1 ) : intPart;
60
+ }
61
+
62
+ template <typename T>
63
+ T sqrt (T x)
64
+ {
65
+ if (x <= T (0 ))
66
+ {
67
+ return T (0 );
68
+ }
69
+ constexpr T epsilon = (sizeof (T) == sizeof (float )) ? T (1e-7 ) : T (1e-15 );
70
+ T guess = x;
71
+ T prev = T (0 );
72
+ int iteration = 0 ;
73
+ const int max_iteration = 20 ;
74
+ while (abs (guess - prev) > epsilon && iteration < max_iteration)
75
+ {
76
+ prev = guess;
77
+ guess = (guess + x / guess) * T (0.5 );
78
+ ++iteration;
79
+ }
80
+ return guess;
81
+ }
82
+
83
+ template <typename T>
84
+ T sin (T x)
85
+ {
86
+ x -= TWO_PI<T> * floor (x / TWO_PI<T>);
87
+
88
+ T sign = T (1 );
89
+ if (x > HALF_PI<T>)
90
+ {
91
+ x = PI<T> - x;
92
+ sign = -1 ;
93
+ }
94
+ else if (x < -HALF_PI<T>)
95
+ {
96
+ x = -PI<T> - x;
97
+ sign = -1 ;
98
+ }
99
+
100
+ T x2 = x * x;
101
+
102
+ const T c1 = T (-0.16666667 );
103
+ const T c2 = T (0.0083333310 );
104
+ const T c3 = T (-0.00019840874 );
105
+
106
+ T t1 = c2 + c3 * x2;
107
+ T t2 = c1 + t1 * x2;
108
+
109
+ return sign * x * (1 + t2 * x2);
110
+ }
111
+
112
+ template <typename T>
113
+ T cos (T x)
114
+ {
115
+ return sin<T>(HALF_PI<T> - x);
116
+ }
117
+
118
+ template <typename T>
119
+ T atan (T x)
120
+ {
121
+ if (abs (x) > T (1 ))
122
+ {
123
+ T result = (x > T (0 ) ? HALF_PI<T> : -HALF_PI<T>) -atan (T (1 ) / x);
124
+ return result;
125
+ }
126
+
127
+ T x2 = x * x;
128
+
129
+ const T c1 = T (-0.33333333 );
130
+ const T c2 = T (0.2 );
131
+ const T c3 = T (-0.14285714 );
132
+ const T c4 = T (0.11111111 );
133
+
134
+ T t1 = c3 + c4 * x2;
135
+ T t2 = c2 + t1 * x2;
136
+ T t3 = c1 + t2 * x2;
137
+
138
+ return x + x * x2 * t3;
139
+ }
140
+
141
+ template <typename T>
142
+ T atan2 (T y, T x)
143
+ {
144
+ if (x > T (0 ))
145
+ return atan (y / x);
146
+ else if (x < T (0 ))
147
+ {
148
+ if (y >= T (0 ))
149
+ return atan (y / x) + PI<T>;
150
+ else
151
+ return atan (y / x) - PI<T>;
152
+ }
153
+ else
154
+ {
155
+ if (y > T (0 ))
156
+ return HALF_PI<T>;
157
+ else if (y < T (0 ))
158
+ return -HALF_PI<T>;
159
+ else
160
+ return T (0 );
161
+ }
162
+ }
163
+
164
+ template <typename T>
165
+ T acos (T x)
166
+ {
167
+ if (abs (x) > T (1 ))
168
+ return T (0 );
169
+
170
+ if (x == T (0 ))
171
+ return HALF_PI<T>;
172
+
173
+ T sqrt_term = sqrt (T (1 ) - x * x);
174
+ return atan2 (sqrt_term, x);
175
+ }
176
+
177
+ } // namespace ZEngine::Core::Maths
0 commit comments