v1.1.0
 All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator Modules Pages
math.h
1 /* -*- mode: C; c-basic-offset: 4; intent-tabs-mode: nil -*-
2  *
3  * Sifteo SDK
4  *
5  * Copyright <c> 2012 Sifteo, Inc.
6  *
7  * Permission is hereby granted, free of charge, to any person obtaining a copy
8  * of this software and associated documentation files (the "Software"), to deal
9  * in the Software without restriction, including without limitation the rights
10  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11  * copies of the Software, and to permit persons to whom the Software is
12  * furnished to do so, subject to the following conditions:
13  *
14  * The above copyright notice and this permission notice shall be included in
15  * all copies or substantial portions of the Software.
16  *
17  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
23  * THE SOFTWARE.
24  */
25 
26 #pragma once
27 #ifdef NOT_USERSPACE
28 # error This is a userspace-only header, not allowed by the current build.
29 #endif
30 
31 #include <sifteo/abi.h>
32 #include <sifteo/macros.h>
33 
34 namespace Sifteo {
35 
44 /*
45  * Common mathematical constants
46  */
47 
48 #define M_E 2.71828182845904523536028747135266250
49 #define M_LOG2E 1.44269504088896340735992468100189214
50 #define M_LOG10E 0.434294481903251827651128918916605082
51 #define M_LN2 0.693147180559945309417232121458176568
52 #define M_LN10 2.30258509299404568401799145468436421
53 #define M_PI 3.14159265358979323846264338327950288
54 #define M_TAU 6.2831853071795862
55 #define M_PI_2 1.57079632679489661923132169163975144
56 #define M_PI_4 0.785398163397448309615660845819875721
57 #define M_1_PI 0.318309886183790671537767526745028724
58 #define M_2_PI 0.636619772367581343075535053490057448
59 #define M_2_SQRTPI 1.12837916709551257389615890312154517
60 #define M_SQRT2 1.41421356237309504880168872420969808
61 #define M_SQRT1_2 0.707106781186547524400844362104849039
62 #define MAXFLOAT ((float)3.40282346638528860e+38)
63 #define NAN __builtin_nanf("0x7fc00000")
64 
65 
72 template <typename T> inline T clamp(const T& value, const T& low, const T& high)
73 {
74  if (value < low) {
75  return low;
76  }
77  if (value > high) {
78  return high;
79  }
80  return value;
81 }
82 
90 template <typename T> inline T abs(const T& value)
91 {
92  if (value < 0) {
93  return -value;
94  }
95  return value;
96 }
97 
106 template <typename T> inline T lslc(const T& value, int bits)
107 {
108  if (bits < 0)
109  return value;
110  if (bits >= sizeof(T) * 8)
111  return 0;
112  return value << (unsigned)bits;
113 }
114 
122 template <typename T> inline T lsrc(const T& value, int bits)
123 {
124  if (bits < 0)
125  return value;
126  if (bits >= sizeof(T) * 8)
127  return 0;
128  return value >> (unsigned)bits;
129 }
130 
139 template <typename T> inline T bitRange(int begin, int end)
140 {
141  return lslc((T)-1, begin) & ~lslc((T)-1, end);
142 }
143 
154 inline unsigned clz(uint32_t word)
155 {
156  return __builtin_clz(word);
157 }
158 
169 inline unsigned ffs(uint32_t word)
170 {
171  // Reference: http://en.wikipedia.org/wiki/Find_first_set#Properties_and_relations
172  return 32 - __builtin_clz(word & -word);
173 }
174 
176 float inline fmod(float a, float b)
177 {
178  uint32_t r = _SYS_fmodf(reinterpret_cast<uint32_t&>(a), reinterpret_cast<uint32_t&>(b));
179  return reinterpret_cast<float&>(r);
180 }
181 
183 double inline fmod(double a, double b)
184 {
185  uint64_t ia = reinterpret_cast<uint64_t&>(a);
186  uint64_t ib = reinterpret_cast<uint64_t&>(b);
187  uint64_t r = _SYS_fmod(ia, ia >> 32, ib, ib >> 32);
188  return reinterpret_cast<double&>(r);
189 }
190 
192 float inline pow(float a, float b)
193 {
194  uint32_t r = _SYS_powf(reinterpret_cast<uint32_t&>(a), reinterpret_cast<uint32_t&>(b));
195  return reinterpret_cast<float&>(r);
196 }
197 
199 double inline pow(double a, double b)
200 {
201  uint64_t ia = reinterpret_cast<uint64_t&>(a);
202  uint64_t ib = reinterpret_cast<uint64_t&>(b);
203  uint64_t r = _SYS_pow(ia, ia >> 32, ib, ib >> 32);
204  return reinterpret_cast<double&>(r);
205 }
206 
208 unsigned inline umod(int a, int b)
209 {
210  int r = a % b;
211  if (r < 0)
212  r += b;
213  return r;
214 }
215 
217 template <typename T> inline T ceildiv(T numerator, T denominator) {
218  return (numerator + (denominator - 1)) / denominator;
219 }
220 
225 template <typename T> inline T roundup(T numerator, T denominator) {
226  return ceildiv(numerator, denominator) * denominator;
227 }
228 
230 float inline log(float a)
231 {
232  uint32_t r = _SYS_logf(reinterpret_cast<uint32_t&>(a));
233  return reinterpret_cast<float&>(r);
234 }
235 
237 double inline log(double a)
238 {
239  uint64_t ia = reinterpret_cast<uint64_t&>(a);
240  uint64_t r = _SYS_logd(ia, ia >> 32);
241  return reinterpret_cast<double&>(r);
242 }
243 
245 float inline sqrt(float a)
246 {
247  uint32_t r = _SYS_sqrtf(reinterpret_cast<uint32_t&>(a));
248  return reinterpret_cast<float&>(r);
249 }
250 
252 double inline sqrt(double a)
253 {
254  uint64_t ia = reinterpret_cast<uint64_t&>(a);
255  uint64_t r = _SYS_sqrt(ia, ia >> 32);
256  return reinterpret_cast<double&>(r);
257 }
258 
265 float inline sin(float x)
266 {
267  uint32_t r = _SYS_sinf(reinterpret_cast<uint32_t&>(x));
268  return reinterpret_cast<float&>(r);
269 }
270 
277 float inline cos(float x)
278 {
279  uint32_t r = _SYS_cosf(reinterpret_cast<uint32_t&>(x));
280  return reinterpret_cast<float&>(r);
281 }
282 
284 float inline tan(float x)
285 {
286  uint32_t r = _SYS_tanf(reinterpret_cast<uint32_t&>(x));
287  return reinterpret_cast<float&>(r);
288 }
289 
291 float inline atan(float x)
292 {
293  uint32_t r = _SYS_atanf(reinterpret_cast<uint32_t&>(x));
294  return reinterpret_cast<float&>(r);
295 }
296 
303 float inline atan2(float a, float b)
304 {
305  uint32_t r = _SYS_atan2f(reinterpret_cast<uint32_t&>(a), reinterpret_cast<uint32_t&>(b));
306  return reinterpret_cast<float&>(r);
307 }
308 
316 void inline sincos(float x, float *s, float *c)
317 {
318  _SYS_sincosf(reinterpret_cast<uint32_t&>(x), s, c);
319 }
320 
328 float inline tsin(float x)
329 {
330  uint32_t r = _SYS_tsinf(reinterpret_cast<uint32_t&>(x));
331  return reinterpret_cast<float&>(r);
332 }
333 
341 float inline tcos(float x)
342 {
343  uint32_t r = _SYS_tcosf(reinterpret_cast<uint32_t&>(x));
344  return reinterpret_cast<float&>(r);
345 }
346 
361 int inline tsini(int x)
362 {
363  return _SYS_tsini(x);
364 }
365 
381 int inline tcosi(int x)
382 {
383  return _SYS_tcosi(x);
384 }
385 
395 bool inline isunordered(float a, float b = 0.f)
396 {
397  return __builtin_isunordered(a, b);
398 }
399 
409 bool inline isunordered(double a, double b = 0.f)
410 {
411  return __builtin_isunordered(a, b);
412 }
413 
426 template <typename T> inline long ceil(const T value)
427 {
428  long result = value;
429  if (result >= 0 && result < value) {
430  return result+1;
431  }
432  return result;
433 }
434 
447 template <typename T> inline long floor(const T value)
448 {
449  long result = value;
450  if (result <= 0 && result > value) {
451  return result - 1;
452  }
453  return result;
454 }
455 
469 template <typename T> inline long round(const T value)
470 {
471  return floor(value + 0.5);
472 }
473 
478 template <typename T> inline bool almostEqual(const T a, const T b, const T epsilon)
479 {
480  return abs(a-b) < epsilon;
481 }
482 
483 
488 template <typename T> struct Vector2 {
489  T x;
490  T y;
491 
495  void set(T _x, T _y) {
496  x = _x;
497  y = _y;
498  }
499 
503  void setPolar(float angle, float magnitude) {
504  float s, c;
505  sincos(angle, &s, &c);
506  x = c * magnitude;
507  y = s * magnitude;
508  }
509 
513  Vector2<T> rotate(float angle) const {
514  float s, c;
515  sincos(angle, &s, &c);
516  Vector2<T> result = { x*c - y*s, x*s + y*c };
517  return result;
518  }
519 
528  Vector2<T> rotateI(int angle) const {
529  Vector2<T> a1 = { -y, x };
530  Vector2<T> a2 = { -x, -y };
531  Vector2<T> a3 = { y, -x };
532  switch (angle) {
533  default: ASSERT(0);
534  case 0: return *this;
535  case 1: return a1;
536  case 2: return a2;
537  case 3: return a3;
538  }
539  }
540 
549  static Vector2<T> unit(int side) {
550  Vector2<T> a0 = { 0, -1 };
551  Vector2<T> a1 = { -1, 0 };
552  Vector2<T> a2 = { 0, 1 };
553  Vector2<T> a3 = { 1, 0 };
554  switch(side) {
555  default: ASSERT(0);
556  case 0: return a0;
557  case 1: return a1;
558  case 2: return a2;
559  case 3: return a3;
560  }
561  }
562 
568  T len2() const {
569  return ( x * x + y * y );
570  }
571 
575  T len() const {
576  return sqrt(len2());
577  }
578 
582  T lenManhattan() const {
583  return abs(x) + abs(y);
584  }
585 
592  return *this / len();
593  }
594 
598  Vector2<int> round() const {
599  Vector2<int> result = { x + 0.5f, y + 0.5f };
600  return result;
601  }
602 
607  template <typename R> Vector2<R> cast() const {
608  Vector2<R> result = { x, y };
609  return result;
610  }
611 
619  Vector2<T> result = { x*u.x - y*u.y, x*u.y + y*u.x };
620  return result;
621  }
622 
624  Vector2<int> toInt() const { return cast<int>(); }
626  Vector2<float> toFloat() const { return cast<float>(); }
628  Vector2<double> toDouble() const { return cast<double>(); }
629 
630  // Implicit casts
631  operator Vector2<int> () const { return cast<int>(); }
632  operator Vector2<unsigned> () const { return cast<unsigned>(); }
633  operator Vector2<short> () const { return cast<short>(); }
634  operator Vector2<unsigned short> () const { return cast<unsigned short>(); }
635  operator Vector2<int8_t> () const { return cast<int8_t>(); }
636  operator Vector2<uint8_t> () const { return cast<uint8_t>(); }
637  operator Vector2<float> () const { return cast<float>(); }
638  operator Vector2<double> () const { return cast<double>(); }
639 };
640 
649 
658 template <typename T> inline Vector2<T> vec(T x, T y) {
659  Vector2<T> result = { x, y };
660  return result;
661 }
662 
664 template <typename T> inline T dot(Vector2<T> u, Vector2<T> v) {
665  return u.x * v.x + u.y * v.y;
666 }
667 
669 template <typename T> inline Vector2<T> polar(T angle, T magnitude) {
670  Vector2<T> result;
671  result.setPolar(angle, magnitude);
672  return result;
673 }
674 
675 // Vector operations
676 template <typename T> inline Vector2<T> operator-(Vector2<T> u) { return vec<T>(-u.x, -u.y); }
677 template <typename T> inline Vector2<T> operator+=(Vector2<T> &u, Vector2<T> v) { return vec<T>(u.x+=v.x, u.y+=v.y); }
678 template <typename T> inline Vector2<T> operator-=(Vector2<T> &u, Vector2<T> v) { return vec<T>(u.x-=v.x, u.y-=v.y); }
679 template <typename T> inline Vector2<T> operator+(Vector2<T> u, Vector2<T> v) { return vec<T>(u.x+v.x, u.y+v.y); }
680 template <typename T> inline Vector2<T> operator-(Vector2<T> u, Vector2<T> v) { return vec<T>(u.x-v.x, u.y-v.y); }
681 template <typename T> inline Vector2<T> operator*(Vector2<T> u, Vector2<T> v) { return vec<T>(u.x*v.x, u.y*v.y); }
682 template <typename T> inline bool operator==(Vector2<T> u, Vector2<T> v) { return u.x == v.x && u.y == v.y; }
683 template <typename T> inline bool operator!=(Vector2<T> u, Vector2<T> v) { return u.x != v.x || u.y != v.y; }
684 
685 // Scalar int promotion
686 template <typename T> inline Int2 operator*(int k, Vector2<T> v) { return vec<int>(k*v.x, k*v.y); }
687 template <typename T> inline Int2 operator*(Vector2<T> v, int k) { return vec<int>(k*v.x, k*v.y); }
688 template <typename T> inline Int2 operator/(Vector2<T> v, int k) { return vec<int>(v.x/k, v.y/k); }
689 template <typename T> inline Int2 operator+=(Vector2<T> &u, int k) { return vec<int>(u.x+=k, u.y+=k); }
690 template <typename T> inline Int2 operator*=(Vector2<T> &u, int k) { return vec<int>(u.x*=k, u.y*=k); }
691 template <typename T> inline Int2 operator<<(Vector2<T> u, int shift) { return vec<int>(u.x<<shift, u.y<<shift); }
692 template <typename T> inline Int2 operator>>(Vector2<T> u, int shift) { return vec<int>(u.x>>shift, u.y>>shift); }
693 
694 // Scalar float promotion
695 template <typename T> inline Float2 operator*(float k, Vector2<T> v) { return vec<float>(k*v.x, k*v.y); }
696 template <typename T> inline Float2 operator*(Vector2<T> v, float k) { return vec<float>(k*v.x, k*v.y); }
697 template <typename T> inline Float2 operator/(Vector2<T> v, float k) { return vec<float>(v.x/k, v.y/k); }
698 template <typename T> inline Float2 operator+=(Vector2<T> &u, float k) { return vec<float>(u.x+=k, u.y+=k); }
699 template <typename T> inline Float2 operator*=(Vector2<T> &u, float k) { return vec<float>(u.x*=k, u.y*=k); }
700 
701 // Scalar double promotion
702 template <typename T> inline Double2 operator*(double k, Vector2<T> v) { return vec<double>(k*v.x, k*v.y); }
703 template <typename T> inline Double2 operator*(Vector2<T> v, double k) { return vec<double>(k*v.x, k*v.y); }
704 template <typename T> inline Double2 operator/(Vector2<T> v, double k) { return vec<double>(v.x/k, v.y/k); }
705 template <typename T> inline Double2 operator+=(Vector2<T> &u, double k) { return vec<double>(u.x+=k, u.y+=k); }
706 template <typename T> inline Double2 operator*=(Vector2<T> &u, double k) { return vec<double>(u.x*=k, u.y*=k); }
707 
708 // Vector int -> float promotion
709 inline Vector2<float> operator+=(Vector2<float> &u, Int2 v) { return vec(u.x+=v.x, u.y+=v.y); }
710 inline Vector2<float> operator-=(Vector2<float> &u, Int2 v) { return vec(u.x-=v.x, u.y-=v.y); }
711 inline Vector2<float> operator+(Vector2<float> u, Int2 v) { return vec(u.x+v.x, u.y+v.y); }
712 inline Vector2<float> operator-(Vector2<float> u, Int2 v) { return vec(u.x-v.x, u.y-v.y); }
713 inline Vector2<float> operator*(Vector2<float> u, Int2 v) { return vec(u.x*v.x, u.y*v.y); }
714 inline Vector2<float> operator+(Int2 u, Vector2<float> v) { return vec(u.x+v.x, u.y+v.y); }
715 inline Vector2<float> operator-(Int2 u, Vector2<float> v) { return vec(u.x-v.x, u.y-v.y); }
716 inline Vector2<float> operator*(Int2 u, Vector2<float> v) { return vec(u.x*v.x, u.y*v.y); }
717 
718 
723 template <typename T> struct Vector3 {
724  T x;
725  T y;
726  T z;
727 
729  void set(T _x, T _y, T _z) {
730  x = _x;
731  y = _y;
732  z = _z;
733  }
734 
735  Vector2<T> xy() const { return vec(x, y); }
736  Vector2<T> xz() const { return vec(x, z); }
737  Vector2<T> yx() const { return vec(y, x); }
738  Vector2<T> yz() const { return vec(y, z); }
739  Vector2<T> zx() const { return vec(z, x); }
740  Vector2<T> zy() const { return vec(z, y); }
741 
747  T len2() const {
748  return ( x * x + y * y + z * z );
749  }
750 
754  T len() const {
755  return sqrt(len2());
756  }
757 
761  T lenManhattan() const {
762  return abs(x) + abs(y) + abs(z);
763  }
764 
771  return *this / len();
772  }
773 
777  Vector3<int> round() const {
778  Vector3<int> result = { x + 0.5f, y + 0.5f, z + 0.5f };
779  return result;
780  }
781 
785  Vector3<T> zRotate(float angle) const {
786  float s, c;
787  sincos(angle, &s, &c);
788  Vector3<T> result = { x*c - y*s, x*s + y*c, z };
789  return result;
790  }
791 
800  Vector3<T> zRotateI(int angle) const {
801  Vector3<T> a1 = { -y, x, z };
802  Vector3<T> a2 = { -x, -y, z };
803  Vector3<T> a3 = { y, -x, z };
804  switch (angle) {
805  default: ASSERT(0);
806  case 0: return *this;
807  case 1: return a1;
808  case 2: return a2;
809  case 3: return a3;
810  }
811  }
812 
817  template <typename R> Vector3<R> cast() const {
818  Vector3<R> result = { x, y, z };
819  return result;
820  }
821 
823  Vector3<int> toInt() const { return cast<int>(); }
825  Vector3<float> toFloat() const { return cast<float>(); }
827  Vector3<double> toDouble() const { return cast<double>(); }
828 
829  // Implicit casts
830  operator Vector3<int> () const { return cast<int>(); }
831  operator Vector3<unsigned> () const { return cast<unsigned>(); }
832  operator Vector3<short> () const { return cast<short>(); }
833  operator Vector3<unsigned short> () const { return cast<unsigned short>(); }
834  operator Vector3<int8_t> () const { return cast<int8_t>(); }
835  operator Vector3<uint8_t> () const { return cast<uint8_t>(); }
836  operator Vector3<float> () const { return cast<float>(); }
837  operator Vector3<double> () const { return cast<double>(); }
838 };
839 
848 
857 template <typename T> inline Vector3<T> vec(T x, T y, T z) {
858  Vector3<T> result = { x, y, z };
859  return result;
860 }
861 
863 template <typename T> inline T dot(Vector3<T> u, Vector3<T> v) {
864  return u.x * v.x + u.y * v.y + u.z * v.z;
865 }
866 
868 template <typename T> inline T cross(T u, T v) {
869  return vec(u.y * v.z - u.z * v.y,
870  u.z * v.x - u.x * v.z,
871  u.x * v.y - u.y * v.x);
872 }
873 
874 // Vector operations
875 template <typename T> inline Vector3<T> operator-(Vector3<T> u) { return vec<T>(-u.x, -u.y, -u.z); }
876 template <typename T> inline Vector3<T> operator+=(Vector3<T> &u, Vector3<T> v) { return vec<T>(u.x+=v.x, u.y+=v.y, u.z+=v.z); }
877 template <typename T> inline Vector3<T> operator-=(Vector3<T> &u, Vector3<T> v) { return vec<T>(u.x-=v.x, u.y-=v.y, u.z-=v.z); }
878 template <typename T> inline Vector3<T> operator+(Vector3<T> u, Vector3<T> v) { return vec<T>(u.x+v.x, u.y+v.y, u.z+v.z); }
879 template <typename T> inline Vector3<T> operator-(Vector3<T> u, Vector3<T> v) { return vec<T>(u.x-v.x, u.y-v.y, u.z-v.z); }
880 template <typename T> inline Vector3<T> operator*(Vector3<T> u, Vector3<T> v) { return vec<T>(u.x*v.x, u.y*v.y, u.z*v.z); }
881 template <typename T> inline bool operator==(Vector3<T> u, Vector3<T> v) { return u.x == v.x && u.y == v.y && u.z == v.z; }
882 template <typename T> inline bool operator!=(Vector3<T> u, Vector3<T> v) { return u.x != v.x || u.y != v.y || u.z != v.z; }
883 
884 // Scalar int promotion
885 template <typename T> inline Int3 operator*(int k, Vector3<T> v) { return vec<int>(k*v.x, k*v.y, k*v.z); }
886 template <typename T> inline Int3 operator*(Vector3<T> v, int k) { return vec<int>(k*v.x, k*v.y, k*v.z); }
887 template <typename T> inline Int3 operator/(Vector3<T> v, int k) { return vec<int>(v.x/k, v.y/k, v.z/k); }
888 template <typename T> inline Int3 operator+=(Vector3<T> &u, int k) { return vec<int>(u.x+=k, u.y+=k, u.z+=k); }
889 template <typename T> inline Int3 operator*=(Vector3<T> &u, int k) { return vec<int>(u.x*=k, u.y*=k, u.z*=k); }
890 template <typename T> inline Int3 operator<<(Vector3<T> u, int shift) { return vec<int>(u.x<<shift, u.y<<shift, u.z<<shift); }
891 template <typename T> inline Int3 operator>>(Vector3<T> u, int shift) { return vec<int>(u.x>>shift, u.y>>shift, u.z>>shift); }
892 
893 // Scalar float promotion
894 template <typename T> inline Float3 operator*(float k, Vector3<T> v) { return vec<float>(k*v.x, k*v.y, k*v.z); }
895 template <typename T> inline Float3 operator*(Vector3<T> v, float k) { return vec<float>(k*v.x, k*v.y, k*v.z); }
896 template <typename T> inline Float3 operator/(Vector3<T> v, float k) { return vec<float>(v.x/k, v.y/k, v.z/k); }
897 template <typename T> inline Float3 operator+=(Vector3<T> &u, float k) { return vec<float>(u.x+=k, u.y+=k, u.z+=k); }
898 template <typename T> inline Float3 operator*=(Vector3<T> &u, float k) { return vec<float>(u.x*=k, u.y*=k, u.z*=k); }
899 
900 // Scalar double promotion
901 template <typename T> inline Double3 operator*(double k, Vector3<T> v) { return vec<double>(k*v.x, k*v.y, k*v.z); }
902 template <typename T> inline Double3 operator*(Vector3<T> v, double k) { return vec<double>(k*v.x, k*v.y, k*v.z); }
903 template <typename T> inline Double3 operator/(Vector3<T> v, double k) { return vec<double>(v.x/k, v.y/k, v.z/k); }
904 template <typename T> inline Double3 operator+=(Vector3<T> &u, double k) { return vec<double>(u.x+=k, u.y+=k, u.z+=k); }
905 template <typename T> inline Double3 operator*=(Vector3<T> &u, double k) { return vec<double>(u.x*=k, u.y*=k, u.z*=k); }
906 
907 // Vector int -> float promotion
908 inline Float3 operator+=(Float3 &u, Int3 v) { return vec(u.x+=v.x, u.y+=v.y, u.z+=v.z); }
909 inline Float3 operator-=(Float3 &u, Int3 v) { return vec(u.x-=v.x, u.y-=v.y, u.z-=v.z); }
910 inline Float3 operator+(Float3 u, Int3 v) { return vec(u.x+v.x, u.y+v.y, u.z+v.z); }
911 inline Float3 operator-(Float3 u, Int3 v) { return vec(u.x-v.x, u.y-v.y, u.z-v.z); }
912 inline Float3 operator*(Float3 u, Int3 v) { return vec(u.x*v.x, u.y*v.y, u.z*v.z); }
913 inline Float3 operator+(Int3 u, Float3 v) { return vec(u.x+v.x, u.y+v.y, u.z+v.z); }
914 inline Float3 operator-(Int3 u, Float3 v) { return vec(u.x-v.x, u.y-v.y, u.z-v.z); }
915 inline Float3 operator*(Int3 u, Float3 v) { return vec(u.x*v.x, u.y*v.y, u.z*v.z); }
916 
917 
927 struct Random {
928  _SYSPseudoRandomState state;
929 
931  Random() {
932  seed();
933  }
934 
936  Random(uint32_t s) {
937  seed(s);
938  }
939 
945  void seed(uint32_t s) {
946  _SYS_prng_init(&state, s);
947  }
948 
954  void seed() {
955  seed((uint32_t) _SYS_ticks_ns());
956  }
957 
959  uint32_t raw() {
960  return _SYS_prng_value(&state);
961  }
962 
964  float random() {
965  return raw() * (1.0f / 0xFFFFFFFF);
966  }
967 
969  float expovariate(float averageInterval) {
970  return -averageInterval * log(1.0f - random());
971  }
972 
981  bool chance(float probability) {
982  // Use 31 bits, to give us range to represent probability=1.
983  const uint32_t mask = 0x7FFFFFFF;
984  uint32_t threshold = probability * (mask + 1);
985  return (raw() & mask) < threshold;
986  }
987 
992  float uniform(float a, float b) {
993  // Order of operations here allows constant folding if the endpoints are constant
994  return a + raw() * ((b-a) / 0xFFFFFFFF);
995  }
996 
1001  template <typename T>
1002  T randint(T a, T b) {
1003  return T(a + _SYS_prng_valueBounded(&state, b - a));
1004  }
1005 
1010  template <typename T>
1011  T randrange(T a, T b) {
1012  return randint<T>(a, T(b - 1));
1013  }
1014 
1021  template <typename T>
1022  T randrange(T count) {
1023  return randrange<T>(T(0), count);
1024  }
1025 
1026 };
1027 
1028 
1043  float cx;
1044  float cy;
1045  float xx;
1046  float xy;
1047  float yx;
1048  float yy;
1049 
1052 
1054  AffineMatrix(float _xx, float _yx, float _cx,
1055  float _xy, float _yy, float _cy)
1056  : cx(_cx), cy(_cy), xx(_xx),
1057  xy(_xy), yx(_yx), yy(_yy) {}
1058 
1061  return AffineMatrix(1, 0, 0,
1062  0, 1, 0);
1063  }
1064 
1066  static AffineMatrix scaling(float s) {
1067  float inv_s = 1.0f / s;
1068  return AffineMatrix(inv_s, 0, 0,
1069  0, inv_s, 0);
1070  }
1071 
1073  static AffineMatrix translation(float x, float y) {
1074  return AffineMatrix(1, 0, x,
1075  0, 1, y);
1076  }
1077 
1079  static AffineMatrix translation(Float2 v) {
1080  return AffineMatrix(1, 0, v.x,
1081  0, 1, v.y);
1082  }
1083 
1085  static AffineMatrix rotation(float angle) {
1086  float s, c;
1087  sincos(angle, &s, &c);
1088  return AffineMatrix(c, -s, 0,
1089  s, c, 0);
1090  }
1091 
1093  void operator*= (const AffineMatrix &m) {
1094  AffineMatrix n;
1095 
1096  n.cx = xx*m.cx + yx*m.cy + cx;
1097  n.cy = xy*m.cx + yy*m.cy + cy;
1098  n.xx = xx*m.xx + yx*m.xy;
1099  n.xy = xy*m.xx + yy*m.xy;
1100  n.yx = xx*m.yx + yx*m.yy;
1101  n.yy = xy*m.yx + yy*m.yy;
1102 
1103  *this = n;
1104  }
1105 
1107  void translate(float x, float y) {
1108  *this *= translation(x, y);
1109  }
1110 
1112  void translate(Float2 v) {
1113  *this *= translation(v);
1114  }
1115 
1117  void rotate(float angle) {
1118  *this *= rotation(angle);
1119  }
1120 
1122  void scale(float s) {
1123  *this *= scaling(s);
1124  }
1125 };
1126 
1131 } // namespace Sifteo
static AffineMatrix scaling(float s)
Create a matrix which scales by a factor of 's'.
Definition: math.h:1066
void seed()
Re-seed this random number generator arbitrarily.
Definition: math.h:954
T randint(T a, T b)
Returns a uniformly distributed random integer in the range [a, b], including both end points...
Definition: math.h:1002
T lsrc(const T &value, int bits)
Logical shift right with clamping.
Definition: math.h:122
T x
Vector component X.
Definition: math.h:724
Vector2< T > zy() const
Extract a 2-vector with only the ZY components.
Definition: math.h:740
Vector3< unsigned > UInt3
Typedef for a 2-vector of unsigned ints.
Definition: math.h:841
static Vector2< T > unit(int side)
Create a unit vector corresponding to the given integer 'side'.
Definition: math.h:549
long round(const T value)
Rounds 'value' to the nearest whole value.
Definition: math.h:469
Vector2< T > zx() const
Extract a 2-vector with only the ZX components.
Definition: math.h:739
Vector3< int8_t > Byte3
Typedef for a 2-vector of bytes.
Definition: math.h:844
void rotate(float angle)
Compose this matrix with a rotation by 'angle' radians.
Definition: math.h:1117
float atan2(float a, float b)
Single-precision arc tangent function, of two variables.
Definition: math.h:303
Vector2< T > yx() const
Extract a 2-vector with only the YX components.
Definition: math.h:737
T z
Vector component Z.
Definition: math.h:726
Generalized two-element cartesian coordinate vector.
Definition: math.h:488
T randrange(T count)
The one-argument variant of randrange() always starts at zero, and returns an integer up to but not i...
Definition: math.h:1022
long ceil(const T value)
Returns the next integer value closer to positive infinity from 'value'.
Definition: math.h:426
Vector3< double > toDouble() const
Explicit cast to double.
Definition: math.h:827
void set(T _x, T _y)
Modify this vector's value in-place.
Definition: math.h:495
#define ASSERT(_x)
Runtime debug assertion.
Definition: macros.h:205
AffineMatrix(float _xx, float _yx, float _cx, float _xy, float _yy, float _cy)
Create a matrix from six scalar values.
Definition: math.h:1054
float cx
Matrix member cx, the constant offset for X.
Definition: math.h:1043
static AffineMatrix translation(float x, float y)
Create a matrix which translates by (x, y)
Definition: math.h:1073
Vector3< R > cast() const
Explicitly cast this vector to another vector type, using default C++ truncation or extension rules...
Definition: math.h:817
double log(double a)
Compute the natural log of a floating point number. Double-precision.
Definition: math.h:237
float cy
Matrix member cy, the constant offset for Y.
Definition: math.h:1044
bool isunordered(double a, double b=0.f)
Unordered comparison.
Definition: math.h:409
float tsin(float x)
Table-driven drop-in replacement for sin()
Definition: math.h:328
Vector2< int8_t > Byte2
Typedef for a 2-vector of bytes.
Definition: math.h:645
Vector2< T > xy() const
Extract a 2-vector with only the XY components.
Definition: math.h:735
Vector3< float > toFloat() const
Explicit cast to float.
Definition: math.h:825
T roundup(T numerator, T denominator)
Round 'numerator' up to the nearest multiple of 'denominator'. Only for integer types.
Definition: math.h:225
Vector2< double > toDouble() const
Explicit cast to double.
Definition: math.h:628
T lenManhattan() const
Calculate the manhattan (city block) distance of this vector.
Definition: math.h:761
void setPolar(float angle, float magnitude)
Set this vector to a new cartesian value, given a value in polar coordinates.
Definition: math.h:503
T randrange(T a, T b)
Returns a uniformly distributed random integer in the half-open interval [a, b), including the lower ...
Definition: math.h:1011
static AffineMatrix identity()
Create the identity matrix.
Definition: math.h:1060
Vector2< int > Int2
Typedef for a 2-vector of ints.
Definition: math.h:641
Vector2< float > toFloat() const
Explicit cast to float.
Definition: math.h:626
T len2() const
Calculate the scalar length (magnitude) of this vector, squared.
Definition: math.h:747
double fmod(double a, double b)
Compute the remainder (modulo) operation for two floating point numbers. Double-precision.
Definition: math.h:183
Vector2< float > Float2
Typedef for a 2-vector of floats.
Definition: math.h:647
bool chance(float probability)
Take a chance. Returns a boolean that has a 'probability' chance of being 'true'. ...
Definition: math.h:981
float yy
Matrix member yy, the vertical Y delta.
Definition: math.h:1048
T x
Vector component X.
Definition: math.h:489
Vector3< T > zRotate(float angle) const
Rotate the vector about the Z axis counterclockwise by 'angle' radians.
Definition: math.h:785
float atan(float x)
Single-precision arc tangent function, of one variable.
Definition: math.h:291
float expovariate(float averageInterval)
Returns a generated pseudorandom inverval for a poisson process (e.g. whack-a-mole timing)...
Definition: math.h:969
T abs(const T &value)
For any type, return the absolute value.
Definition: math.h:90
Vector2< T > rotateI(int angle) const
Rotate this vector about the origin counterclockwise by an integer multiple of 90 degrees...
Definition: math.h:528
Random()
Construct a new random number generator, using an arbitrary seed.
Definition: math.h:931
Vector3< T > normalize() const
Return a normalized version of this vector.
Definition: math.h:770
T ceildiv(T numerator, T denominator)
Ceiling division. Divide, rounding up instead of down.
Definition: math.h:217
float tcos(float x)
Table-driven drop-in replacement for cos()
Definition: math.h:341
bool almostEqual(const T a, const T b, const T epsilon)
Returns true when 'a' and 'b' are within 'epsilon' of each other.
Definition: math.h:478
T lenManhattan() const
Calculate the manhattan (city block) distance of this vector.
Definition: math.h:582
double sqrt(double a)
Compute the square root of a floating point number. Double-precision.
Definition: math.h:252
float xy
Matrix member xy, the horizontal Y delta.
Definition: math.h:1046
Vector3< short > Short3
Typedef for a 2-vector of shorts.
Definition: math.h:842
void translate(Float2 v)
Compose this matrix with a translation by vector 'v'.
Definition: math.h:1112
T len2() const
Calculate the scalar length (magnitude) of this vector, squared.
Definition: math.h:568
Vector2< unsigned short > UShort2
Typedef for a 2-vector of unsigned shorts.
Definition: math.h:644
float tan(float x)
Calculate the tangent of a specified angle, in radians. Single-precision.
Definition: math.h:284
void operator*=(const AffineMatrix &m)
Matrix multiplication.
Definition: math.h:1093
void scale(float s)
Compose this matrix with a scale by factor 's'.
Definition: math.h:1122
T len() const
Calculate the scalar length (magnitude) of this vector.
Definition: math.h:575
Vector2< short > Short2
Typedef for a 2-vector of shorts.
Definition: math.h:643
T y
Vector component Y.
Definition: math.h:725
AffineMatrix()
Create an uninitialized matrix.
Definition: math.h:1051
int tcosi(int x)
Integer cosine table lookup.
Definition: math.h:381
Vector3< unsigned short > UShort3
Typedef for a 2-vector of unsigned shorts.
Definition: math.h:843
long floor(const T value)
Returns the next integer value closer to negative infinity from 'value'.
Definition: math.h:447
An augmented 3x2 matrix, for doing 2D affine transforms.
Definition: math.h:1042
Random(uint32_t s)
Construct a new random number generator with a well-defined seed.
Definition: math.h:936
uint32_t raw()
Returns the next raw 32-bit pseudo-random number.
Definition: math.h:959
Vector2< uint8_t > UByte2
Typedef for a 2-vector of unsigned bytes.
Definition: math.h:646
Vector2< T > xz() const
Extract a 2-vector with only the XZ components.
Definition: math.h:736
unsigned ffs(uint32_t word)
Find first bit set in a 32-bit word.
Definition: math.h:169
Vector3< int > toInt() const
Explicit cast to int.
Definition: math.h:823
Vector2< T > cmul(Vector2< T > u) const
Complex multiplication.
Definition: math.h:618
T len() const
Calculate the scalar length (magnitude) of this vector.
Definition: math.h:754
T dot(Vector3< T > u, Vector3< T > v)
Vector dot-product.
Definition: math.h:863
Vector3< float > Float3
Typedef for a 2-vector of floats.
Definition: math.h:846
static AffineMatrix translation(Float2 v)
Create a matrix which translates by vector 'v'.
Definition: math.h:1079
unsigned clz(uint32_t word)
Count leading zeroes in a 32-bit word.
Definition: math.h:154
float sin(float x)
Calculate the sine of a specified angle, in radians. Single-precision.
Definition: math.h:265
Pseudo-random number generator.
Definition: math.h:927
Definition: array.h:34
void sincos(float x, float *s, float *c)
Simultaneously compute the sine and cosine of a specified angle, in radians.
Definition: math.h:316
Vector3< int > Int3
Typedef for a 2-vector of ints.
Definition: math.h:840
Vector3< T > vec(T x, T y, T z)
Create a Vector3, from a set of (x, y, z) coordinates.
Definition: math.h:857
Vector2< double > Double2
Typedef for a 2-vector of double-precision floats.
Definition: math.h:648
T y
Vector component Y.
Definition: math.h:490
Vector3< T > zRotateI(int angle) const
Rotate this vector about the Z axis counterclockwise by an integer multiple of 90 degrees...
Definition: math.h:800
unsigned umod(int a, int b)
Compute the unsigned remainder from dividing two signed integers.
Definition: math.h:208
Vector2< R > cast() const
Explicitly cast this vector to another vector type, using default C++ truncation or extension rules...
Definition: math.h:607
Generalized three-element cartesian coordinate vector.
Definition: math.h:723
T lslc(const T &value, int bits)
Logical shift left with clamping.
Definition: math.h:106
float random()
Returns a uniformly distributed floating point number between 0 and 1, inclusive. ...
Definition: math.h:964
Vector3< double > Double3
Typedef for a 2-vector of double-precision floats.
Definition: math.h:847
float yx
Matrix member yx, the vertical X delta.
Definition: math.h:1047
float cos(float x)
Calculate the cosine of a specified angle, in radians. Single-precision.
Definition: math.h:277
T bitRange(int begin, int end)
Return a value of type T which has bits set in the half-open interval [begin, end).
Definition: math.h:139
void seed(uint32_t s)
Re-seed this random number generator.
Definition: math.h:945
void set(T _x, T _y, T _z)
Modify this vector's value in-place.
Definition: math.h:729
Vector2< unsigned > UInt2
Typedef for a 2-vector of unsigned ints.
Definition: math.h:642
int tsini(int x)
Integer sine table lookup.
Definition: math.h:361
Vector3< int > round() const
Round a floating point vector to the nearest integer.
Definition: math.h:777
Vector2< int > toInt() const
Explicit cast to int.
Definition: math.h:624
T clamp(const T &value, const T &low, const T &high)
For any type, clamp a value to the extremes 'low' and 'high'.
Definition: math.h:72
double pow(double a, double b)
Compute 'x' raised to the power 'y'. Double-precision.
Definition: math.h:199
Vector3< uint8_t > UByte3
Typedef for a 2-vector of unsigned bytes.
Definition: math.h:845
Vector2< T > yz() const
Extract a 2-vector with only the YZ components.
Definition: math.h:738
Vector2< T > normalize() const
Return a normalized version of this vector.
Definition: math.h:591
T cross(T u, T v)
Vector cross-product.
Definition: math.h:868
Vector2< T > polar(T angle, T magnitude)
Convert polar to cartesian.
Definition: math.h:669
Vector2< int > round() const
Round a floating point vector to the nearest integer.
Definition: math.h:598
static AffineMatrix rotation(float angle)
Create a matrix which rotates by 'angle' radians.
Definition: math.h:1085
Vector2< T > rotate(float angle) const
Rotate this vector about the origin counterclockwise by 'angle' radians.
Definition: math.h:513
float uniform(float a, float b)
Returns a uniformly distributed floating point number in the range [a, b) or [a, b], depending on rounding.
Definition: math.h:992
void translate(float x, float y)
Compose this matrix with a translation by (x, y)
Definition: math.h:1107
float xx
Matrix member xx, the horizontal X delta.
Definition: math.h:1045