BEEP-8 Helper Lib 1.0.0
Loading...
Searching...
No Matches
submath.h
Go to the documentation of this file.
1
44#pragma once
45#include <submath.h>
46#include <fixed.h>
47#include <fxmath.h>
48#include <b8/type.h>
49
57inline std::string tostr(const fx8& val) {
58 float float_value = static_cast< float >( val );
59 return std::to_string( float_value );
60}
61
62constexpr fx8 FX8_E = fx8(696, 256); // 2.718281828459045 (e)
63constexpr fx8 FX8_LOG2E = fx8(369, 256); // 1.4426950408889634 (log2(e))
64constexpr fx8 FX8_LOG10E = fx8(111, 256); // 0.4342944819032518 (log10(e))
65constexpr fx8 FX8_LN2 = fx8(178, 256); // 0.6931471805599453 (ln(2))
66constexpr fx8 FX8_LN10 = fx8(590, 256); // 2.3025850929940457 (ln(10))
67constexpr fx8 FX8_1_PI = fx8(82, 256); // 0.3183098861837907 (1/π)
68constexpr fx8 FX8_2_PI = fx8(163, 256); // 0.6366197723675814 (2/π)
69constexpr fx8 FX8_2_SQRTPI = fx8(289, 256); // 1.1283791670955126 (2/√π)
70constexpr fx8 FX8_SQRT2 = fx8(362, 256); // 1.4142135623730951 (√2)
71constexpr fx8 FX8_SQRT1_2 = fx8(181, 256); // 0.7071067811865475 (1/√2)
72constexpr fx8 FX8_2PI = fx8(1608, 256); // 6.283185307179586 (2π)
73constexpr fx8 FX8_PI = fx8(804, 256); // 3.141592653589793 (π)
74constexpr fx8 FX8_PI_2 = fx8(402, 256); // 1.5707963267948966 (π/2)
75constexpr fx8 FX8_PI_3 = fx8(268, 256); // 1.0471975511965976 (π/3)
76constexpr fx8 FX8_PI_4 = fx8(201, 256); // 0.7853981633974483 (π/4)
77constexpr fx8 FX8_PI_5 = fx8(161, 256); // 0.6283185307179586 (π/5)
78constexpr fx8 FX8_PI_6 = fx8(134, 256); // 0.5235987755982988 (π/6)
79constexpr fx8 FX8_PI_7 = fx8(115, 256); // 0.4487989505128276 (π/7)
80constexpr fx8 FX8_PI_8 = fx8(100, 256); // 0.39269908169872414 (π/8)
81constexpr fx8 FX8_PI_9 = fx8(89, 256); // 0.3490658503988659 (π/9)
82constexpr fx8 FX8_PI_10 = fx8(80, 256); // 0.3141592653589793 (π/10)
83constexpr fx8 FX8_PI_11 = fx8(73, 256); // 0.28559933214452665 (π/11)
84constexpr fx8 FX8_PI_12 = fx8(67, 256); // 0.2617993877991494 (π/12)
85constexpr fx8 FX8_PI_13 = fx8(62, 256); // 0.241660973353061 (π/13)
86constexpr fx8 FX8_PI_14 = fx8(57, 256); // 0.2243994752564138 (π/14)
87constexpr fx8 FX8_PI_15 = fx8(54, 256); // 0.20943951023931953 (π/15)
88constexpr fx8 FX8_PI_16 = fx8(50, 256); // 0.19634954084936207 (π/16)
89
97
98constexpr fx12 FX12_E = fx12(11135, 4096); // 2.718281828459045 (e)
99constexpr fx12 FX12_LOG2E = fx12(5912, 4096); // 1.4426950408889634 (log2(e))
100constexpr fx12 FX12_LOG10E = fx12(1785, 4096); // 0.4342944819032518 (log10(e))
101constexpr fx12 FX12_LN2 = fx12(2831, 4096); // 0.6931471805599453 (ln(2))
102constexpr fx12 FX12_LN10 = fx12(9438, 4096); // 2.3025850929940457 (ln(10))
103constexpr fx12 FX12_1_PI = fx12(1317, 4096); // 0.3183098861837907 (1/π)
104constexpr fx12 FX12_2_PI = fx12(2634, 4096); // 0.6366197723675814 (2/π)
105constexpr fx12 FX12_2_SQRTPI = fx12(4613, 4096); // 1.1283791670955126 (2/√π)
106constexpr fx12 FX12_SQRT2 = fx12(5793, 4096); // 1.4142135623730951 (√2)
107constexpr fx12 FX12_SQRT1_2 = fx12(2896, 4096); // 0.7071067811865475 (1/√2)
108constexpr fx12 FX12_PI = fx12(12868, 4096); // 3.141592653589793 (π)
109constexpr fx12 FX12_PI_2 = fx12(6434, 4096); // 1.5707963267948966 (π/2)
110constexpr fx12 FX12_PI_3 = fx12(4290, 4096); // 1.0471975511965976 (π/3)
111constexpr fx12 FX12_PI_4 = fx12(3217, 4096); // 0.7853981633974483 (π/4)
112constexpr fx12 FX12_PI_5 = fx12(2574, 4096); // 0.6283185307179586 (π/5)
113constexpr fx12 FX12_PI_6 = fx12(2145, 4096); // 0.5235987755982988 (π/6)
114constexpr fx12 FX12_PI_7 = fx12(1838, 4096); // 0.4487989505128276 (π/7)
115constexpr fx12 FX12_PI_8 = fx12(1609, 4096); // 0.39269908169872414 (π/8)
116constexpr fx12 FX12_PI_9 = fx12(1432, 4096); // 0.3490658503988659 (π/9)
117constexpr fx12 FX12_PI_10 = fx12(1287, 4096); // 0.3141592653589793 (π/10)
118constexpr fx12 FX12_PI_11 = fx12(1171, 4096); // 0.28559933214452665 (π/11)
119constexpr fx12 FX12_PI_12 = fx12(1072, 4096); // 0.2617993877991494 (π/12)
120constexpr fx12 FX12_PI_13 = fx12(989, 4096); // 0.241660973353061 (π/13)
121constexpr fx12 FX12_PI_14 = fx12(919, 4096); // 0.2243994752564138 (π/14)
122constexpr fx12 FX12_PI_15 = fx12(858, 4096); // 0.20943951023931953 (π/15)
123constexpr fx12 FX12_PI_16 = fx12(804, 4096); // 0.19634954084936207 (π/16)
124struct Rect;
125class Vec {
126public:
127 fx8 x;
128 fx8 y;
129
130 // Constructs the vector with optional initial coordinates
131 Vec(fx8 x_ = 0, fx8 y_ = 0) : x(x_), y(y_) {}
132
133 // Sets the coordinates
134 Vec& set(fx8 x_ = 0, fx8 y_ = 0);
135
136 // Adds specified values to the vector
137 Vec& add(fx8 x_ = 0, fx8 y_ = 0);
138
139 // Subtracts specified values from the vector
140 Vec& sub(fx8 x_ = 0, fx8 y_ = 0);
141
142 // Multiplies the vector by a scalar
143 Vec& mul(fx8 v);
144
145 // Divides the vector by a scalar
146 Vec& div(fx8 v);
147
148 // Clamps the vector within a specified range
149 Vec& clamp(fx8 xLow, fx8 xHigh, fx8 yLow, fx8 yHigh);
150
151 // Wraps the vector's coordinates around the specified range
152 Vec& wrap(fx8 xLow, fx8 xHigh, fx8 yLow, fx8 yHigh);
153
154 // Sets the vector by using an angle and a length
155 Vec& setWithAngle(fx8 angle, fx8 length);
156
157 // Adds to the vector by using an angle and a length
158 Vec& addWithAngle(fx8 angle, fx8 length);
159
160 // Swaps the x and y components
161 Vec& swapXy();
162
163 // Normalizes the vector
164 Vec& normalize();
165
166 // Rotates the vector by a specified angle
167 Vec& rotate(fx8 angle);
168
169 // Returns the angle from this vector to given coordinates
170 fx8 angleTo(fx8 x_, fx8 y_) const;
171
172 // Returns the distance from this vector to given coordinates
173 fx8 distanceTo(fx8 x_, fx8 y_) const;
174
175 // Returns the distance from this vector to another vector
176 fx8 distanceTo(const Vec& xy_) const;
177
178 // Checks if the vector is inside the specified rectangle
179 bool isInRect(fx8 x_, fx8 y_, fx8 width, fx8 height) const;
180 bool isInRect(const Rect& rc ) const;
181
182 // Checks if this vector equals another vector
183 bool equals(const Vec& other) const;
184
185 // Floors the vector's coordinates
186 Vec& floor();
187
188 // Rounds the vector's coordinates
189 Vec& round();
190
191 // Ceils the vector's coordinates
192 Vec& ceil();
193
194 // Returns the length of the vector
195 fx8 length() const;
196
197 // Returns the angle of the vector
198 fx8 angle() const;
199
200 // Member function that negates the vector components
201 // (reverses the signs of x and y)
202 Vec& negative() {
203 x = -x;
204 y = -y;
205 return *this;
206 }
207
208 // Returns the result of vector addition
209 Vec operator+(const Vec& other) const {
210 return Vec(x + other.x, y + other.y);
211 }
212
213 // Returns the result of vector subtraction
214 Vec operator-(const Vec& other) const {
215 return Vec(x - other.x, y - other.y);
216 }
217
218 // Adds a vector to this vector
219 Vec& operator+=(const Vec& other) {
220 x += other.x;
221 y += other.y;
222 return *this;
223 }
224
225 // Subtracts a vector from this vector
226 Vec& operator-=(const Vec& other) {
227 x -= other.x;
228 y -= other.y;
229 return *this;
230 }
231
232 // Returns the result of multiplying this vector by a scalar
233 Vec operator*(fx8 scalar) const {
234 return Vec(x * scalar, y * scalar);
235 }
236
237 // Multiplies this vector by a scalar
238 Vec& operator*=(fx8 scalar) {
239 x *= scalar;
240 y *= scalar;
241 return *this;
242 }
243
244 // Returns the result of element-wise vector multiplication
245 Vec operator*(const Vec& other) const {
246 return Vec(x * other.x, y * other.y);
247 }
248
249 // Performs element-wise vector multiplication
250 Vec& operator*=(const Vec& other) {
251 x *= other.x;
252 y *= other.y;
253 return *this;
254 }
255
256 // Returns the result of element-wise vector division
257 Vec operator/(const Vec& other) const {
258 fx8 rx = (other.x == 0) ? fx8(0) : (x / other.x);
259 fx8 ry = (other.y == 0) ? fx8(0) : (y / other.y);
260 return Vec(rx, ry);
261 }
262
263 // Performs element-wise vector division
264 Vec& operator/=(const Vec& other) {
265 if (other.x == 0) {
266 x = fx8(0);
267 } else {
268 x /= other.x;
269 }
270 if (other.y == 0) {
271 y = fx8(0);
272 } else {
273 y /= other.y;
274 }
275 return *this;
276 }
277
278 // Returns the result of dividing this vector by a scalar
279 Vec operator/(fx8 scalar) const {
280 Vec tmp(*this);
281 tmp.div(scalar);
282 return tmp;
283 }
284
285 // Divides this vector by a scalar
286 Vec& operator/=(fx8 scalar) {
287 return div(scalar);
288 }
289
303 Vec& clampLength(fx8 maxLength) {
304 fx8 currentLen = length(); // Get the current length of the vector
305 if (currentLen > maxLength && currentLen != fx8(0)) {
306 fx8 scale = maxLength / currentLen; // Calculate the scaling factor
307 x *= scale;
308 y *= scale;
309 }
310 return *this;
311 }
312};
313
314inline std::string tostr(const Vec& val) {
315 return '(' + tostr( val.x ) + " , " + tostr( val.y ) + ')';
316}
317
327struct Line {
330
334 Line() = default;
335
342 Line(const Vec& p0, const Vec& p1) : pos0(p0), pos1(p1) {}
343};
344
355struct Poly {
359
360 Poly() = default;
361 Poly( fx8 x0,fx8 y0,fx8 x1,fx8 y1,fx8 x2,fx8 y2 ){
362 pos0.x = x0; pos0.y = y0;
363 pos1.x = x1; pos1.y = y1;
364 pos2.x = x2; pos2.y = y2;
365 }
366};
367
368
372struct Rect{
373 fx8 x;
374 fx8 y;
375 fx8 w;
376 fx8 h;
377
386 void SetXYWH( fx8 x_ , fx8 y_ , fx8 w_ , fx8 h_ ){
387 x = x_;
388 y = y_;
389 w = w_;
390 h = h_;
391 }
392
399 fx8 ww(w);
400 ww.asr(1);
401 return x + w;
402 }
403
404 Rect( fx8 x_ , fx8 y_ , fx8 w_ , fx8 h_ ){
405 SetXYWH( x_ , y_ , w_ , h_ );
406 }
407 Rect(){}
408};
409
410inline std::string tostr(const Rect& val) {
411 return '(' + tostr( val.x ) + "," + tostr( val.y ) + " , " +
412 tostr( val.w ) + "," + tostr( val.h ) + ')';
413
414};
415
423inline const fx8& _min(const fx8& lhs_ , const fx8& rhs_ ){
424 return lhs_ < rhs_ ? lhs_ : rhs_;
425}
426
434inline const fx8& _max(const fx8& lhs_ , const fx8& rhs_ ){
435 return lhs_ > rhs_ ? lhs_ : rhs_;
436}
437
446inline const fx8& _lim( const fx8& x_, const fx8& lhs_, const fx8& rhs_){
447 return _min( _max( lhs_, x_ ), rhs_ );
448}
449
456inline const fx8 _abs(const fx8& x_ ){
457 return x_ > fx8(0) ? x_ : -x_;
458}
459
473template <typename T, typename U, typename V>
474inline T lim(const T& x_, const U& lhs_, const V& rhs_) {
475 return std::min(static_cast<T>(std::max(x_, static_cast<T>(lhs_))), static_cast<T>(rhs_));
476}
477
484extern s16 sin_12( u32 th );
485
492extern s16 cos_12( u32 th );
493
501extern fx8 rad_cos_12( fx8 rad, u32 th );
502
510extern fx8 rad_sin_12( fx8 rad, u32 th );
511
519extern fx8 genrand_min_max_fx8(fx8 min_ , fx8 max_ );
520
539extern uint32_t qmod(uint32_t x, uint32_t N);
540
559extern uint32_t qdiv(uint32_t x, uint32_t N);
560
561#define M_E 2.71828182845904523536028747135266250 /* e */
562#define M_LOG2E 1.44269504088896340735992468100189214 /* log2(e) */
563#define M_LOG10E 0.434294481903251827651128918916605082 /* log10(e) */
564#define M_LN2 0.693147180559945309417232121458176568 /* loge(2) */
565#define M_LN10 2.30258509299404568401799145468436421 /* loge(10) */
566#define M_PI 3.14159265358979323846264338327950288 /* pi */
567#define M_PI_2 1.57079632679489661923132169163975144 /* pi/2 */
568#define M_PI_4 0.785398163397448309615660845819875721 /* pi/4 */
569#define M_1_PI 0.318309886183790671537767526745028724 /* 1/pi */
570#define M_2_PI 0.636619772367581343075535053490057448 /* 2/pi */
571#define M_2_SQRTPI 1.12837916709551257389615890312154517 /* 2/sqrt(pi) */
572#define M_SQRT2 1.41421356237309504880168872420969808 /* sqrt(2) */
573#define M_SQRT1_2 0.707106781186547524400844362104849039 /* 1/sqrt(2) */
574
576 u32 state;
577
578 explicit Xorshift32(uint32_t seed = 0xA5A5A5A5 ) : state(seed) {
579 if (state == 0) state = 1;
580 }
581
582 u32 next() {
583 state ^= state << 13;
584 state ^= state >> 17;
585 state ^= state << 5;
586 return state;
587 }
588
596 s32 next_int31(void){
597 return static_cast< s32 >( next()>>1 );
598 }
599
609 s32 next_range(int32_t min_, int32_t max_) {
610 if (min_ > max_) std::swap(min_, max_);
611 const uint64_t range = static_cast<uint64_t>(max_) - static_cast<uint64_t>(min_) + 1;
612 if (range > static_cast<uint64_t>(0x7fffffff)) {
613 int32_t random_val;
614 do {
615 random_val = this->next_int31();
616 } while (static_cast<uint64_t>(random_val) >= range);
617 return min_ + random_val;
618 } else {
619 return min_ + qmod( this->next_int31() , static_cast<int32_t>(range) );
620 }
621 }
622};
623
624#define MAXFLOAT 0x1.fffffep+127f
Definition submath.h:125
Vec & clampLength(fx8 maxLength)
Clamps the length of the vector to the specified maximum value.
Definition submath.h:303
Represents a line segment in 2D space defined by two points.
Definition submath.h:327
Vec pos1
The ending point of the line.
Definition submath.h:329
Line(const Vec &p0, const Vec &p1)
Constructor that initializes the line with given starting and ending points.
Definition submath.h:342
Line()=default
Default constructor that initializes both points to (0, 0).
Vec pos0
The starting point of the line.
Definition submath.h:328
Represents a triangle in 2D space using three points.
Definition submath.h:355
Poly()=default
Default constructor.
Vec pos0
The first vertex of the triangle.
Definition submath.h:356
Vec pos2
The third vertex of the triangle.
Definition submath.h:358
Vec pos1
The second vertex of the triangle.
Definition submath.h:357
A structure for representing rectangles with fixed-point coordinates.
Definition submath.h:372
void SetXYWH(fx8 x_, fx8 y_, fx8 w_, fx8 h_)
Set the coordinates and dimensions of the rectangle.
Definition submath.h:386
fx8 MiddlePointX()
Calculate the middle point x-coordinate of the rectangle.
Definition submath.h:398
Definition submath.h:575
s32 next_range(int32_t min_, int32_t max_)
Generates a random number in the specified range [min_, max_].
Definition submath.h:609
s32 next_int31(void)
Generates a random number on [0, 0x7fffffff] interval.
Definition submath.h:596
Provides mathematical functions and utilities, primarily focused on fixed-point arithmetic.
T lim(const T &x_, const U &lhs_, const V &rhs_)
Limit a value within a specified range.
Definition submath.h:474
const fx8 & _max(const fx8 &lhs_, const fx8 &rhs_)
Get the maximum of two fixed-point values.
Definition submath.h:434
const fx8 & _lim(const fx8 &x_, const fx8 &lhs_, const fx8 &rhs_)
Limit a fixed-point value within a specified range.
Definition submath.h:446
s16 cos_12(u32 th)
Calculate the cosine of an angle using a 12-bit angle representation.
Definition submath.cpp:1040
fx8 rad_sin_12(fx8 rad, u32 th)
Calculate the sine of an angle and scale a fixed-point value by it.
Definition submath.cpp:1052
fx8 genrand_min_max_fx8(fx8 min_, fx8 max_)
Generate a random fixed-point number within a specified range.
Definition submath.cpp:1060
s16 sin_12(u32 th)
Calculate the sine of an angle using a 12-bit angle representation.
Definition submath.cpp:1033
fpm::fixed< std::int32_t, std::int64_t, 12 > fx12
Alias for fixed-point type with 12 fractional bits.
Definition submath.h:96
fpm::fixed< std::int32_t, std::int64_t, 8 > fx8
Alias for fixed-point type with 8 fractional bits.
Definition submath.h:56
uint32_t qdiv(uint32_t x, uint32_t N)
Computes the quotient of x divided by N using an optimized method.
Definition submath.cpp:1265
const fx8 _abs(const fx8 &x_)
Get the absolute value of a fixed-point number.
Definition submath.h:456
uint32_t qmod(uint32_t x, uint32_t N)
Computes the remainder of x divided by N using an optimized method.
Definition submath.cpp:1255
const fx8 & _min(const fx8 &lhs_, const fx8 &rhs_)
Get the minimum of two fixed-point values.
Definition submath.h:423
fx8 rad_cos_12(fx8 rad, u32 th)
Calculate the cosine of an angle and scale a fixed-point value by it.
Definition submath.cpp:1044