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