You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

141 lines
2.5KB

  1. #pragma once
  2. #include <stdint.h>
  3. #include <math.h>
  4. namespace rack {
  5. ////////////////////
  6. // Math
  7. ////////////////////
  8. inline float clampf(float x, float min, float max) {
  9. return fmaxf(min, fminf(max, x));
  10. }
  11. inline float mapf(float x, float xMin, float xMax, float yMin, float yMax) {
  12. return yMin + (x - xMin) / (xMax - xMin) * (yMax - yMin);
  13. }
  14. inline float crossf(float a, float b, float frac) {
  15. return (1.0 - frac) * a + frac * b;
  16. }
  17. inline int mini(int a, int b) {
  18. return a < b ? a : b;
  19. }
  20. inline int maxi(int a, int b) {
  21. return a > b ? a : b;
  22. }
  23. // Euclidean modulus, always returns 0 <= mod < base for positive base
  24. // Assumes this architecture's division is non-Euclidean
  25. inline int eucMod(int a, int base) {
  26. int mod = a % base;
  27. return mod < 0 ? mod + base : mod;
  28. }
  29. inline float getf(const float *p, float v = 0.0) {
  30. return p ? *p : v;
  31. }
  32. inline void setf(float *p, float v) {
  33. if (p)
  34. *p = v;
  35. }
  36. // Linearly interpolate an array `p` with index `x`
  37. inline float interpf(float *p, float x) {
  38. int i = x;
  39. x -= i;
  40. return crossf(p[i], p[i+1], x);
  41. }
  42. ////////////////////
  43. // RNG
  44. ////////////////////
  45. uint64_t randomi64(void);
  46. // Return a uniform random number on [0.0, 1.0)
  47. inline float randomf(void) {
  48. return (float)randomi64() / UINT64_MAX;
  49. }
  50. ////////////////////
  51. // 2D float vector
  52. ////////////////////
  53. struct Vec {
  54. float x, y;
  55. Vec() : x(0.0), y(0.0) {}
  56. Vec(float x, float y) : x(x), y(y) {}
  57. Vec neg() {
  58. return Vec(-x, -y);
  59. }
  60. Vec plus(Vec b) {
  61. return Vec(x + b.x, y + b.y);
  62. }
  63. Vec minus(Vec b) {
  64. return Vec(x - b.x, y - b.y);
  65. }
  66. Vec mult(float s) {
  67. return Vec(x * s, y * s);
  68. }
  69. Vec div(float s) {
  70. return Vec(x / s, y / s);
  71. }
  72. float dot(Vec b) {
  73. return x * b.x + y * b.y;
  74. }
  75. float norm() {
  76. return hypotf(x, y);
  77. }
  78. Vec min(Vec b) {
  79. return Vec(fminf(x, b.x), fminf(y, b.y));
  80. }
  81. Vec max(Vec b) {
  82. return Vec(fmaxf(x, b.x), fmaxf(y, b.y));
  83. }
  84. Vec round() {
  85. return Vec(roundf(x), roundf(y));
  86. }
  87. };
  88. struct Rect {
  89. Vec pos;
  90. Vec size;
  91. Rect() {}
  92. Rect(Vec pos, Vec size) : pos(pos), size(size) {}
  93. bool contains(Vec v) {
  94. return pos.x <= v.x && v.x < pos.x + size.x
  95. && pos.y <= v.y && v.y < pos.y + size.y;
  96. }
  97. bool intersects(Rect r) {
  98. return (pos.x + size.x > r.pos.x && r.pos.x + r.size.x > pos.x)
  99. && (pos.y + size.y > r.pos.y && r.pos.y + r.size.y > pos.y);
  100. }
  101. Vec getCenter() {
  102. return pos.plus(size.mult(0.5));
  103. }
  104. Vec getTopRight() {
  105. return pos.plus(Vec(size.x, 0.0));
  106. }
  107. Vec getBottomLeft() {
  108. return pos.plus(Vec(0.0, size.y));
  109. }
  110. Vec getBottomRight() {
  111. return pos.plus(size);
  112. }
  113. };
  114. } // namespace rack