Pico Headers
Loading...
Searching...
No Matches
pico_math.h
Go to the documentation of this file.
1
80#ifndef PICO_MATH_H
81#define PICO_MATH_H
82
83#include <float.h> // FLT_MIN/MAX, DBL_MIN/MAX
84#include <math.h> // sqrt(f), cos(f), sin(f), atan2(f)...
85#include <stdbool.h> // bool, true, false
86#include <stdint.h> // uint32_t
87
88#ifdef __cplusplus
89extern "C" {
90#endif
91
92// Common
93
94#if defined(_MSC_VER)
95 #define PM_INLINE __forceinline
96#elif defined(__GNUC__) || defined(__clang__)
97 #define PM_INLINE static inline __attribute((always_inline))
98#else
99 #define PM_INLINE
100#endif
101
102/*==============================================================================
103 * Types, constants, and function aliases
104 *============================================================================*/
105
106#ifdef PICO_MATH_DOUBLE
108 typedef double pfloat;
109
110 #define PM_EPSILON 1e-7
111
112 #define PM_PI 3.14159265358979323846264338327950288
113 #define PM_PI2 (2.0 * PM_PI)
114 #define PM_E 2.71828182845904523536028747135266250
115
116 #define PM_FLOAT_MIN DBL_MIN
117 #define PM_FLOAT_MAX DBL_MAX
118
119 #define pf_sqrt sqrt
120 #define pf_cos cos
121 #define pf_sin sin
122 #define pf_acos acos
123 #define pf_asin asin
124 #define pf_atan2 atan2
125 #define pf_abs fabs
126 #define pf_fmod fmod
127 #define pf_exp exp
128 #define pf_pow pow
129 #define pf_floor floor
130 #define pf_ceil ceil
131 #define pf_log2 log2
132 #define pf_max fmax
133 #define pf_min fmin
134
135#else
137 typedef float pfloat;
138
139 #define PM_EPSILON 1e-5f
140
141 #define PM_PI 3.14159265359f
142 #define PM_PI2 (2.0f * PM_PI)
143 #define PM_E 2.71828182845f
144
145 #define PM_FLOAT_MIN FLT_MIN
146 #define PM_FLOAT_MAX FLT_MAX
147
148 #define pf_sqrt sqrtf
149 #define pf_cos cosf
150 #define pf_sin sinf
151 #define pf_acos acosf
152 #define pf_asin asinf
153 #define pf_atan2 atan2f
154 #define pf_abs fabsf
155 #define pf_fmod fmodf
156 #define pf_exp expf
157 #define pf_pow powf
158 #define pf_floor floorf
159 #define pf_ceil ceilf
160 #define pf_log2 log2f
161 #define pf_max fmaxf
162 #define pf_min fminf
163#endif
164
165/*==============================================================================
166 * Data structures
167 *============================================================================*/
168
172typedef struct
173{
175} pv2;
176
180typedef struct
181{
182 pfloat t00, t10, t01, t11, tx, ty;
183} pt2;
184
188typedef struct
189{
190 pv2 min, max;
191} pb2;
192
193/*==============================================================================
194 * Scalar functions and macros
195 *============================================================================*/
196
201 {
202 return ((val < min) ? min : ((val > max) ? max : val));
203 }
204
214{
215 return ((0 == val) ? 0.0f : ((val > 0.0f) ? 1.0f : -1.0f));
216}
217
222{
223 return pf_abs(c1 - c2) < PM_EPSILON;
224}
225
234{
235 return a + (b - a) * alpha;
236}
237
245pfloat pf_lerp_angle(pfloat angle1, pfloat angle2, pfloat alpha);
246
251{
252 while (angle >= PM_PI2)
253 angle -= PM_PI2;
254
255 while (angle < 0.0f)
256 angle += PM_PI2;
257
258 return angle;
259}
260
261/*==============================================================================
262 * Vectors
263 *============================================================================*/
264
268#define pv2_make(x, y) ((const pv2){ x, y })
269
274{
275 return pf_equal(v1.x, v2.x) &&
276 pf_equal(v1.y, v2.y);
277}
278
285{
286 return pv2_make(v1.x + v2.x, v1.y + v2.y);
287}
288
295{
296 return pv2_make(v1.x - v2.x, v1.y - v2.y);
297}
298
305{
306 return pv2_make(v.x * c, v.y * c);
307}
308
313{
314 return v1.x * v2.x + v1.y * v2.y;
315}
316
321{
322 return pv2_dot(v, v);
323}
324
329{
330 return pf_sqrt(pv2_len2(v));
331}
332
339{
340 pfloat c = pv2_len(v);
341
342 if (c < PM_EPSILON)
343 return pv2_make(0.0f, 0.0f);
344 else
345 return pv2_scale(v, 1.0f / c);
346}
347
354{
355 return pv2_scale(v, -1.0f);
356}
357
364{
365 return pv2_make(-v.y, v.x);
366}
367
372{
373 pv2 perp = pv2_perp(v1);
374 return pv2_dot(perp, v2);
375}
376
381{
382 return pf_atan2(v.y, v.x);
383}
384
392{
393 pfloat d = pv2_dot(v1, v2) / pv2_dot(v2, v2);
394 return pv2_scale(v2, d);
395}
396
401{
402 pv2 v = pv2_sub(v1, v2);
403 return pv2_len(v);
404}
405
413{
414 pv2 out;
415 out.x = pf_lerp(v1.x, v2.x, alpha);
416 out.y = pf_lerp(v1.y, v2.y, alpha);
417 return out;
418}
419
423#define pv2_zero() (pv2_make(0.0f, 0.0f))
424
429{
430 return pv2_make(len * pf_cos(angle), len * pf_sin(angle));
431}
432
437{
438 return pv2_make(pf_min(v1.x, v2.x), pf_min(v1.y, v2.y));
439}
440
445{
446 return pv2_make(pf_max(v1.x, v2.x), pf_max(v1.y, v2.y));
447}
448
453{
454 return pv2_make(pf_floor(v.x), pf_floor(v.y));
455}
456
461{
462 return pv2_make(pf_ceil(v.x), pf_ceil(v.y));
463}
464
465/*==============================================================================
466 * 2D Affine Transforms
467 *============================================================================*/
468
472#define pt2_make(t00, t01, tx, t10, t11, ty) ((const pt2){ t00, t10, t01, t11, tx, ty })
473
478{
479 return pt2_make(1.0f, 0.0f, 0.0f,
480 0.0f, 1.0f, 0.0f);
481}
482
486bool pt2_equal(const pt2* t1, const pt2* t2);
487
493{
494 return pv2_make(t->tx, t->ty);
495}
496
503{
504 t->tx = pos.x;
505 t->ty = pos.y;
506}
507
512{
513 return pf_normalize_angle(pf_atan2(t->t10, t->t00));
514}
515
526void pt2_set_scale(pt2* t, pv2 scale);
527
538
542void pt2_set_angle(pt2* t, pfloat angle);
543
550{
551 pv2 out;
552 out.x = t->t00 * v.x + t->t01 * v.y + t->tx;
553 out.y = t->t10 * v.x + t->t11 * v.y + t->ty;
554 return out;
555}
556
561{
562 return t->t00 * t->t11 - t->t01 * t->t10;
563}
564
569pt2 pt2_inv(const pt2* t);
570
574pt2 pt2_mult(const pt2* t1, const pt2* t2);
575
579pt2 pt2_lerp(const pt2* t1, const pt2* t2, pfloat alpha);
580
586{
587 return pt2_make(scale.x, 0.0f, 0.0f,
588 0.0f, scale.y, 0.0f);
589}
590
596{
597 pfloat c = pf_cos(angle);
598 pfloat s = pf_sin(angle);
599
600 return pt2_make(c, -s, 0.0f,
601 s, c, 0.0f);
602}
603
609{
610 return pt2_make(1.0f, 0.0f, pos.x,
611 0.0f, 1.0f, pos.y);
612}
613
619PM_INLINE void pt2_scale(pt2* t, pv2 scale)
620{
621 pt2 scaling = pt2_scaling(scale);
622 *t = pt2_mult(&scaling, t);
623}
624
631{
632 pt2 rotation = pt2_rotation(angle);
633 *t = pt2_mult(&rotation, t);
634}
635
642{
643 pt2 translation = pt2_translation(pos);
644 *t = pt2_mult(&translation, t);
645}
646
647/*==============================================================================
648 * 2D Box (AABB)
649 *============================================================================*/
650
651#define pb2_make_minmax(min, max) ((const pb2){ min, max })
652
656#define pb2_make(x, y, w, h) ((const pb2){ { x, y }, { x + w, y + h } })
657
661#define pb2_zero() (pb2_make(0.0f, 0.0f, 0.0f, 0.0f))
662
667{
668 return b->min;
669}
670
675{
676 return pv2_sub(b->max, b->min);
677}
678
685{
686 pv2 size = pb2_get_size(b);
687 *b = pb2_make(pos.x, pos.y, size.x, size.y);
688}
689
696{
697 pv2 pos = pb2_get_pos(b);
698 *b = pb2_make(pos.x, pos.y, size.x, size.y);
699}
700
704bool pb2_equal(const pb2* b1, const pb2* b2);
705
709pb2 pb2_combine(const pb2* b1, const pb2* b2);
710
714pb2 pb2_overlap(const pb2* b1, const pb2* b2);
715
719PM_INLINE bool pb2_overlaps(const pb2* b1, const pb2* b2)
720{
721 return b1->max.x >= b2->min.x &&
722 b1->max.y >= b2->min.y &&
723 b2->max.x >= b1->min.x &&
724 b2->max.y >= b1->min.y;
725}
726
730PM_INLINE bool pb2_contains(const pb2* b1, const pb2* b2)
731{
732 return b2->min.x >= b1->min.x &&
733 b2->min.y >= b1->min.y &&
734 b2->max.x <= b1->max.x &&
735 b2->max.y <= b1->max.y;
736}
737
742{
743 pfloat x = v.x;
744 pfloat y = v.y;
745
746 return x > b->min.x &&
747 y > b->min.y &&
748 x < b->max.x &&
749 y < b->max.y;
750}
751
756{
757 return (b->max.x - b->min.x) * (b->max.y - b->min.y);
758}
759
764{
765 pv2 offset = pv2_scale(pv2_sub(b->max, b->min), 1.0f / 2.0f);
766 return pv2_add(offset, b->min);
767}
768
774pb2 pb2_enclosing(const pv2 verts[], int count);
775
780pb2 pb2_transform(const pt2* t, const pb2* b);
781
785typedef struct prng_t
786{
787 uint32_t s[4];
789
795void prng_seed(prng_t* rng, uint64_t seed);
796
801uint32_t prng_random(prng_t* rng);
802
807
808#ifdef __cplusplus
809}
810#endif
811
812#endif // PICO_MATH_H
813
814#ifdef PICO_MATH_IMPLEMENTATION
815
816pfloat pf_lerp_angle(pfloat angle1, pfloat angle2, pfloat alpha)
817{
818 const pv2 v1 = pv2_make(pf_cos(angle1), pf_sin(angle1));
819 const pv2 v2 = pv2_make(pf_cos(angle2), pf_sin(angle2));
820
821 // Calculuate cosine of angle between the two vectors
822 pfloat dot = pf_clamp(pv2_dot(v1, v2), -1.0f, 1.0f);
823
824 // LERP if the cosine is too close to its limits
825 if (pf_equal(dot, 1.0f) || pf_equal(dot, -1.0f))
826 {
827 pv2 tmp = pv2_lerp(v1, v2, alpha);
828 return pf_normalize_angle(pf_atan2(tmp.y, tmp.x));
829 }
830
831 // Calculate angle
832 pfloat angle = pf_acos(dot) * alpha;
833
834 // Gram-Schmidt(construct a new vector 'v0' that is orthogonal to 'v1')
835 pv2 v0 = pv2_sub(v2, pv2_scale(v1, dot));
836 v0 = pv2_normalize(v0);
837
838 // Calcuate vector in new coordinate system
839 pv2 tmp1 = pv2_scale(v1, pf_cos(angle));
840 pv2 tmp2 = pv2_scale(v0, pf_sin(angle));
841
842 pv2 tmp = pv2_add(tmp1, tmp2);
843
844 // Calculate new angle
845 return pf_normalize_angle(pf_atan2(tmp.y, tmp.x));
846}
847
848bool pt2_equal(const pt2* t1, const pt2* t2)
849{
850 return pf_equal(t1->t00, t2->t00) &&
851 pf_equal(t1->t10, t2->t10) &&
852 pf_equal(t1->t01, t2->t01) &&
853 pf_equal(t1->t11, t2->t11) &&
854 pf_equal(t1->tx, t2->tx) &&
855 pf_equal(t1->ty, t2->ty);
856}
857
858void pt2_set_scale(pt2* t, pv2 scale)
859{
860 pfloat angle = pt2_get_angle(t);
861
862 pfloat c = pf_cos(angle);
863 pfloat s = pf_sin(angle);
864
865 pfloat sx = scale.x;
866 pfloat sy = scale.y;
867
868 t->t00 = sx * c; t->t01 = sy * -s;
869 t->t10 = sx * s; t->t11 = sy * c;
870}
871
872pv2 pt2_get_scale(const pt2* t)
873{
874 pfloat angle = pt2_get_angle(t);
875 pfloat cos_sign = pf_sign(pf_cos(angle));
876
877 pv2 out;
878
879 if (0.0f == cos_sign) //TODO: pf_equal?
880 {
881 out.x = t->t10;
882 out.y = -t->t01;
883 return out;
884 }
885
886 pv2 v1 = pv2_make(t->t00, t->t10);
887 pv2 v2 = pv2_make(t->t01, t->t11);
888
889 out.x = pf_sign(t->t00) * cos_sign * pv2_len(v1);
890 out.y = pf_sign(t->t11) * cos_sign * pv2_len(v2);
891
892 return out;
893}
894
895void pt2_set_angle(pt2* t, pfloat angle)
896{
897 pfloat c = pf_cos(angle);
898 pfloat s = pf_sin(angle);
899
900 pv2 scale = pt2_get_scale(t);
901
902 pfloat sx = scale.x;
903 pfloat sy = scale.y;
904
905 t->t00 = sx * c; t->t01 = sy * -s;
906 t->t10 = sx * s; t->t11 = sy * c;
907}
908
909pt2 pt2_inv(const pt2* t)
910{
911 pfloat det = pt2_det(t);
912
913 if (0.0f == det) // Intentionally not using epsilon because determinants
914 { // can be really small and still be valid
915 return pt2_identity();
916 }
917
918 pfloat inv_det = 1.0f / det;
919
920 pt2 out;
921
922 out.t00 = t->t11 * inv_det; out.t01 = -t->t01 * inv_det;
923 out.t10 = -t->t10 * inv_det; out.t11 = t->t00 * inv_det;
924
925 out.tx = (t->t01 * t->ty - t->t11 * t->tx) * inv_det;
926 out.ty = (t->t10 * t->tx - t->t00 * t->ty) * inv_det;
927
928 return out;
929}
930
931pt2 pt2_mult(const pt2* t1, const pt2* t2)
932{
933 pt2 out;
934
935 out.t00 = t1->t00 * t2->t00 + t1->t01 * t2->t10;
936 out.t10 = t1->t10 * t2->t00 + t1->t11 * t2->t10;
937
938 out.t01 = t1->t00 * t2->t01 + t1->t01 * t2->t11;
939 out.t11 = t1->t10 * t2->t01 + t1->t11 * t2->t11;
940
941 out.tx = t1->t00 * t2->tx + t1->t01 * t2->ty + t1->tx;
942 out.ty = t1->t10 * t2->tx + t1->t11 * t2->ty + t1->ty;
943
944 return out;
945}
946
947pt2 pt2_lerp(const pt2* t1, const pt2* t2, pfloat alpha)
948{
949 pv2 scale1 = pt2_get_scale(t1);
950 pv2 scale2 = pt2_get_scale(t2);
951
952 pfloat angle1 = pt2_get_angle(t1);
953 pfloat angle2 = pt2_get_angle(t2);
954
955 pv2 pos1 = pt2_get_pos(t1);
956 pv2 pos2 = pt2_get_pos(t2);
957
958 pv2 scale = pv2_lerp(scale1, scale2, alpha);
959 pv2 pos = pv2_lerp(pos1, pos2, alpha);
960 pfloat angle = pf_lerp_angle(angle1, angle2, alpha);
961
962 pfloat c = pf_cos(angle);
963 pfloat s = pf_sin(angle);
964
965 pfloat sx = scale.x;
966 pfloat sy = scale.y;
967
968 pfloat tx = pos.x;
969 pfloat ty = pos.y;
970
971 pt2 out;
972
973 out.t00 = sx * c; out.t01 = sy * -s; out.tx = tx;
974 out.t10 = sx * s; out.t11 = sy * c; out.ty = ty;
975
976 return out;
977}
978
979bool pb2_equal(const pb2* b1, const pb2* b2)
980{
981 return pv2_equal(b1->min, b2->min) && pv2_equal(b1->max, b2->max);
982}
983
984pb2 pb2_combine(const pb2* b1, const pb2* b2)
985{
986 pv2 min = pv2_min(b1->min, b2->min);
987 pv2 max = pv2_max(b1->max, b2->max);
988 return pb2_make_minmax(min, max);
989}
990
991pb2 pb2_overlap(const pb2* b1, const pb2* b2)
992{
993 if (!pb2_overlaps(b1, b2))
994 return pb2_make(0.0f, 0.0f, 0.0f, 0.0f);
995
996 pv2 min = pv2_max(b1->min, b2->min);
997 pv2 max = pv2_min(b1->max, b2->max);
998 return pb2_make_minmax(min, max);
999}
1000
1001pb2 pb2_enclosing(const pv2 verts[], int count)
1002{
1003 if (0 == count)
1004 return pb2_make(0.0f, 0.0f, 0.0f, 0.0f);
1005
1006 pv2 min = verts[0];
1007 pv2 max = verts[0];
1008
1009 for (int i = 1; i < count; i++)
1010 {
1011 min = pv2_min(min, verts[i]);
1012 max = pv2_max(max, verts[i]);
1013 }
1014
1015 return pb2_make_minmax(min, max);
1016}
1017
1018pb2 pb2_transform(const pt2* t, const pb2* b)
1019{
1020 pv2 pos = pb2_get_pos(b);
1021 pv2 size = pb2_get_size(b);
1022
1023 pfloat w = size.x;
1024 pfloat h = size.y;
1025
1026 pv2 verts[4];
1027
1028 verts[0] = pos;
1029 verts[1] = pv2_make(pos.x, pos.y + h);
1030 verts[2] = pv2_make(pos.x + w, pos.y + h);
1031 verts[3] = pv2_make(pos.x + w, pos.y);
1032
1033 verts[0] = pt2_map(t, verts[0]);
1034 verts[1] = pt2_map(t, verts[1]);
1035 verts[2] = pt2_map(t, verts[2]);
1036 verts[3] = pt2_map(t, verts[3]);
1037
1038 return pb2_enclosing(verts, 4);
1039}
1040
1041/*
1042 * Implementation of the xoshiro128** algorithm
1043 * https://en.wikipedia.org/wiki/Xorshift
1044 */
1045
1046void prng_seed(prng_t* rng, uint64_t seed)
1047{
1048 for (int i = 0; i < 2; i++)
1049 {
1050 uint64_t result = (seed += 0x9E3779B97f4A7C15);
1051 result = (result ^ (result >> 30)) * 0xBF58476D1CE4E5B9;
1052 result = (result ^ (result >> 27)) * 0x94D049BB133111EB;
1053 result = result ^ (result >> 31);
1054
1055 int j = i * 2;
1056
1057 rng->s[j] = (uint32_t)result;
1058 rng->s[j + 1] = (uint32_t)(result >> 32);
1059 }
1060}
1061
1062static uint32_t rng_rol32(uint32_t x, int k)
1063{
1064 return (x << k) | (x >> (32 - k));
1065}
1066
1067uint32_t prng_random(prng_t* rng)
1068{
1069 uint32_t *s = rng->s;
1070 uint32_t const result = rng_rol32(s[1] * 5, 7) * 9;
1071 uint32_t const t = s[1] << 17;
1072
1073 s[2] ^= s[0];
1074 s[3] ^= s[1];
1075 s[1] ^= s[2];
1076 s[0] ^= s[3];
1077
1078 s[2] ^= t;
1079 s[3] = rng_rol32(s[3], 45);
1080
1081 return result;
1082}
1083
1085{
1086 return (pfloat)prng_random(rng) / (pfloat)UINT32_MAX;
1087}
1088
1089#endif // PICO_MATH_IMPLEMENTATION
1090
1091/*
1092 ----------------------------------------------------------------------------
1093 This software is available under two licenses (A) or (B). You may choose
1094 either one as you wish:
1095 ----------------------------------------------------------------------------
1096
1097 (A) The zlib License
1098
1099 Copyright (c) 2021 James McLean
1100
1101 This software is provided 'as-is', without any express or implied warranty.
1102 In no event will the authors be held liable for any damages arising from the
1103 use of this software.
1104
1105 Permission is granted to anyone to use this software for any purpose,
1106 including commercial applications, and to alter it and redistribute it
1107 freely, subject to the following restrictions:
1108
1109 1. The origin of this software must not be misrepresented; you must not
1110 claim that you wrote the original software. If you use this software in a
1111 product, an acknowledgment in the product documentation would be appreciated
1112 but is not required.
1113
1114 2. Altered source versions must be plainly marked as such, and must not be
1115 misrepresented as being the original software.
1116
1117 3. This notice may not be removed or altered from any source distribution.
1118
1119 ----------------------------------------------------------------------------
1120
1121 (B) Public Domain (www.unlicense.org)
1122
1123 This is free and unencumbered software released into the public domain.
1124
1125 Anyone is free to copy, modify, publish, use, compile, sell, or distribute
1126 this software, either in source code form or as a compiled binary, for any
1127 purpose, commercial or non-commercial, and by any means.
1128
1129 In jurisdictions that recognize copyright laws, the author or authors of
1130 this software dedicate any and all copyright interest in the software to the
1131 public domain. We make this dedication for the benefit of the public at
1132 large and to the detriment of our heirs and successors. We intend this
1133 dedication to be an overt act of relinquishment in perpetuity of all present
1134 and future rights to this software under copyright law.
1135
1136 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
1137 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
1138 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
1139 AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
1140 ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
1141 WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
1142*/
1143
PM_INLINE pfloat pv2_dot(pv2 v1, pv2 v2)
Dot product.
Definition pico_math.h:312
PM_INLINE void pt2_translate(pt2 *t, pv2 pos)
Applies a translation a transform.
Definition pico_math.h:641
#define pv2_make(x, y)
Constructs a vector.
Definition pico_math.h:268
#define pf_atan2
Definition pico_math.h:153
PM_INLINE pv2 pv2_min(pv2 v1, pv2 v2)
Computes the component-wise minimum of two vectors.
Definition pico_math.h:436
PM_INLINE pv2 pv2_proj(pv2 v1, pv2 v2)
Projects a vector onto another.
Definition pico_math.h:391
PM_INLINE pv2 pv2_polar(pfloat angle, pfloat len)
Contructs a vector in polar coordinates.
Definition pico_math.h:428
PM_INLINE pt2 pt2_translation(pv2 pos)
Constructs a translation transform.
Definition pico_math.h:608
PM_INLINE pfloat pf_clamp(pfloat val, pfloat min, pfloat max)
Clamps the value to the given range.
Definition pico_math.h:200
PM_INLINE pfloat pt2_det(const pt2 *t)
Returns the determinant of the transform.
Definition pico_math.h:560
PM_INLINE pv2 pv2_lerp(pv2 v1, pv2 v2, pfloat alpha)
Linearly interpolates between two vectors.
Definition pico_math.h:412
pfloat pf_lerp_angle(pfloat angle1, pfloat angle2, pfloat alpha)
Linearly interpolates between two angles.
PM_INLINE pv2 pv2_scale(pv2 v, pfloat c)
Scales a vector.
Definition pico_math.h:304
PM_INLINE pv2 pv2_normalize(pv2 v)
Normalizes a vector (sets its length to one)
Definition pico_math.h:338
PM_INLINE void pt2_scale(pt2 *t, pv2 scale)
Scales a transform.
Definition pico_math.h:619
#define pf_cos
Definition pico_math.h:149
uint32_t prng_random(prng_t *rng)
Generates a pseudo random number in [0, UINT32_MAX].
pv2 pt2_get_scale(const pt2 *t)
Gets the scale of the transform.
pb2 pb2_combine(const pb2 *b1, const pb2 *b2)
Computes the union of b1 and `b2.
PM_INLINE pv2 pb2_get_pos(const pb2 *b)
Returns the position of an AABB.
Definition pico_math.h:666
#define PM_INLINE
Definition pico_math.h:99
#define PM_PI2
Definition pico_math.h:142
void pt2_set_scale(pt2 *t, pv2 scale)
Sets the scale of the transform.
PM_INLINE bool pb2_contains(const pb2 *b1, const pb2 *b2)
Returns true if the first box is contained within the second.
Definition pico_math.h:730
pfloat pf_random(prng_t *rng)
Generates a psuedo random number in [0, 1].
#define pt2_make(t00, t01, tx, t10, t11, ty)
Constructs a 2D transform.
Definition pico_math.h:472
PM_INLINE bool pf_equal(pfloat c1, pfloat c2)
Returns true if the values are within epsilon of one another.
Definition pico_math.h:221
PM_INLINE pv2 pv2_sub(pv2 v1, pv2 v2)
Subtracts two vectors.
Definition pico_math.h:294
pt2 pt2_lerp(const pt2 *t1, const pt2 *t2, pfloat alpha)
Linearly interpolates two transforms.
PM_INLINE void pt2_rotate(pt2 *t, pfloat angle)
Applies a rotation to a transform.
Definition pico_math.h:630
float pfloat
A single precision floating point number.
Definition pico_math.h:137
PM_INLINE pfloat pf_lerp(pfloat a, pfloat b, pfloat alpha)
Linearly interpolates the two values.
Definition pico_math.h:233
#define pf_sin
Definition pico_math.h:150
PM_INLINE bool pv2_equal(pv2 v1, pv2 v2)
Returns true if the vectors are equal (within epsilon)
Definition pico_math.h:273
#define pb2_make_minmax(min, max)
Definition pico_math.h:651
pt2 pt2_mult(const pt2 *t1, const pt2 *t2)
Composes two transformations.
PM_INLINE pfloat pb2_area(const pb2 *b)
Returns the area of the box.
Definition pico_math.h:755
#define pf_sqrt
Definition pico_math.h:148
pb2 pb2_transform(const pt2 *t, const pb2 *b)
Computes the minimum AABB obtained by transforming the vertices of the specified AABB.
bool pb2_equal(const pb2 *b1, const pb2 *b2)
Returns true if the bounding boxes are equal (within epsilon)
#define pf_floor
Definition pico_math.h:158
PM_INLINE pv2 pb2_center(const pb2 *b)
Computes the center of the box.
Definition pico_math.h:763
#define pb2_make(x, y, w, h)
Constructs a 2D box (rectangle)
Definition pico_math.h:656
#define pf_acos
Definition pico_math.h:151
PM_INLINE void pb2_set_pos(pb2 *b, pv2 pos)
Sets the position of an AABB.
Definition pico_math.h:684
PM_INLINE pv2 pt2_get_pos(const pt2 *t)
Gets the translation components of the transform.
Definition pico_math.h:492
#define pf_abs
Definition pico_math.h:154
#define pf_ceil
Definition pico_math.h:159
PM_INLINE void pb2_set_size(pb2 *b, pv2 size)
Sets the dimensions of an AABB.
Definition pico_math.h:695
PM_INLINE pfloat pf_normalize_angle(pfloat angle)
Clamps the angle to be in [0, 2 * PI].
Definition pico_math.h:250
bool pt2_equal(const pt2 *t1, const pt2 *t2)
Returns true if the transforms are equal (within epsilon)
PM_INLINE pt2 pt2_identity(void)
Return the identity transform.
Definition pico_math.h:477
#define PM_EPSILON
Definition pico_math.h:139
PM_INLINE pfloat pv2_angle(pv2 v)
Returns the angle the vector with respect to the current basis.
Definition pico_math.h:380
PM_INLINE pv2 pv2_floor(pv2 v)
Computes the component-wise floor of the specified vector.
Definition pico_math.h:452
PM_INLINE pfloat pv2_len(pv2 v)
Returns the length of the vector.
Definition pico_math.h:328
#define pf_max
Definition pico_math.h:161
PM_INLINE void pt2_set_pos(pt2 *t, pv2 pos)
Sets the translation components of the transform.
Definition pico_math.h:502
PM_INLINE pfloat pv2_dist(pv2 v1, pv2 v2)
Returns the distance between the two vectors.
Definition pico_math.h:400
#define pf_min
Definition pico_math.h:162
PM_INLINE pt2 pt2_scaling(pv2 scale)
Constructs a scaling transform.
Definition pico_math.h:585
void prng_seed(prng_t *rng, uint64_t seed)
Initialize and seed the RNG.
PM_INLINE pfloat pf_sign(pfloat val)
Computes the sign of the number.
Definition pico_math.h:213
PM_INLINE pfloat pt2_get_angle(const pt2 *t)
Gets the angle of rotation of the transform.
Definition pico_math.h:511
PM_INLINE pt2 pt2_rotation(pfloat angle)
Constructs a rotation transform.
Definition pico_math.h:595
PM_INLINE pfloat pv2_cross(pv2 v1, pv2 v2)
A 2D analog of the 3D cross product.
Definition pico_math.h:371
pt2 pt2_inv(const pt2 *t)
Calculates the inverse of the transform.
PM_INLINE pfloat pv2_len2(pv2 v)
Returns the square of the length of the vector.
Definition pico_math.h:320
PM_INLINE pv2 pv2_perp(pv2 v)
Construct a vector that is perpendicular to the specified vector.
Definition pico_math.h:363
PM_INLINE pv2 pb2_get_size(const pb2 *b)
Returns the dimensions of an AABB.
Definition pico_math.h:674
PM_INLINE pv2 pv2_ceil(pv2 v)
Computes the component-wise ceiling of the specified vector.
Definition pico_math.h:460
pb2 pb2_overlap(const pb2 *b1, const pb2 *b2)
Computes the intersection of b1 and b2
PM_INLINE pv2 pv2_add(pv2 v1, pv2 v2)
Adds two vectors.
Definition pico_math.h:284
pb2 pb2_enclosing(const pv2 verts[], int count)
Computes the minimum box containing all of the vertices.
PM_INLINE bool pb2_contains_point(const pb2 *b, pv2 v)
Returns true if the box contains the point v
Definition pico_math.h:741
PM_INLINE bool pb2_overlaps(const pb2 *b1, const pb2 *b2)
Return true if the two bounding boxes intersect.
Definition pico_math.h:719
PM_INLINE pv2 pv2_reflect(pv2 v)
Negates a vector (scales it by -1.0)
Definition pico_math.h:353
PM_INLINE pv2 pv2_max(pv2 v1, pv2 v2)
Computes the component-wise maximum of two vectors.
Definition pico_math.h:444
void pt2_set_angle(pt2 *t, pfloat angle)
Sets the angle of the transform.
PM_INLINE pv2 pt2_map(const pt2 *t, pv2 v)
Transforms a vector.
Definition pico_math.h:549
A 2D axis-aligned-bounding-box (AABB)
Definition pico_math.h:189
pv2 min
Definition pico_math.h:190
pv2 max
Definition pico_math.h:190
The pseudo random number generator (RNG) state.
Definition pico_math.h:786
uint32_t s[4]
Definition pico_math.h:787
A 2D transform.
Definition pico_math.h:181
pfloat t01
Definition pico_math.h:182
pfloat t11
Definition pico_math.h:182
pfloat tx
Definition pico_math.h:182
pfloat t00
Definition pico_math.h:182
pfloat ty
Definition pico_math.h:182
pfloat t10
Definition pico_math.h:182
A 2D vector.
Definition pico_math.h:173
pfloat y
Definition pico_math.h:174
pfloat x
Definition pico_math.h:174