vec.h 8.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390
  1. /*
  2. James William Fletcher (github.com/mrbid)
  3. September 2021 - February 2023
  4. Portable floating-point Vec4 lib.
  5. */
  6. #ifndef VEC_H
  7. #define VEC_H
  8. #include <math.h>
  9. #include <string.h>
  10. #define PI 3.141592741f // PI
  11. #define x2PI 6.283185482f // PI * 2
  12. #define d2PI 1.570796371f // PI / 2
  13. #define DEGREE 57.29578018f // 1 Radian as Degrees
  14. #define RADIAN 0.01745329238f // PI / 180 (1 Degree as Radians)
  15. #define RAD2DEG DEGREE
  16. #define DEG2RAD RADIAN
  17. typedef struct{
  18. float x,y,z,w;
  19. } vec;
  20. static inline float randf(); // uniform [0 to 1]
  21. static inline float randfc(); // uniform [-1 to 1]
  22. float randfn(); // box-muller normal [bi-directional]
  23. static inline float fRandFloat(const float min, const float max);
  24. static inline int fRand(const float min, const float max);
  25. int vec_ftoi(float f); // float to integer quantise
  26. // normalising the result is optional / at the callers responsibility
  27. void vRuv(vec* v); // Random Unit Vector
  28. void vRuvN(vec* v); // Normal Random Unit Vector
  29. void vRuvBT(vec* v); // Brian Tung Random Unit Vector (on surface of unit sphere)
  30. void vRuvTA(vec* v); // T.Davison Trial & Error (inside unit sphere)
  31. void vRuvTD(vec* v); // T.Davison Random Unit Vector Sphere
  32. void vCross(vec* r, const vec v1, const vec v2);
  33. float vDot(const vec v1, const vec v2);
  34. float vSum(const vec v);
  35. float vSumAbs(const vec v);
  36. void vReflect(vec* r, const vec v, const vec n);
  37. int vEqualTol(const vec a, const vec b, const float tol);
  38. int vEqualInt(const vec a, const vec b);
  39. void vMin(vec* r, const vec v1, const vec v2);
  40. void vMax(vec* r, const vec v1, const vec v2);
  41. void vNorm(vec* v);
  42. float vDist(const vec v1, const vec v2);
  43. float vDistSq(const vec a, const vec b);
  44. float vDistMh(const vec a, const vec b); // manhattan
  45. float vDistLa(const vec a, const vec b); // longest axis
  46. float vMod(const vec v); // modulus
  47. float vMag(const vec v); // magnitude
  48. void vInv(vec* v); // invert
  49. void vCopy(vec* r, const vec v);
  50. void vDir(vec* r, const vec v1, const vec v2); // direction vector from v1 to v2
  51. void vRotX(vec* v, const float radians);
  52. void vRotY(vec* v, const float radians);
  53. void vRotZ(vec* v, const float radians);
  54. void vAdd(vec* r, const vec v1, const vec v2);
  55. void vSub(vec* r, const vec v1, const vec v2);
  56. void vDiv(vec* r, const vec numerator, const vec denominator);
  57. void vMul(vec* r, const vec v1, const vec v2);
  58. void vAddS(vec* r, const vec v1, const float v2);
  59. void vSubS(vec* r, const vec v1, const float v2);
  60. void vDivS(vec* r, const vec v1, const float v2);
  61. void vMulS(vec* r, const vec v1, const float v2);
  62. //
  63. int srandfq = 74235;
  64. static inline void srandf(const int seed){srandfq = seed;}
  65. static inline float randf()
  66. {
  67. // https://www.musicdsp.org/en/latest/Other/273-fast-float-random-numbers.html (moc.liamg@seir.kinimod)
  68. srandfq *= 16807;
  69. return (float)(srandfq & 0x7FFFFFFF) * 4.6566129e-010f;
  70. }
  71. static inline float randfc()
  72. {
  73. // https://www.musicdsp.org/en/latest/Other/273-fast-float-random-numbers.html (moc.liamg@seir.kinimod)
  74. srandfq *= 16807;
  75. return ((float)(srandfq)) * 4.6566129e-010f;
  76. }
  77. static inline float fRandFloat(const float min, const float max)
  78. {
  79. return min + randf() * (max-min);
  80. }
  81. static inline int fRand(const float min, const float max)
  82. {
  83. return (int)((min + randf() * (max-min))+0.5f);
  84. }
  85. float randfn()
  86. {
  87. float u = randfc();
  88. float v = randfc();
  89. float r = u * u + v * v;
  90. while(r == 0.f || r > 1.f)
  91. {
  92. u = randfc();
  93. v = randfc();
  94. r = u * u + v * v;
  95. }
  96. return u * sqrtf(-2.f * logf(r) / r);
  97. }
  98. void vRuv(vec* v)
  99. {
  100. v->x = randfc();
  101. v->y = randfc();
  102. v->z = randfc();
  103. }
  104. void vRuvN(vec* v)
  105. {
  106. v->x = randfn();
  107. v->y = randfn();
  108. v->z = randfn();
  109. }
  110. void vRuvBT(vec* v)
  111. {
  112. // https://math.stackexchange.com/a/1586185
  113. // or should I have called this vRuvLR()
  114. // https://mathworld.wolfram.com/SpherePointPicking.html
  115. const float y = acosf(randfc()) - d2PI;
  116. const float p = x2PI * randf();
  117. v->x = cosf(y) * cosf(p);
  118. v->y = cosf(y) * sinf(p);
  119. v->z = sinf(y);
  120. }
  121. void vRuvTA(vec* v)
  122. {
  123. // T.P.Davison@tees.ac.uk
  124. while(1)
  125. {
  126. v->x = randfc();
  127. v->y = randfc();
  128. v->z = randfc();
  129. const float len = vMag(*v);
  130. if(len <= 1.0f){return;}
  131. }
  132. }
  133. void vRuvTD(vec* v)
  134. {
  135. // T.P.Davison@tees.ac.uk
  136. v->x = sinf((randf() * x2PI) - PI);
  137. v->y = cosf((randf() * x2PI) - PI);
  138. v->z = randfc();
  139. }
  140. void vCross(vec* r, const vec v1, const vec v2)
  141. {
  142. r->x = (v1.y * v2.z) - (v2.y * v1.z);
  143. r->y = -((v1.x * v2.z) - (v2.x * v1.z));
  144. r->z = (v1.x * v2.y) - (v2.x * v1.y);
  145. }
  146. float vDot(const vec v1, const vec v2)
  147. {
  148. return (v1.x * v2.x) + (v1.y * v2.y) + (v1.z * v2.z);
  149. }
  150. float vSum(const vec v)
  151. {
  152. return v.x + v.y + v.z;
  153. }
  154. float vSumAbs(const vec v)
  155. {
  156. return fabs(v.x) + fabs(v.y) + fabs(v.z);
  157. }
  158. void vInv(vec* v)
  159. {
  160. v->x = -v->x;
  161. v->y = -v->y;
  162. v->z = -v->z;
  163. }
  164. void vNorm(vec* v)
  165. {
  166. const float len = 1.f/sqrtf(v->x*v->x + v->y*v->y + v->z*v->z);
  167. v->x *= len;
  168. v->y *= len;
  169. v->z *= len;
  170. }
  171. float vDist(const vec v1, const vec v2)
  172. {
  173. const float xm = (v1.x - v2.x);
  174. const float ym = (v1.y - v2.y);
  175. const float zm = (v1.z - v2.z);
  176. return sqrtf(xm*xm + ym*ym + zm*zm);
  177. }
  178. float vDistSq(const vec a, const vec b)
  179. {
  180. const float xm = (a.x - b.x);
  181. const float ym = (a.y - b.y);
  182. const float zm = (a.z - b.z);
  183. return xm*xm + ym*ym + zm*zm;
  184. }
  185. float vDistMh(const vec a, const vec b)
  186. {
  187. return (a.x - b.x) + (a.y - b.y) + (a.z - b.z);
  188. }
  189. float vDistLa(const vec v1, const vec v2)
  190. {
  191. const float xm = fabsf(v1.x - v2.x);
  192. const float ym = fabsf(v1.y - v2.y);
  193. const float zm = fabsf(v1.z - v2.z);
  194. float dist = xm;
  195. if(ym > dist)
  196. dist = ym;
  197. if(zm > dist)
  198. dist = zm;
  199. return dist;
  200. }
  201. void vReflect(vec* r, const vec v, const vec n)
  202. {
  203. const float angle = vDot(v, n);
  204. r->x = v.x - (2.f * n.x) * angle;
  205. r->y = v.y - (2.f * n.y) * angle;
  206. r->z = v.z - (2.f * n.z) * angle;
  207. }
  208. int vEqualTol(const vec a, const vec b, const float tol)
  209. {
  210. return a.x >= b.x - tol && a.x <= b.x + tol &&
  211. a.y >= b.y - tol && a.y <= b.y + tol &&
  212. a.z >= b.z - tol && a.z <= b.z + tol;
  213. }
  214. void vMin(vec* r, const vec v1, const vec v2)
  215. {
  216. if(v1.x < v2.x && v1.y < v2.y && v1.z < v2.z)
  217. {
  218. r->x = v1.x;
  219. r->y = v1.y;
  220. r->z = v1.z;
  221. }
  222. r->x = v2.x;
  223. r->y = v2.y;
  224. r->z = v2.z;
  225. }
  226. void vMax(vec* r, const vec v1, const vec v2)
  227. {
  228. if(v1.x > v2.x && v1.y > v2.y && v1.z > v2.z)
  229. {
  230. r->x = v1.x;
  231. r->y = v1.y;
  232. r->z = v1.z;
  233. }
  234. r->x = v2.x;
  235. r->y = v2.y;
  236. r->z = v2.z;
  237. }
  238. int vec_ftoi(float f)
  239. {
  240. if(f < 0.f)
  241. f -= 0.5f;
  242. else
  243. f += 0.5f;
  244. return (int)f;
  245. }
  246. int vEqualInt(const vec a, const vec b)
  247. {
  248. return vec_ftoi(a.x) == vec_ftoi(b.x) && vec_ftoi(a.y) == vec_ftoi(b.y) && vec_ftoi(a.z) == vec_ftoi(b.z);
  249. }
  250. float vMod(const vec v)
  251. {
  252. return sqrtf(v.x*v.x + v.y*v.y + v.z*v.z);
  253. }
  254. float vMag(const vec v)
  255. {
  256. return v.x*v.x + v.y*v.y + v.z*v.z;
  257. }
  258. void vCopy(vec* r, const vec v)
  259. {
  260. memcpy(r, &v, sizeof(vec));
  261. }
  262. void vDir(vec* r, const vec v1, const vec v2)
  263. {
  264. vSub(r, v2, v1);
  265. vNorm(r);
  266. }
  267. void vRotX(vec* v, const float radians)
  268. {
  269. v->y = v->y * cosf(radians) + v->z * sinf(radians);
  270. v->z = v->y * sinf(radians) - v->z * cosf(radians);
  271. }
  272. void vRotY(vec* v, const float radians)
  273. {
  274. v->x = v->z * sinf(radians) - v->x * cosf(radians);
  275. v->z = v->z * cosf(radians) + v->x * sinf(radians);
  276. }
  277. void vRotZ(vec* v, const float radians)
  278. {
  279. v->x = v->x * cosf(radians) + v->y * sinf(radians);
  280. v->y = v->x * sinf(radians) - v->y * cosf(radians);
  281. }
  282. void vAdd(vec* r, const vec v1, const vec v2)
  283. {
  284. r->x = v1.x + v2.x;
  285. r->y = v1.y + v2.y;
  286. r->z = v1.z + v2.z;
  287. }
  288. void vSub(vec* r, const vec v1, const vec v2)
  289. {
  290. r->x = v1.x - v2.x;
  291. r->y = v1.y - v2.y;
  292. r->z = v1.z - v2.z;
  293. }
  294. void vDiv(vec* r, const vec numerator, const vec denominator)
  295. {
  296. r->x = numerator.x / denominator.x;
  297. r->y = numerator.y / denominator.y;
  298. r->z = numerator.z / denominator.z;
  299. }
  300. void vMul(vec* r, const vec v1, const vec v2)
  301. {
  302. r->x = v1.x * v2.x;
  303. r->y = v1.y * v2.y;
  304. r->z = v1.z * v2.z;
  305. }
  306. void vAddS(vec* r, const vec v1, const float v2)
  307. {
  308. r->x = v1.x + v2;
  309. r->y = v1.y + v2;
  310. r->z = v1.z + v2;
  311. }
  312. void vSubS(vec* r, const vec v1, const float v2)
  313. {
  314. r->x = v1.x - v2;
  315. r->y = v1.y - v2;
  316. r->z = v1.z - v2;
  317. }
  318. void vDivS(vec* r, const vec v1, const float v2)
  319. {
  320. r->x = v1.x / v2;
  321. r->y = v1.y / v2;
  322. r->z = v1.z / v2;
  323. }
  324. void vMulS(vec* r, const vec v1, const float v2)
  325. {
  326. r->x = v1.x * v2;
  327. r->y = v1.y * v2;
  328. r->z = v1.z * v2;
  329. }
  330. #endif