mat3_test.js 14 KB

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