SMatrix.ts 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579
  1. /*
  2. * *********************************************************************************************************************
  3. *
  4. * !!
  5. * .F88X
  6. * X8888Y
  7. * .}888888N;
  8. * i888888N; .:! .I$WI:
  9. * R888888I .'N88~ i8}+8Y&8"l8i$8>8W~'>W8}8]KW+8IIN"8&
  10. * .R888888I .;N8888~ .X8' "8I.!,/8" !%NY8`"8I8~~8>,88I
  11. * +888888N; .8888888Y "&&8Y.}8,
  12. * ./888888N; .R888888Y .'}~ .>}'.`+> i}! "i' +/' .'i~ !11,.:">, .~]! .i}i
  13. * ~888888%: .I888888l .]88~`1/iY88Ii+1'.R$8$8]"888888888> Y8$ W8E X8E W8888'188Il}Y88$*
  14. * 18888888 E8888881 .]W%8$`R8X'&8%++N8i,8N%N8+l8%` .}8N:.R$RE%N88N%N$K$R 188,FE$8%~Y88I
  15. * .E888888I .i8888888' .:$8I;88+`E8R:/8N,.>881.`$8E/1/]N8X.Y8N`"KF&&FK!'88*."88K./$88%RN888+~
  16. * 8888888I .,N888888~ ~88i"8W,!N8*.I88.}888%F,i$88"F88" 888:E8X.>88!i88>`888*.}Fl1]*}1YKi'
  17. * i888888N' I888Y ]88;/EX*IFKFK88X K8R .l8W 88Y ~88}'88E&%8W.X8N``]88!.$8K .:W8I
  18. * .i888888N; I8Y .&8$ .X88! i881.:%888>I88 ;88] +88+.';;;;:.Y88X 18N.,88l .+88/
  19. * .:R888888I
  20. * .&888888I Copyright (c) 2009-2020. 博锐尚格科技股份有限公司
  21. * ~8888'
  22. * .!88~ All rights reserved.
  23. *
  24. * *********************************************************************************************************************
  25. */
  26. /**
  27. * 变换矩阵
  28. *
  29. * @author 庞利祥 <sybotan@126.com>
  30. */
  31. export class SMatrix {
  32. // 开始:矩阵元素定义
  33. m11 = 1;
  34. m21 = 0;
  35. m31 = 0;
  36. m41 = 0;
  37. m12 = 0;
  38. m22 = 1;
  39. m32 = 0;
  40. m42 = 0;
  41. m13 = 0;
  42. m23 = 0;
  43. m33 = 1;
  44. m43 = 0;
  45. m14 = 0;
  46. m24 = 0;
  47. m34 = 0;
  48. m44 = 1;
  49. // 结束:矩阵元素定义
  50. /** x 轴方向的缩放比例 */
  51. get a(): number {
  52. return this.m11;
  53. }
  54. set a(v: number) {
  55. this.m11 = v;
  56. }
  57. /** x 轴方向斜切 */
  58. get b(): number {
  59. return this.m12;
  60. }
  61. set b(v: number) {
  62. this.m12 = v;
  63. }
  64. /** y轴方向斜切 */
  65. get c(): number {
  66. return this.m21;
  67. }
  68. set c(v: number) {
  69. this.m21 = v;
  70. }
  71. /** y轴方向缩放比例 */
  72. get d(): number {
  73. return this.m22;
  74. }
  75. set d(v: number) {
  76. this.m22 = v;
  77. }
  78. /** x轴方向平移 */
  79. get e(): number {
  80. return this.m41;
  81. }
  82. set e(v: number) {
  83. this.m41 = v;
  84. }
  85. /** y轴方向平移 */
  86. get f(): number {
  87. return this.m42;
  88. }
  89. set f(v: number) {
  90. this.m42 = v;
  91. }
  92. /**
  93. * 是否为 2D 矩阵
  94. */
  95. get is2D(): boolean {
  96. return true;
  97. }
  98. /**
  99. * 是否为单位矩阵
  100. */
  101. get isIdentity(): boolean {
  102. return (
  103. this.m11 == 1 &&
  104. this.m21 == 0 &&
  105. this.m31 == 0 &&
  106. this.m41 == 0 &&
  107. this.m12 == 0 &&
  108. this.m22 == 1 &&
  109. this.m32 == 0 &&
  110. this.m42 == 0 &&
  111. this.m13 == 0 &&
  112. this.m23 == 0 &&
  113. this.m33 == 1 &&
  114. this.m43 == 0 &&
  115. this.m14 == 0 &&
  116. this.m24 == 0 &&
  117. this.m34 == 0 &&
  118. this.m44 == 1
  119. );
  120. }
  121. /**
  122. * 重置变换矩阵
  123. *
  124. * @return 返回自身
  125. */
  126. reset(): SMatrix {
  127. this.m11 = 1;
  128. this.m21 = 0;
  129. this.m31 = 0;
  130. this.m41 = 0;
  131. this.m12 = 0;
  132. this.m22 = 1;
  133. this.m32 = 0;
  134. this.m42 = 0;
  135. this.m13 = 0;
  136. this.m23 = 0;
  137. this.m33 = 1;
  138. this.m43 = 0;
  139. this.m14 = 0;
  140. this.m24 = 0;
  141. this.m34 = 0;
  142. this.m44 = 1;
  143. return this;
  144. }
  145. /**
  146. * 原始矩阵乘以给定的变换矩阵
  147. *
  148. * @param mat 给定的变换矩阵
  149. * @return 返回自身
  150. */
  151. multiply(mat: SMatrix): SMatrix {
  152. [
  153. this.m11,
  154. this.m21,
  155. this.m31,
  156. this.m41,
  157. this.m12,
  158. this.m22,
  159. this.m32,
  160. this.m42,
  161. this.m13,
  162. this.m23,
  163. this.m33,
  164. this.m43,
  165. this.m14,
  166. this.m24,
  167. this.m34,
  168. this.m44
  169. ] = [
  170. this.m11 * mat.m11 +
  171. this.m21 * mat.m12 +
  172. this.m31 * mat.m13 +
  173. this.m41 * mat.m14,
  174. this.m11 * mat.m21 +
  175. this.m21 * mat.m22 +
  176. this.m31 * mat.m23 +
  177. this.m41 * mat.m24,
  178. this.m11 * mat.m31 +
  179. this.m21 * mat.m32 +
  180. this.m31 * mat.m33 +
  181. this.m41 * mat.m34,
  182. this.m11 * mat.m41 +
  183. this.m21 * mat.m42 +
  184. this.m31 * mat.m43 +
  185. this.m41 * mat.m44,
  186. this.m12 * mat.m11 +
  187. this.m22 * mat.m12 +
  188. this.m32 * mat.m13 +
  189. this.m42 * mat.m14,
  190. this.m12 * mat.m21 +
  191. this.m22 * mat.m22 +
  192. this.m32 * mat.m23 +
  193. this.m42 * mat.m24,
  194. this.m12 * mat.m31 +
  195. this.m22 * mat.m32 +
  196. this.m32 * mat.m33 +
  197. this.m42 * mat.m34,
  198. this.m12 * mat.m41 +
  199. this.m22 * mat.m42 +
  200. this.m32 * mat.m43 +
  201. this.m42 * mat.m44,
  202. this.m13 * mat.m11 +
  203. this.m23 * mat.m12 +
  204. this.m33 * mat.m13 +
  205. this.m43 * mat.m14,
  206. this.m13 * mat.m21 +
  207. this.m23 * mat.m22 +
  208. this.m33 * mat.m23 +
  209. this.m43 * mat.m24,
  210. this.m13 * mat.m31 +
  211. this.m23 * mat.m32 +
  212. this.m33 * mat.m33 +
  213. this.m43 * mat.m34,
  214. this.m13 * mat.m41 +
  215. this.m23 * mat.m42 +
  216. this.m33 * mat.m43 +
  217. this.m43 * mat.m44,
  218. this.m14 * mat.m11 +
  219. this.m24 * mat.m12 +
  220. this.m34 * mat.m13 +
  221. this.m44 * mat.m14,
  222. this.m14 * mat.m21 +
  223. this.m24 * mat.m22 +
  224. this.m34 * mat.m23 +
  225. this.m44 * mat.m24,
  226. this.m14 * mat.m31 +
  227. this.m24 * mat.m32 +
  228. this.m34 * mat.m33 +
  229. this.m44 * mat.m34,
  230. this.m14 * mat.m41 +
  231. this.m24 * mat.m42 +
  232. this.m34 * mat.m43 +
  233. this.m44 * mat.m44
  234. ];
  235. return this;
  236. }
  237. /**
  238. * 位移变换
  239. *
  240. * @param dx X 轴位移
  241. * @param dy Y 轴位移
  242. * @param dz Z 轴位移
  243. * @return 返回自身
  244. */
  245. translate(dx: number, dy: number, dz = 0): SMatrix {
  246. const mat = new SMatrix();
  247. mat.m41 = dx;
  248. mat.m42 = dy;
  249. mat.m43 = dz;
  250. this.multiply(mat);
  251. return this;
  252. }
  253. /**
  254. * 缩放变换
  255. *
  256. * @param sx X 轴缩放比例
  257. * @param sy Y 轴缩放比例
  258. * @return 返回自身
  259. */
  260. scale(sx: number, sy: number): SMatrix {
  261. const mat = new SMatrix();
  262. mat.m11 = sx;
  263. mat.m22 = sy;
  264. this.multiply(mat);
  265. return this;
  266. }
  267. /**
  268. * 旋转变形
  269. *
  270. * @param angle 绕 Z 轴旋转角度(单位角度度)
  271. * @return 返回自身
  272. */
  273. rotate(angle: number): SMatrix;
  274. /**
  275. * 旋转变形
  276. *
  277. * @param rotX 绕 X 轴旋转角度(单位角度 度)
  278. * @param rotY 绕 Y 轴旋转角度(单位角度 度)
  279. * @param rotZ 绕 Z 轴旋转角度(单位角度 度)
  280. * @return 返回自身
  281. */
  282. rotate(rotX: number, rotY: number, rotZ: number): SMatrix;
  283. /**
  284. * 旋转变形
  285. *
  286. * @param rotX 绕 Z 轴旋转角度 | 绕 X 轴旋转角度(单位度)
  287. * @param rotY 绕 Y 轴旋转角度(单位度)
  288. * @param rotZ 绕 Z 轴旋转角度(单位度)
  289. * @return 返回自身
  290. */
  291. rotate(rotX: number, rotY?: number, rotZ?: number): SMatrix {
  292. const matZ = new SMatrix();
  293. // 重载实现了 rotate(rotX: number, rotY: number, rotZ: number): SMatrix;
  294. if (rotY != undefined && rotZ != undefined) {
  295. const matX = new SMatrix();
  296. matX.m22 = Math.cos((rotX * Math.PI) / 180);
  297. matX.m32 = -Math.sin((rotX * Math.PI) / 180);
  298. matX.m23 = Math.sin((rotX * Math.PI) / 180);
  299. matX.m33 = Math.cos((rotX * Math.PI) / 180);
  300. this.multiply(matX);
  301. const matY = new SMatrix();
  302. matY.m11 = Math.cos((rotY * Math.PI) / 180);
  303. matY.m31 = Math.sin((rotY * Math.PI) / 180);
  304. matY.m13 = -Math.sin((rotY * Math.PI) / 180);
  305. matY.m33 = Math.cos((rotY * Math.PI) / 180);
  306. this.multiply(matY);
  307. matZ.m11 = Math.cos((rotZ * Math.PI) / 180);
  308. matZ.m21 = -Math.sin((rotZ * Math.PI) / 180);
  309. matZ.m12 = Math.sin((rotZ * Math.PI) / 180);
  310. matZ.m22 = Math.cos((rotZ * Math.PI) / 180);
  311. this.multiply(matZ);
  312. return this;
  313. } else { // 重载实现了 rotate(angle: number): SMatrix;
  314. matZ.m11 = Math.cos((rotX * Math.PI) / 180);
  315. matZ.m21 = -Math.sin((rotX * Math.PI) / 180);
  316. matZ.m12 = Math.sin((rotX * Math.PI) / 180);
  317. matZ.m22 = Math.cos((rotX * Math.PI) / 180);
  318. this.multiply(matZ);
  319. return this;
  320. }
  321. }
  322. /**
  323. * 转置当前矩阵
  324. *
  325. * @return 返回自身
  326. */
  327. transpose(): SMatrix {
  328. [this.m12, this.m21] = [this.m21, this.m12];
  329. [this.m13, this.m31] = [this.m31, this.m13];
  330. [this.m14, this.m41] = [this.m41, this.m14];
  331. [this.m23, this.m32] = [this.m32, this.m23];
  332. [this.m24, this.m42] = [this.m42, this.m24];
  333. [this.m34, this.m43] = [this.m43, this.m34];
  334. return this;
  335. }
  336. /**
  337. * 返回当前矩阵的逆矩阵
  338. *
  339. * @return 当前矩阵的逆矩阵
  340. */
  341. inversed(): SMatrix {
  342. const detMat = this.det();
  343. const d = this.value();
  344. const ret = new SMatrix();
  345. ret.m11 = detMat.m11 / d;
  346. ret.m21 = detMat.m21 / d;
  347. ret.m31 = detMat.m31 / d;
  348. ret.m41 = detMat.m41 / d;
  349. ret.m12 = detMat.m12 / d;
  350. ret.m22 = detMat.m22 / d;
  351. ret.m32 = detMat.m32 / d;
  352. ret.m42 = detMat.m42 / d;
  353. ret.m13 = detMat.m13 / d;
  354. ret.m23 = detMat.m23 / d;
  355. ret.m33 = detMat.m33 / d;
  356. ret.m43 = detMat.m43 / d;
  357. ret.m14 = detMat.m14 / d;
  358. ret.m24 = detMat.m24 / d;
  359. ret.m34 = detMat.m34 / d;
  360. ret.m44 = detMat.m44 / d;
  361. return ret;
  362. }
  363. /**
  364. * 返回当前矩阵的伴随矩阵
  365. *
  366. * @return 当前矩阵的伴随矩阵
  367. */
  368. det(): SMatrix {
  369. const m = new SMatrix();
  370. m.m11 =
  371. this.m22 * this.m33 * this.m44 +
  372. this.m32 * this.m43 * this.m24 +
  373. this.m42 * this.m23 * this.m34 -
  374. this.m42 * this.m33 * this.m24 -
  375. this.m32 * this.m23 * this.m44 -
  376. this.m22 * this.m43 * this.m34;
  377. m.m12 = -(
  378. this.m12 * this.m33 * this.m44 +
  379. this.m32 * this.m43 * this.m14 +
  380. this.m42 * this.m13 * this.m34 -
  381. this.m42 * this.m33 * this.m14 -
  382. this.m32 * this.m13 * this.m44 -
  383. this.m12 * this.m43 * this.m34
  384. );
  385. m.m13 =
  386. this.m12 * this.m23 * this.m44 +
  387. this.m22 * this.m43 * this.m14 +
  388. this.m42 * this.m13 * this.m24 -
  389. this.m42 * this.m23 * this.m14 -
  390. this.m22 * this.m13 * this.m44 -
  391. this.m12 * this.m43 * this.m24;
  392. m.m14 = -(
  393. this.m12 * this.m23 * this.m34 +
  394. this.m22 * this.m33 * this.m14 +
  395. this.m32 * this.m13 * this.m24 -
  396. this.m32 * this.m23 * this.m14 -
  397. this.m22 * this.m13 * this.m34 -
  398. this.m12 * this.m33 * this.m24
  399. );
  400. m.m21 = -(
  401. this.m21 * this.m33 * this.m44 +
  402. this.m31 * this.m43 * this.m24 +
  403. this.m41 * this.m23 * this.m34 -
  404. this.m41 * this.m33 * this.m24 -
  405. this.m31 * this.m23 * this.m44 -
  406. this.m21 * this.m43 * this.m34
  407. );
  408. m.m22 =
  409. this.m11 * this.m33 * this.m44 +
  410. this.m31 * this.m43 * this.m14 +
  411. this.m41 * this.m13 * this.m34 -
  412. this.m41 * this.m33 * this.m14 -
  413. this.m31 * this.m13 * this.m44 -
  414. this.m11 * this.m43 * this.m34;
  415. m.m23 = -(
  416. this.m11 * this.m23 * this.m44 +
  417. this.m21 * this.m43 * this.m14 +
  418. this.m41 * this.m13 * this.m24 -
  419. this.m41 * this.m23 * this.m14 -
  420. this.m21 * this.m13 * this.m44 -
  421. this.m11 * this.m43 * this.m24
  422. );
  423. m.m24 =
  424. this.m11 * this.m23 * this.m34 +
  425. this.m21 * this.m33 * this.m14 +
  426. this.m31 * this.m13 * this.m24 -
  427. this.m31 * this.m23 * this.m14 -
  428. this.m21 * this.m13 * this.m34 -
  429. this.m11 * this.m33 * this.m24;
  430. m.m31 =
  431. this.m21 * this.m32 * this.m44 +
  432. this.m31 * this.m42 * this.m24 +
  433. this.m41 * this.m22 * this.m34 -
  434. this.m41 * this.m32 * this.m24 -
  435. this.m31 * this.m22 * this.m44 -
  436. this.m21 * this.m42 * this.m34;
  437. m.m32 = -(
  438. this.m11 * this.m32 * this.m44 +
  439. this.m31 * this.m42 * this.m14 +
  440. this.m41 * this.m12 * this.m34 -
  441. this.m41 * this.m32 * this.m14 -
  442. this.m31 * this.m12 * this.m44 -
  443. this.m11 * this.m42 * this.m34
  444. );
  445. m.m33 =
  446. this.m11 * this.m22 * this.m44 +
  447. this.m21 * this.m42 * this.m14 +
  448. this.m41 * this.m12 * this.m24 -
  449. this.m41 * this.m22 * this.m14 -
  450. this.m21 * this.m12 * this.m44 -
  451. this.m11 * this.m42 * this.m24;
  452. m.m34 = -(
  453. this.m11 * this.m22 * this.m34 +
  454. this.m21 * this.m32 * this.m14 +
  455. this.m31 * this.m12 * this.m24 -
  456. this.m31 * this.m22 * this.m14 -
  457. this.m21 * this.m12 * this.m34 -
  458. this.m11 * this.m32 * this.m24
  459. );
  460. m.m41 = -(
  461. this.m21 * this.m32 * this.m43 +
  462. this.m31 * this.m42 * this.m23 +
  463. this.m41 * this.m22 * this.m33 -
  464. this.m41 * this.m32 * this.m23 -
  465. this.m31 * this.m22 * this.m43 -
  466. this.m21 * this.m42 * this.m33
  467. );
  468. m.m42 =
  469. this.m11 * this.m32 * this.m43 +
  470. this.m31 * this.m42 * this.m13 +
  471. this.m41 * this.m12 * this.m33 -
  472. this.m41 * this.m32 * this.m13 -
  473. this.m31 * this.m12 * this.m43 -
  474. this.m11 * this.m42 * this.m33;
  475. m.m43 = -(
  476. this.m11 * this.m22 * this.m43 +
  477. this.m21 * this.m42 * this.m13 +
  478. this.m41 * this.m12 * this.m23 -
  479. this.m41 * this.m22 * this.m13 -
  480. this.m21 * this.m12 * this.m43 -
  481. this.m11 * this.m42 * this.m23
  482. );
  483. m.m44 =
  484. this.m11 * this.m22 * this.m33 +
  485. this.m21 * this.m32 * this.m13 +
  486. this.m31 * this.m12 * this.m23 -
  487. this.m31 * this.m22 * this.m13 -
  488. this.m21 * this.m12 * this.m33 -
  489. this.m11 * this.m32 * this.m23;
  490. return m;
  491. }
  492. /**
  493. * 返回当前矩阵的值
  494. *
  495. * @return 当前矩阵的值
  496. */
  497. value(): number {
  498. return (
  499. this.m11 *
  500. (this.m22 * this.m33 * this.m44 +
  501. this.m32 * this.m43 * this.m24 +
  502. this.m42 * this.m23 * this.m34 -
  503. this.m42 * this.m33 * this.m24 -
  504. this.m32 * this.m23 * this.m44 -
  505. this.m22 * this.m43 * this.m34) -
  506. this.m21 *
  507. (this.m12 * this.m33 * this.m44 +
  508. this.m32 * this.m43 * this.m14 +
  509. this.m42 * this.m13 * this.m34 -
  510. this.m42 * this.m33 * this.m14 -
  511. this.m32 * this.m13 * this.m44 -
  512. this.m12 * this.m43 * this.m34) +
  513. this.m31 *
  514. (this.m12 * this.m23 * this.m44 +
  515. this.m22 * this.m43 * this.m14 +
  516. this.m42 * this.m13 * this.m24 -
  517. this.m42 * this.m23 * this.m14 -
  518. this.m22 * this.m13 * this.m44 -
  519. this.m12 * this.m43 * this.m24) -
  520. this.m41 *
  521. (this.m12 * this.m23 * this.m34 +
  522. this.m22 * this.m33 * this.m14 +
  523. this.m32 * this.m13 * this.m24 -
  524. this.m32 * this.m23 * this.m14 -
  525. this.m22 * this.m13 * this.m34 -
  526. this.m12 * this.m33 * this.m24)
  527. );
  528. }
  529. }