Math.cpp 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354
  1. #include "tests/framework/Framework.h"
  2. #include "anki/Math.h"
  3. using namespace anki;
  4. /// Test the common perators between a vector and another vector
  5. template<typename Vec>
  6. void operatorsSame()
  7. {
  8. const U size = Vec::SIZE;
  9. using T = typename Vec::Scalar;
  10. Vec a, b;
  11. Array<T, size> add, sub, mul, div;
  12. for(U i = 0; i < size; i++)
  13. {
  14. T v0 = T(i * 10) / 2 + 1;
  15. T v1 = T(i * 1000) / 5.123 + 1;
  16. a[i] = v0;
  17. b[i] = v1;
  18. add[i] = v0 + v1;
  19. sub[i] = v0 - v1;
  20. mul[i] = v0 * v1;
  21. div[i] = v0 / v1;
  22. }
  23. Vec c = a + b;
  24. Vec d = a - b;
  25. Vec e = a * b;
  26. Vec f = a / b;
  27. for(U i = 0; i < size; i++)
  28. {
  29. ANKI_TEST_EXPECT_EQ(c[i], add[i]);
  30. ANKI_TEST_EXPECT_EQ(d[i], sub[i]);
  31. ANKI_TEST_EXPECT_EQ(e[i], mul[i]);
  32. ANKI_TEST_EXPECT_EQ(f[i], div[i]);
  33. }
  34. c = a;
  35. c += b;
  36. d = a;
  37. d -= b;
  38. e = a;
  39. e *= b;
  40. f = a;
  41. f /= b;
  42. for(U i = 0; i < size; i++)
  43. {
  44. ANKI_TEST_EXPECT_EQ(c[i], add[i]);
  45. ANKI_TEST_EXPECT_EQ(d[i], sub[i]);
  46. ANKI_TEST_EXPECT_EQ(e[i], mul[i]);
  47. ANKI_TEST_EXPECT_EQ(f[i], div[i]);
  48. }
  49. }
  50. /// Test the dot prods
  51. template<typename Vec>
  52. void dot()
  53. {
  54. const U size = Vec::SIZE;
  55. using T = typename Vec::Scalar;
  56. T res = 0;
  57. Vec vec;
  58. for(U i = 0; i < size; i++)
  59. {
  60. T x = i * 666 + 1;
  61. vec[i] = x;
  62. res += x * x;
  63. }
  64. ANKI_TEST_EXPECT_EQ(vec.dot(vec), res);
  65. }
  66. /// Test length and normalization
  67. template<typename Vec>
  68. void length()
  69. {
  70. using T = typename Vec::Scalar;
  71. U size = Vec::SIZE;
  72. Vec vec;
  73. T res = 0;
  74. for(U i = 0; i < size; i++)
  75. {
  76. T x = i * 666;
  77. vec[i] = x;
  78. res += x * x;
  79. }
  80. res = sqrt(res);
  81. ANKI_TEST_EXPECT_EQ(vec.getLength(), res);
  82. if(Vec::IS_INTEGER)
  83. {
  84. ANKI_TEST_EXPECT_EQ(vec.getNormalized(), vec / res);
  85. }
  86. else
  87. {
  88. auto a = vec / res;
  89. auto b = vec.getNormalized();
  90. for(U i = 0; i < size; i++)
  91. {
  92. ANKI_TEST_EXPECT_NEAR(a[i], b[i], 0.0001);
  93. }
  94. }
  95. }
  96. template<typename Vec>
  97. void comparision()
  98. {
  99. U size = Vec::SIZE;
  100. Vec a, a1, b;
  101. for(U i = 0; i < size; i++)
  102. {
  103. a[i] = i * 666;
  104. a1[i] = a[i];
  105. b[i] = a[i] + 1;
  106. }
  107. ANKI_TEST_EXPECT_EQ(a == a1, true);
  108. ANKI_TEST_EXPECT_EQ(a != a1, false);
  109. ANKI_TEST_EXPECT_EQ(a < a1, false);
  110. ANKI_TEST_EXPECT_EQ(a <= a1, true);
  111. ANKI_TEST_EXPECT_EQ(a > a1, false);
  112. ANKI_TEST_EXPECT_EQ(a >= a1, true);
  113. ANKI_TEST_EXPECT_EQ(a == b, false);
  114. ANKI_TEST_EXPECT_EQ(a != b, true);
  115. ANKI_TEST_EXPECT_EQ(a < b, true);
  116. ANKI_TEST_EXPECT_EQ(a <= b, true);
  117. ANKI_TEST_EXPECT_EQ(a > b, false);
  118. ANKI_TEST_EXPECT_EQ(a >= b, false);
  119. }
  120. /// Common vector tests
  121. template<typename Vec>
  122. void commonVecTests()
  123. {
  124. operatorsSame<Vec>();
  125. dot<Vec>();
  126. length<Vec>();
  127. comparision<Vec>();
  128. }
  129. ANKI_TEST(Math, Vec2)
  130. {
  131. commonVecTests<Vec2>();
  132. commonVecTests<IVec2>();
  133. commonVecTests<UVec2>();
  134. }
  135. ANKI_TEST(Math, Vec3)
  136. {
  137. commonVecTests<Vec3>();
  138. commonVecTests<IVec3>();
  139. commonVecTests<UVec3>();
  140. }
  141. ANKI_TEST(Math, Vec4)
  142. {
  143. commonVecTests<Vec4>();
  144. commonVecTests<IVec4>();
  145. commonVecTests<UVec4>();
  146. }
  147. /// Test the common operators between a matrices
  148. template<typename Mat>
  149. void matOperatorsSame()
  150. {
  151. const U size = Mat::SIZE;
  152. using T = typename Mat::Scalar;
  153. Mat a, b;
  154. Array<T, size> add, sub;
  155. for(U i = 0; i < size; i++)
  156. {
  157. T v0 = T(i * 10) / 2;
  158. T v1 = T(i * 1000) / 5.123;
  159. a[i] = v0;
  160. b[i] = v1;
  161. add[i] = v0 + v1;
  162. sub[i] = v0 - v1;
  163. }
  164. Mat c = a + b;
  165. Mat d = a - b;
  166. for(U i = 0; i < size; i++)
  167. {
  168. ANKI_TEST_EXPECT_EQ(c[i], add[i]);
  169. ANKI_TEST_EXPECT_EQ(d[i], sub[i]);
  170. }
  171. c = a;
  172. c += b;
  173. d = a;
  174. d -= b;
  175. for(U i = 0; i < size; i++)
  176. {
  177. ANKI_TEST_EXPECT_EQ(c[i], add[i]);
  178. ANKI_TEST_EXPECT_EQ(d[i], sub[i]);
  179. }
  180. }
  181. /// Get a filled matrix
  182. template<typename Mat>
  183. Mat getNonEmptyMat(typename Mat::Scalar offset = 0)
  184. {
  185. Mat out;
  186. for(U i = 0; i < Mat::SIZE; i++)
  187. {
  188. out[i] = i + offset;
  189. }
  190. return out;
  191. }
  192. /// Some getters setters
  193. template<typename Mat, typename RowVec, typename ColVec>
  194. void matSettersGetters()
  195. {
  196. using T = typename Mat::Scalar;
  197. Mat m(T(0));
  198. m.setRow(1, RowVec(1.0));
  199. ANKI_TEST_EXPECT_EQ(m.getRow(1), RowVec(1.0));
  200. m.setColumn(1, ColVec(2.0));
  201. m.setColumn(2, ColVec(3.0));
  202. ANKI_TEST_EXPECT_EQ(m.getColumn(1), ColVec(2.0));
  203. ANKI_TEST_EXPECT_EQ(m.getColumn(2), ColVec(3.0));
  204. ANKI_TEST_EXPECT_EQ(m.getYAxis(), m.getColumn(1));
  205. }
  206. /// Transpose
  207. template<typename Mat>
  208. void transpose()
  209. {
  210. Mat a = getNonEmptyMat<Mat>();
  211. Mat b = a.getTransposed();
  212. for(U j = 0; j < Mat::ROW_SIZE; j++)
  213. {
  214. for(U i = 0; i < Mat::COLUMN_SIZE; i++)
  215. {
  216. ANKI_TEST_EXPECT_EQ(a(j, i), b(i, j));
  217. }
  218. }
  219. b.transposeRotationPart();
  220. for(U j = 0; j < 3; j++)
  221. {
  222. for(U i = 0; i < 3; i++)
  223. {
  224. ANKI_TEST_EXPECT_EQ(a(j, i), b(j, i));
  225. }
  226. }
  227. }
  228. /// Mat vector multiplication
  229. template<typename Mat, typename VecIn, typename VecOut>
  230. void matVecMul()
  231. {
  232. using T = typename Mat::Scalar;
  233. Mat m = getNonEmptyMat<Mat>();
  234. VecIn v;
  235. for(U i = 0; i < VecIn::SIZE; i++)
  236. {
  237. v[i] = i;
  238. }
  239. VecOut out = m * v;
  240. VecOut out1;
  241. for(U j = 0; j < Mat::ROW_SIZE; j++)
  242. {
  243. T sum = 0;
  244. for(U i = 0; i < Mat::COLUMN_SIZE; i++)
  245. {
  246. sum += m(j, i) * v[j];
  247. }
  248. out1[j] = sum;
  249. }
  250. ANKI_TEST_EXPECT_EQ(out1, out);
  251. }
  252. template<typename Mat, typename RowVec, typename ColVec>
  253. void commonMatTests()
  254. {
  255. matOperatorsSame<Mat>();
  256. matSettersGetters<Mat, RowVec, ColVec>();
  257. }
  258. ANKI_TEST(Math, Mat3)
  259. {
  260. commonMatTests<Mat3, Vec3, Vec3>();
  261. transpose<Mat3>();
  262. // mat*mat
  263. {
  264. Mat3 a = getNonEmptyMat<Mat3>(0);
  265. Mat3 b = getNonEmptyMat<Mat3>(1);
  266. Mat3 c = a * b;
  267. Mat3 d = Mat3(18.000, 21.000, 24.000,
  268. 54.000, 66.000, 78.000,
  269. 90.000, 111.000, 132.000);
  270. ANKI_TEST_EXPECT_EQ(c, d);
  271. }
  272. // mat*vec
  273. {
  274. Mat3 m = getNonEmptyMat<Mat3>(1.0);
  275. Vec3 v(0.0, 1.0, 2.0);
  276. ANKI_TEST_EXPECT_EQ(m * v, Vec3(8, 17, 26));
  277. }
  278. }
  279. ANKI_TEST(Math, Mat4)
  280. {
  281. commonMatTests<Mat4, Vec4, Vec4>();
  282. transpose<Mat4>();
  283. // mat*mat
  284. {
  285. Mat4 a = getNonEmptyMat<Mat4>(0);
  286. Mat4 b = getNonEmptyMat<Mat4>(1);
  287. Mat4 c = a * b;
  288. Mat4 d = Mat4(62.0, 68.0, 74.0, 80.0,
  289. 174.000, 196.000, 218.000, 240.000,
  290. 286.000, 324.000, 362.000, 400.000,
  291. 398.000, 452.000, 506.000, 560.000);
  292. ANKI_TEST_EXPECT_EQ(c, d);
  293. }
  294. // mat*vec
  295. {
  296. Mat4 m = getNonEmptyMat<Mat4>(1.0);
  297. Vec4 v(0.0, 1.0, 2.0, 3.0);
  298. ANKI_TEST_EXPECT_EQ(m * v, Vec4(20, 44, 68, 92));
  299. }
  300. }