mat3f_test.js 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408
  1. /**
  2. * @license
  3. * Copyright The Closure Library Authors.
  4. * SPDX-License-Identifier: Apache-2.0
  5. */
  6. ////////////////////////// NOTE ABOUT EDITING THIS FILE ///////////////////////
  7. // //
  8. // Any edits to this file must be applied to mat3d_test.js by running: //
  9. // swap_type.sh mat3f_test.js > mat3d_test.js //
  10. // //
  11. ////////////////////////// NOTE ABOUT EDITING THIS FILE ///////////////////////
  12. goog.module('goog.vec.mat3fTest');
  13. goog.setTestOnly();
  14. const mat3f = goog.require('goog.vec.mat3f');
  15. const testSuite = goog.require('goog.testing.testSuite');
  16. const randommat3f = mat3f.setFromValues(
  17. mat3f.create(), 0.8025078773498535, 0.7559120655059814, 0.15274643898010254,
  18. 0.19196106493473053, 0.0890120416879654, 0.15422114729881287,
  19. 0.09754583984613419, 0.44862601161003113, 0.9196512699127197);
  20. testSuite({
  21. testCreate() {
  22. const m = mat3f.create();
  23. assertElementsEquals([0, 0, 0, 0, 0, 0, 0, 0, 0], m);
  24. },
  25. testCreateIdentity() {
  26. const m = mat3f.createIdentity();
  27. assertElementsEquals([1, 0, 0, 0, 1, 0, 0, 0, 1], m);
  28. },
  29. testSet() {
  30. const m0 = mat3f.create();
  31. const m1 = mat3f.setFromArray(mat3f.create(), [1, 2, 3, 4, 5, 6, 7, 8, 9]);
  32. mat3f.setFromArray(m0, m1);
  33. assertElementsEquals([1, 2, 3, 4, 5, 6, 7, 8, 9], m0);
  34. mat3f.setFromValues(m0, 2, 3, 4, 5, 6, 7, 8, 9, 10);
  35. assertElementsEquals([2, 3, 4, 5, 6, 7, 8, 9, 10], m0);
  36. },
  37. testSetDiagonal() {
  38. const m0 = mat3f.create();
  39. mat3f.setDiagonalValues(m0, 1, 2, 3);
  40. assertElementsEquals([1, 0, 0, 0, 2, 0, 0, 0, 3], m0);
  41. mat3f.setDiagonal(m0, [4, 5, 6]);
  42. assertElementsEquals([4, 0, 0, 0, 5, 0, 0, 0, 6], m0);
  43. },
  44. testSetGetColumn() {
  45. const m0 = mat3f.create();
  46. mat3f.setColumn(m0, 0, [1, 2, 3]);
  47. mat3f.setColumn(m0, 1, [4, 5, 6]);
  48. mat3f.setColumn(m0, 2, [7, 8, 9]);
  49. assertElementsEquals([1, 2, 3, 4, 5, 6, 7, 8, 9], m0);
  50. const v0 = [0, 0, 0];
  51. mat3f.getColumn(m0, 0, v0);
  52. assertElementsEquals([1, 2, 3], v0);
  53. mat3f.getColumn(m0, 1, v0);
  54. assertElementsEquals([4, 5, 6], v0);
  55. mat3f.getColumn(m0, 2, v0);
  56. assertElementsEquals([7, 8, 9], v0);
  57. },
  58. testSetGetColumns() {
  59. const m0 = mat3f.create();
  60. mat3f.setColumns(m0, [1, 2, 3], [4, 5, 6], [7, 8, 9]);
  61. assertElementsEquals([1, 2, 3, 4, 5, 6, 7, 8, 9], m0);
  62. const v0 = [0, 0, 0];
  63. const v1 = [0, 0, 0];
  64. const v2 = [0, 0, 0];
  65. mat3f.getColumns(m0, v0, v1, v2);
  66. assertElementsEquals([1, 2, 3], v0);
  67. assertElementsEquals([4, 5, 6], v1);
  68. assertElementsEquals([7, 8, 9], v2);
  69. },
  70. testSetGetRow() {
  71. const m0 = mat3f.create();
  72. mat3f.setRow(m0, 0, [1, 2, 3]);
  73. mat3f.setRow(m0, 1, [4, 5, 6]);
  74. mat3f.setRow(m0, 2, [7, 8, 9]);
  75. assertElementsEquals([1, 4, 7, 2, 5, 8, 3, 6, 9], m0);
  76. const v0 = [0, 0, 0];
  77. mat3f.getRow(m0, 0, v0);
  78. assertElementsEquals([1, 2, 3], v0);
  79. mat3f.getRow(m0, 1, v0);
  80. assertElementsEquals([4, 5, 6], v0);
  81. mat3f.getRow(m0, 2, v0);
  82. assertElementsEquals([7, 8, 9], v0);
  83. },
  84. testSetGetRows() {
  85. const m0 = mat3f.create();
  86. mat3f.setRows(m0, [1, 2, 3], [4, 5, 6], [7, 8, 9]);
  87. assertElementsEquals([1, 4, 7, 2, 5, 8, 3, 6, 9], m0);
  88. const v0 = [0, 0, 0];
  89. const v1 = [0, 0, 0];
  90. const v2 = [0, 0, 0];
  91. mat3f.getRows(m0, v0, v1, v2);
  92. assertElementsEquals([1, 2, 3], v0);
  93. assertElementsEquals([4, 5, 6], v1);
  94. assertElementsEquals([7, 8, 9], v2);
  95. },
  96. testMakeZero() {
  97. const m0 = mat3f.setFromArray(mat3f.create(), [1, 2, 3, 4, 5, 6, 7, 8, 9]);
  98. assertElementsEquals([1, 2, 3, 4, 5, 6, 7, 8, 9], m0);
  99. mat3f.makeZero(m0);
  100. assertElementsEquals([0, 0, 0, 0, 0, 0, 0, 0, 0], m0);
  101. },
  102. testMakeIdentity() {
  103. const m0 = mat3f.create();
  104. mat3f.makeIdentity(m0);
  105. assertElementsEquals([1, 0, 0, 0, 1, 0, 0, 0, 1], m0);
  106. },
  107. testSetGetElement() {
  108. const m0 = mat3f.create();
  109. for (let r = 0; r < 3; r++) {
  110. for (let c = 0; c < 3; c++) {
  111. const value = c * 3 + r + 1;
  112. mat3f.setElement(m0, r, c, value);
  113. assertEquals(value, mat3f.getElement(m0, r, c));
  114. }
  115. }
  116. assertElementsEquals([1, 2, 3, 4, 5, 6, 7, 8, 9], m0);
  117. },
  118. testAddMat() {
  119. const m0 = mat3f.setFromValues(mat3f.create(), 1, 2, 3, 4, 5, 6, 7, 8, 9);
  120. const m1 = mat3f.setFromValues(mat3f.create(), 3, 4, 5, 6, 7, 8, 9, 1, 2);
  121. const m2 = mat3f.create();
  122. mat3f.addMat(m0, m1, m2);
  123. assertElementsEquals([1, 2, 3, 4, 5, 6, 7, 8, 9], m0);
  124. assertElementsEquals([3, 4, 5, 6, 7, 8, 9, 1, 2], m1);
  125. assertElementsEquals([4, 6, 8, 10, 12, 14, 16, 9, 11], m2);
  126. mat3f.addMat(m0, m1, m0);
  127. assertElementsEquals([3, 4, 5, 6, 7, 8, 9, 1, 2], m1);
  128. assertElementsEquals([4, 6, 8, 10, 12, 14, 16, 9, 11], m0);
  129. },
  130. testSubMat() {
  131. const m0 = mat3f.setFromValues(mat3f.create(), 1, 2, 3, 4, 5, 6, 7, 8, 9);
  132. const m1 = mat3f.setFromValues(mat3f.create(), 3, 4, 5, 6, 7, 8, 9, 1, 2);
  133. const m2 = mat3f.create();
  134. mat3f.subMat(m0, m1, m2);
  135. assertElementsEquals([1, 2, 3, 4, 5, 6, 7, 8, 9], m0);
  136. assertElementsEquals([3, 4, 5, 6, 7, 8, 9, 1, 2], m1);
  137. assertElementsEquals([-2, -2, -2, -2, -2, -2, -2, 7, 7], m2);
  138. mat3f.subMat(m1, m0, m1);
  139. assertElementsEquals([1, 2, 3, 4, 5, 6, 7, 8, 9], m0);
  140. assertElementsEquals([2, 2, 2, 2, 2, 2, 2, -7, -7], m1);
  141. },
  142. testMultScalar() {
  143. const m0 = mat3f.setFromValues(mat3f.create(), 1, 2, 3, 4, 5, 6, 7, 8, 9);
  144. const m1 = mat3f.create();
  145. mat3f.multScalar(m0, 5, m1);
  146. assertElementsEquals([1, 2, 3, 4, 5, 6, 7, 8, 9], m0);
  147. assertElementsEquals([5, 10, 15, 20, 25, 30, 35, 40, 45], m1);
  148. mat3f.multScalar(m0, 5, m0);
  149. assertElementsEquals([5, 10, 15, 20, 25, 30, 35, 40, 45], m0);
  150. },
  151. testMultMat() {
  152. const m0 = mat3f.setFromValues(mat3f.create(), 1, 2, 3, 4, 5, 6, 7, 8, 9);
  153. const m1 = mat3f.setFromValues(mat3f.create(), 1, 2, 3, 4, 5, 6, 7, 8, 9);
  154. const m2 = mat3f.create();
  155. mat3f.multMat(m0, m1, m2);
  156. assertElementsEquals([30, 36, 42, 66, 81, 96, 102, 126, 150], m2);
  157. mat3f.addMat(m0, m1, m1);
  158. mat3f.multMat(m0, m1, m1);
  159. assertElementsEquals([60, 72, 84, 132, 162, 192, 204, 252, 300], m1);
  160. },
  161. testTranspose() {
  162. const m0 = mat3f.setFromValues(mat3f.create(), 1, 2, 3, 4, 5, 6, 7, 8, 9);
  163. const m1 = mat3f.create();
  164. mat3f.transpose(m0, m1);
  165. assertElementsEquals([1, 4, 7, 2, 5, 8, 3, 6, 9], m1);
  166. mat3f.transpose(m1, m1);
  167. assertElementsEquals([1, 2, 3, 4, 5, 6, 7, 8, 9], m1);
  168. },
  169. testInvert() {
  170. const m0 = mat3f.setFromValues(mat3f.create(), 1, 1, 1, 1, 1, 1, 1, 1, 1);
  171. assertFalse(mat3f.invert(m0, m0));
  172. assertElementsEquals([1, 1, 1, 1, 1, 1, 1, 1, 1], m0);
  173. mat3f.setFromValues(m0, 1, 2, 3, 1, 3, 4, 3, 4, 5);
  174. assertTrue(mat3f.invert(m0, m0));
  175. assertElementsEquals([0.5, -1.0, 0.5, -3.5, 2.0, 0.5, 2.5, -1.0, -0.5], m0);
  176. mat3f.makeScale(m0, .01, .01, .01);
  177. assertTrue(mat3f.invert(m0, m0));
  178. const m1 = mat3f.create();
  179. mat3f.makeScale(m1, 100, 100, 100);
  180. assertElementsEquals(m1, m0);
  181. },
  182. testEquals() {
  183. const m0 = mat3f.setFromValues(mat3f.create(), 1, 2, 3, 4, 5, 6, 7, 8, 9);
  184. const m1 = mat3f.setFromArray(mat3f.create(), m0);
  185. assertTrue(mat3f.equals(m0, m1));
  186. assertTrue(mat3f.equals(m1, m0));
  187. for (let i = 0; i < 9; i++) {
  188. m1[i] = 15;
  189. assertFalse(mat3f.equals(m0, m1));
  190. assertFalse(mat3f.equals(m1, m0));
  191. m1[i] = i + 1;
  192. }
  193. },
  194. testMultVec3() {
  195. const m0 = mat3f.setFromValues(mat3f.create(), 1, 2, 3, 4, 5, 6, 7, 8, 9);
  196. const v0 = [1, 2, 3];
  197. const v1 = [0, 0, 0];
  198. mat3f.multVec3(m0, v0, v1);
  199. assertElementsEquals([30, 36, 42], v1);
  200. mat3f.multVec3(m0, v0, v0);
  201. assertElementsEquals([30, 36, 42], v0);
  202. },
  203. testSetValues() {
  204. const a0 = mat3f.create();
  205. assertElementsEquals([0, 0, 0, 0, 0, 0, 0, 0, 0], a0);
  206. mat3f.setFromValues(a0, 1, 2, 3, 4, 5, 6, 7, 8, 9);
  207. assertElementsEquals([1, 2, 3, 4, 5, 6, 7, 8, 9], a0);
  208. const a1 = mat3f.create();
  209. mat3f.setDiagonalValues(a1, 1, 2, 3);
  210. assertElementsEquals([1, 0, 0, 0, 2, 0, 0, 0, 3], a1);
  211. mat3f.setColumnValues(a1, 0, 2, 3, 4);
  212. mat3f.setColumnValues(a1, 1, 5, 6, 7);
  213. mat3f.setColumnValues(a1, 2, 8, 9, 1);
  214. assertElementsEquals([2, 3, 4, 5, 6, 7, 8, 9, 1], a1);
  215. mat3f.setRowValues(a1, 0, 1, 4, 7);
  216. mat3f.setRowValues(a1, 1, 2, 5, 8);
  217. mat3f.setRowValues(a1, 2, 3, 6, 9);
  218. assertElementsEquals([1, 2, 3, 4, 5, 6, 7, 8, 9], a1);
  219. },
  220. testMakeTranslate() {
  221. const m0 = mat3f.create();
  222. mat3f.makeTranslate(m0, 3, 4);
  223. assertElementsEquals([1, 0, 0, 0, 1, 0, 3, 4, 1], m0);
  224. },
  225. testMakeScale() {
  226. const m0 = mat3f.create();
  227. mat3f.makeScale(m0, 3, 4, 5);
  228. assertElementsEquals([3, 0, 0, 0, 4, 0, 0, 0, 5], m0);
  229. },
  230. testMakeRotate() {
  231. const m0 = mat3f.create();
  232. mat3f.makeRotate(m0, Math.PI / 2, 0, 0, 1);
  233. const v0 = [0, 1, 0, -1, 0, 0, 0, 0, 1];
  234. assertElementsRoughlyEqual(m0, v0, goog.vec.EPSILON);
  235. const m1 = mat3f.create();
  236. mat3f.makeRotate(m1, -Math.PI / 4, 0, 0, 1);
  237. mat3f.multMat(m0, m1, m1);
  238. const v1 = [0.7071068, 0.7071068, 0, -0.7071068, 0.7071068, 0, 0, 0, 1];
  239. assertElementsRoughlyEqual(m1, v1, goog.vec.EPSILON);
  240. },
  241. testMakeRotateX() {
  242. const m0 = mat3f.create();
  243. const m1 = mat3f.create();
  244. mat3f.makeRotateX(m0, Math.PI / 7);
  245. mat3f.makeRotate(m1, Math.PI / 7, 1, 0, 0);
  246. assertElementsRoughlyEqual(m0, m1, goog.vec.EPSILON);
  247. },
  248. testMakeRotateY() {
  249. const m0 = mat3f.create();
  250. const m1 = mat3f.create();
  251. mat3f.makeRotateY(m0, Math.PI / 7);
  252. mat3f.makeRotate(m1, Math.PI / 7, 0, 1, 0);
  253. assertElementsRoughlyEqual(m0, m1, goog.vec.EPSILON);
  254. },
  255. testMakeRotateZ() {
  256. const m0 = mat3f.create();
  257. const m1 = mat3f.create();
  258. mat3f.makeRotateZ(m0, Math.PI / 7);
  259. mat3f.makeRotate(m1, Math.PI / 7, 0, 0, 1);
  260. assertElementsRoughlyEqual(m0, m1, goog.vec.EPSILON);
  261. },
  262. testRotate() {
  263. const m0 = mat3f.makeIdentity(mat3f.create());
  264. mat3f.rotate(m0, Math.PI / 2, 0, 0, 1);
  265. assertElementsRoughlyEqual(
  266. [0, 1, 0, -1, 0, 0, 0, 0, 1], m0, goog.vec.EPSILON);
  267. mat3f.rotate(m0, -Math.PI / 4, 0, 0, 1);
  268. assertElementsRoughlyEqual(
  269. [0.7071068, 0.7071068, 0, -0.7071068, 0.7071068, 0, 0, 0, 1], m0,
  270. goog.vec.EPSILON);
  271. },
  272. testRotateX() {
  273. const m0 = mat3f.create();
  274. const m1 = mat3f.setFromArray(mat3f.create(), randommat3f);
  275. mat3f.makeRotateX(m0, Math.PI / 7);
  276. mat3f.multMat(m1, m0, m0);
  277. mat3f.rotateX(m1, Math.PI / 7);
  278. assertElementsRoughlyEqual(m0, m1, goog.vec.EPSILON);
  279. },
  280. testRotateY() {
  281. const m0 = mat3f.create();
  282. const m1 = mat3f.setFromArray(mat3f.create(), randommat3f);
  283. mat3f.makeRotateY(m0, Math.PI / 7);
  284. mat3f.multMat(m1, m0, m0);
  285. mat3f.rotateY(m1, Math.PI / 7);
  286. assertElementsRoughlyEqual(m0, m1, goog.vec.EPSILON);
  287. },
  288. testRotateZ() {
  289. const m0 = mat3f.create();
  290. const m1 = mat3f.setFromArray(mat3f.create(), randommat3f);
  291. mat3f.makeRotateZ(m0, Math.PI / 7);
  292. mat3f.multMat(m1, m0, m0);
  293. mat3f.rotateZ(m1, Math.PI / 7);
  294. assertElementsRoughlyEqual(m0, m1, goog.vec.EPSILON);
  295. },
  296. testMakeEulerZXZ() {
  297. const m0 = mat3f.create();
  298. const roll = 0.200982 * 2 * Math.PI;
  299. const tilt = 0.915833 * Math.PI;
  300. const yaw = 0.839392 * 2 * Math.PI;
  301. mat3f.makeRotate(m0, roll, 0, 0, 1);
  302. mat3f.rotate(m0, tilt, 1, 0, 0);
  303. mat3f.rotate(m0, yaw, 0, 0, 1);
  304. const m1 = mat3f.create();
  305. mat3f.makeEulerZXZ(m1, roll, tilt, yaw);
  306. assertElementsRoughlyEqual(m0, m1, goog.vec.EPSILON);
  307. let euler = [0, 0, 0];
  308. mat3f.toEulerZXZ(m0, euler);
  309. assertRoughlyEquals(roll, euler[0], goog.vec.EPSILON);
  310. assertRoughlyEquals(tilt, euler[1], goog.vec.EPSILON);
  311. assertRoughlyEquals(yaw, euler[2], goog.vec.EPSILON);
  312. // Test negative tilt now.
  313. mat3f.makeRotate(m0, roll, 0, 0, 1);
  314. mat3f.rotate(m0, -tilt, 1, 0, 0);
  315. mat3f.rotate(m0, yaw, 0, 0, 1);
  316. mat3f.makeEulerZXZ(m1, roll, -tilt, yaw);
  317. assertElementsRoughlyEqual(m0, m1, goog.vec.EPSILON);
  318. euler = [0, 0, 0];
  319. mat3f.toEulerZXZ(m0, euler, true);
  320. assertRoughlyEquals(roll, euler[0], goog.vec.EPSILON);
  321. assertRoughlyEquals(-tilt, euler[1], goog.vec.EPSILON);
  322. assertRoughlyEquals(yaw, euler[2], goog.vec.EPSILON);
  323. },
  324. testEulerZXZExtrema() {
  325. const m0 = mat3f.setFromArray(mat3f.create(), [1, 0, 0, 0, 0, -1, 0, 1, 0]);
  326. const m1 = mat3f.setFromArray(mat3f.create(), [0, 0, 0, 0, 0, 0, 0, 0, 0]);
  327. const euler = [0, 0, 0];
  328. mat3f.toEulerZXZ(m0, euler);
  329. assertElementsRoughlyEqual(
  330. [Math.PI, Math.PI / 2, Math.PI], euler, goog.vec.EPSILON);
  331. mat3f.makeEulerZXZ(m1, euler[0], euler[1], euler[2]);
  332. assertElementsRoughlyEqual(m0, m1, goog.vec.EPSILON);
  333. },
  334. });