SMatrix.ts 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628
  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) 2016-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. m11 = 1;
  33. m21 = 0;
  34. m31 = 0;
  35. m41 = 0;
  36. m12 = 0;
  37. m22 = 1;
  38. m32 = 0;
  39. m42 = 0;
  40. m13 = 0;
  41. m23 = 0;
  42. m33 = 1;
  43. m43 = 0;
  44. m14 = 0;
  45. m24 = 0;
  46. m34 = 0;
  47. m44 = 1;
  48. /** x轴方向的缩放比例 */
  49. get a(): number {
  50. return this.m11;
  51. } //
  52. set a(v: number) {
  53. this.m11 = v;
  54. }
  55. /** x轴方向斜切 */
  56. get b(): number {
  57. return this.m12;
  58. }
  59. set b(v: number) {
  60. this.m12 = v;
  61. }
  62. /** y轴方向斜切 */
  63. get c(): number {
  64. return this.m21;
  65. }
  66. set c(v: number) {
  67. this.m21 = v;
  68. }
  69. /** y轴方向缩放比例 */
  70. get d(): number {
  71. return this.m22;
  72. }
  73. set d(v: number) {
  74. this.m22 = v;
  75. }
  76. /** x轴方向平移 */
  77. get e(): number {
  78. return this.m41;
  79. }
  80. set e(v: number) {
  81. this.m41 = v;
  82. }
  83. /** y轴方向平移 */
  84. get f(): number {
  85. return this.m42;
  86. }
  87. set f(v: number) {
  88. this.m42 = v;
  89. }
  90. /**
  91. * 是否为 2D 矩阵
  92. */
  93. get is2D(): boolean {
  94. return true;
  95. }
  96. /**
  97. * 是否为单位矩阵
  98. */
  99. get isIdentity(): boolean {
  100. return (
  101. this.m11 == 1 &&
  102. this.m21 == 0 &&
  103. this.m31 == 0 &&
  104. this.m41 == 0 &&
  105. this.m12 == 0 &&
  106. this.m22 == 1 &&
  107. this.m32 == 0 &&
  108. this.m42 == 0 &&
  109. this.m13 == 0 &&
  110. this.m23 == 0 &&
  111. this.m33 == 1 &&
  112. this.m43 == 0 &&
  113. this.m14 == 0 &&
  114. this.m24 == 0 &&
  115. this.m34 == 0 &&
  116. this.m44 == 1
  117. );
  118. }
  119. // /**
  120. // * 构造函数
  121. // */
  122. // constructor() {}
  123. /**
  124. * 重置变换矩阵
  125. *
  126. * @return 返回自身
  127. */
  128. reset(): SMatrix {
  129. this.m11 = 1;
  130. this.m21 = 0;
  131. this.m31 = 0;
  132. this.m41 = 0;
  133. this.m12 = 0;
  134. this.m22 = 1;
  135. this.m32 = 0;
  136. this.m42 = 0;
  137. this.m13 = 0;
  138. this.m23 = 0;
  139. this.m33 = 1;
  140. this.m43 = 0;
  141. this.m14 = 0;
  142. this.m24 = 0;
  143. this.m34 = 0;
  144. this.m44 = 1;
  145. return this;
  146. }
  147. /**
  148. * 原始矩阵乘以给定的变换矩阵
  149. *
  150. * @param mat 给定的变换矩阵
  151. * @return 返回自身
  152. */
  153. multiply(mat: SMatrix): SMatrix {
  154. [
  155. this.m11,
  156. this.m21,
  157. this.m31,
  158. this.m41,
  159. this.m12,
  160. this.m22,
  161. this.m32,
  162. this.m42,
  163. this.m13,
  164. this.m23,
  165. this.m33,
  166. this.m43,
  167. this.m14,
  168. this.m24,
  169. this.m34,
  170. this.m44
  171. ] = [
  172. this.m11 * mat.m11 +
  173. this.m21 * mat.m12 +
  174. this.m31 * mat.m13 +
  175. this.m41 * mat.m14,
  176. this.m11 * mat.m21 +
  177. this.m21 * mat.m22 +
  178. this.m31 * mat.m23 +
  179. this.m41 * mat.m24,
  180. this.m11 * mat.m31 +
  181. this.m21 * mat.m32 +
  182. this.m31 * mat.m33 +
  183. this.m41 * mat.m34,
  184. this.m11 * mat.m41 +
  185. this.m21 * mat.m42 +
  186. this.m31 * mat.m43 +
  187. this.m41 * mat.m44,
  188. this.m12 * mat.m11 +
  189. this.m22 * mat.m12 +
  190. this.m32 * mat.m13 +
  191. this.m42 * mat.m14,
  192. this.m12 * mat.m21 +
  193. this.m22 * mat.m22 +
  194. this.m32 * mat.m23 +
  195. this.m42 * mat.m24,
  196. this.m12 * mat.m31 +
  197. this.m22 * mat.m32 +
  198. this.m32 * mat.m33 +
  199. this.m42 * mat.m34,
  200. this.m12 * mat.m41 +
  201. this.m22 * mat.m42 +
  202. this.m32 * mat.m43 +
  203. this.m42 * mat.m44,
  204. this.m13 * mat.m11 +
  205. this.m23 * mat.m12 +
  206. this.m33 * mat.m13 +
  207. this.m43 * mat.m14,
  208. this.m13 * mat.m21 +
  209. this.m23 * mat.m22 +
  210. this.m33 * mat.m23 +
  211. this.m43 * mat.m24,
  212. this.m13 * mat.m31 +
  213. this.m23 * mat.m32 +
  214. this.m33 * mat.m33 +
  215. this.m43 * mat.m34,
  216. this.m13 * mat.m41 +
  217. this.m23 * mat.m42 +
  218. this.m33 * mat.m43 +
  219. this.m43 * mat.m44,
  220. this.m14 * mat.m11 +
  221. this.m24 * mat.m12 +
  222. this.m34 * mat.m13 +
  223. this.m44 * mat.m14,
  224. this.m14 * mat.m21 +
  225. this.m24 * mat.m22 +
  226. this.m34 * mat.m23 +
  227. this.m44 * mat.m24,
  228. this.m14 * mat.m31 +
  229. this.m24 * mat.m32 +
  230. this.m34 * mat.m33 +
  231. this.m44 * mat.m34,
  232. this.m14 * mat.m41 +
  233. this.m24 * mat.m42 +
  234. this.m34 * mat.m43 +
  235. this.m44 * mat.m44
  236. ];
  237. return this;
  238. }
  239. /**
  240. * 位移变换
  241. *
  242. * @param dx X轴位移
  243. * @param dy Y轴位移
  244. * @param dz Z轴位移
  245. * @return 返回自身
  246. */
  247. translate(dx: number, dy: number, dz = 0): SMatrix {
  248. const mat = new SMatrix();
  249. mat.m41 = dx;
  250. mat.m42 = dy;
  251. mat.m43 = dz;
  252. this.multiply(mat);
  253. return this;
  254. }
  255. // /**
  256. // * 平移变换矩阵
  257. // *
  258. // * @param dx X轴位移
  259. // * @param dy Y轴位移
  260. // * @param dz Z轴位移
  261. // * @return 返回平移变换矩阵
  262. // */
  263. // translated(dx: number, dy: number, dz = 0): SMatrix {
  264. // const mat = new SMatrix();
  265. // mat.m41 = dx;
  266. // mat.m42 = dy;
  267. // mat.m43 = dz;
  268. // return mat;
  269. // }
  270. /**
  271. * 缩放变换
  272. *
  273. * @param sx X轴缩放比例
  274. * @param sy Y轴缩放比例
  275. * @return 返回自身
  276. */
  277. scale(sx: number, sy: number): SMatrix {
  278. const mat = new SMatrix();
  279. mat.m11 = sx;
  280. mat.m22 = sy;
  281. this.multiply(mat);
  282. return this;
  283. }
  284. // /**
  285. // * 缩放变换矩阵
  286. // *
  287. // * @param sx X轴缩放比例
  288. // * @param sy Y轴缩放比例
  289. // * @return 返回缩放变换矩阵
  290. // */
  291. // scaled(sx: number, sy: number): SMatrix {
  292. // const mat = new SMatrix();
  293. // mat.m11 = sx;
  294. // mat.m22 = sy;
  295. // return mat;
  296. // }
  297. /**
  298. * 旋转变形
  299. *
  300. * @param angle 绕 Z 轴旋转角度(单位角度度)
  301. * @return 返回自身
  302. */
  303. rotate(angle: number): SMatrix;
  304. /**
  305. * 旋转变形
  306. *
  307. * @param rotX 绕 X 轴旋转角度(单位角度度)
  308. * @param rotY 绕 X 轴旋转角度(单位角度度)
  309. * @param rotZ 绕 X 轴旋转角度(单位角度度)
  310. * @return 返回自身
  311. */
  312. rotate(rotX: number, rotY: number, rotZ: number): SMatrix;
  313. /**
  314. * 旋转变形
  315. *
  316. * @param rotX 绕 Z 轴旋转角度 | 绕 X 轴旋转角度(单位弧度)
  317. * @param rotY 绕 X 轴旋转角度(单位弧度)
  318. * @param rotZ 绕 X 轴旋转角度(单位弧度)
  319. * @return 返回自身
  320. */
  321. rotate(rotX: number, rotY?: number, rotZ?: number): SMatrix {
  322. const matZ = new SMatrix();
  323. if (rotY != undefined && rotZ != undefined) {
  324. const matX = new SMatrix();
  325. matX.m22 = Math.cos((rotX * Math.PI) / 180);
  326. matX.m32 = -Math.sin((rotX * Math.PI) / 180);
  327. matX.m23 = Math.sin((rotX * Math.PI) / 180);
  328. matX.m33 = Math.cos((rotX * Math.PI) / 180);
  329. this.multiply(matX);
  330. const matY = new SMatrix();
  331. matY.m11 = Math.cos((rotY * Math.PI) / 180);
  332. matY.m31 = Math.sin((rotY * Math.PI) / 180);
  333. matY.m13 = -Math.sin((rotY * Math.PI) / 180);
  334. matY.m33 = Math.cos((rotY * Math.PI) / 180);
  335. this.multiply(matY);
  336. matZ.m11 = Math.cos((rotZ * Math.PI) / 180);
  337. matZ.m21 = -Math.sin((rotZ * Math.PI) / 180);
  338. matZ.m12 = Math.sin((rotZ * Math.PI) / 180);
  339. matZ.m22 = Math.cos((rotZ * Math.PI) / 180);
  340. this.multiply(matZ);
  341. return this;
  342. } else {
  343. matZ.m11 = Math.cos((rotX * Math.PI) / 180);
  344. matZ.m21 = -Math.sin((rotX * Math.PI) / 180);
  345. matZ.m12 = Math.sin((rotX * Math.PI) / 180);
  346. matZ.m22 = Math.cos((rotX * Math.PI) / 180);
  347. this.multiply(matZ);
  348. return this;
  349. }
  350. }
  351. /**
  352. * 转置当前矩阵
  353. *
  354. * @return 返回自身
  355. */
  356. transpose(): SMatrix {
  357. [this.m12, this.m21] = [this.m21, this.m12];
  358. [this.m13, this.m31] = [this.m31, this.m13];
  359. [this.m14, this.m41] = [this.m41, this.m14];
  360. [this.m23, this.m32] = [this.m32, this.m23];
  361. [this.m24, this.m42] = [this.m42, this.m24];
  362. [this.m34, this.m43] = [this.m43, this.m34];
  363. return this;
  364. }
  365. // /**
  366. // * 转置当前矩阵
  367. // *
  368. // * @return 返回自身
  369. // */
  370. // transposed(): SMatrix {
  371. // const mat = new SMatrix();
  372. // mat.m11 = this.m11;
  373. // mat.m21 = this.m12;
  374. // mat.m31 = this.m13;
  375. // mat.m41 = this.m14;
  376. //
  377. // mat.m12 = this.m21;
  378. // mat.m22 = this.m22;
  379. // mat.m32 = this.m23;
  380. // mat.m42 = this.m24;
  381. //
  382. // mat.m13 = this.m31;
  383. // mat.m23 = this.m32;
  384. // mat.m33 = this.m33;
  385. // mat.m43 = this.m34;
  386. //
  387. // mat.m14 = this.m41;
  388. // mat.m24 = this.m42;
  389. // mat.m34 = this.m43;
  390. // mat.m44 = this.m44;
  391. //
  392. // return mat;
  393. // }
  394. /**
  395. * 返回当前矩阵的逆矩阵
  396. *
  397. * @return 当前矩阵的逆矩阵
  398. * */
  399. inversed(): SMatrix {
  400. const detMat = this.det();
  401. const d = this.value();
  402. const ret = new SMatrix();
  403. ret.m11 = detMat.m11 / d;
  404. ret.m21 = detMat.m21 / d;
  405. ret.m31 = detMat.m31 / d;
  406. ret.m41 = detMat.m41 / d;
  407. ret.m12 = detMat.m12 / d;
  408. ret.m22 = detMat.m22 / d;
  409. ret.m32 = detMat.m32 / d;
  410. ret.m42 = detMat.m42 / d;
  411. ret.m13 = detMat.m13 / d;
  412. ret.m23 = detMat.m23 / d;
  413. ret.m33 = detMat.m33 / d;
  414. ret.m43 = detMat.m43 / d;
  415. ret.m14 = detMat.m14 / d;
  416. ret.m24 = detMat.m24 / d;
  417. ret.m34 = detMat.m34 / d;
  418. ret.m44 = detMat.m44 / d;
  419. return ret;
  420. }
  421. /**
  422. * 返回当前矩阵的伴随矩阵
  423. *
  424. * @return 当前矩阵的伴随矩阵
  425. * */
  426. det(): SMatrix {
  427. const m = new SMatrix();
  428. m.m11 =
  429. this.m22 * this.m33 * this.m44 +
  430. this.m32 * this.m43 * this.m24 +
  431. this.m42 * this.m23 * this.m34 -
  432. this.m42 * this.m33 * this.m24 -
  433. this.m32 * this.m23 * this.m44 -
  434. this.m22 * this.m43 * this.m34;
  435. m.m12 = -(
  436. this.m12 * this.m33 * this.m44 +
  437. this.m32 * this.m43 * this.m14 +
  438. this.m42 * this.m13 * this.m34 -
  439. this.m42 * this.m33 * this.m14 -
  440. this.m32 * this.m13 * this.m44 -
  441. this.m12 * this.m43 * this.m34
  442. );
  443. m.m13 =
  444. this.m12 * this.m23 * this.m44 +
  445. this.m22 * this.m43 * this.m14 +
  446. this.m42 * this.m13 * this.m24 -
  447. this.m42 * this.m23 * this.m14 -
  448. this.m22 * this.m13 * this.m44 -
  449. this.m12 * this.m43 * this.m24;
  450. m.m14 = -(
  451. this.m12 * this.m23 * this.m34 +
  452. this.m22 * this.m33 * this.m14 +
  453. this.m32 * this.m13 * this.m24 -
  454. this.m32 * this.m23 * this.m14 -
  455. this.m22 * this.m13 * this.m34 -
  456. this.m12 * this.m33 * this.m24
  457. );
  458. m.m21 = -(
  459. this.m21 * this.m33 * this.m44 +
  460. this.m31 * this.m43 * this.m24 +
  461. this.m41 * this.m23 * this.m34 -
  462. this.m41 * this.m33 * this.m24 -
  463. this.m31 * this.m23 * this.m44 -
  464. this.m21 * this.m43 * this.m34
  465. );
  466. m.m22 =
  467. this.m11 * this.m33 * this.m44 +
  468. this.m31 * this.m43 * this.m14 +
  469. this.m41 * this.m13 * this.m34 -
  470. this.m41 * this.m33 * this.m14 -
  471. this.m31 * this.m13 * this.m44 -
  472. this.m11 * this.m43 * this.m34;
  473. m.m23 = -(
  474. this.m11 * this.m23 * this.m44 +
  475. this.m21 * this.m43 * this.m14 +
  476. this.m41 * this.m13 * this.m24 -
  477. this.m41 * this.m23 * this.m14 -
  478. this.m21 * this.m13 * this.m44 -
  479. this.m11 * this.m43 * this.m24
  480. );
  481. m.m24 =
  482. this.m11 * this.m23 * this.m34 +
  483. this.m21 * this.m33 * this.m14 +
  484. this.m31 * this.m13 * this.m24 -
  485. this.m31 * this.m23 * this.m14 -
  486. this.m21 * this.m13 * this.m34 -
  487. this.m11 * this.m33 * this.m24;
  488. m.m31 =
  489. this.m21 * this.m32 * this.m44 +
  490. this.m31 * this.m42 * this.m24 +
  491. this.m41 * this.m22 * this.m34 -
  492. this.m41 * this.m32 * this.m24 -
  493. this.m31 * this.m22 * this.m44 -
  494. this.m21 * this.m42 * this.m34;
  495. m.m32 = -(
  496. this.m11 * this.m32 * this.m44 +
  497. this.m31 * this.m42 * this.m14 +
  498. this.m41 * this.m12 * this.m34 -
  499. this.m41 * this.m32 * this.m14 -
  500. this.m31 * this.m12 * this.m44 -
  501. this.m11 * this.m42 * this.m34
  502. );
  503. m.m33 =
  504. this.m11 * this.m22 * this.m44 +
  505. this.m21 * this.m42 * this.m14 +
  506. this.m41 * this.m12 * this.m24 -
  507. this.m41 * this.m22 * this.m14 -
  508. this.m21 * this.m12 * this.m44 -
  509. this.m11 * this.m42 * this.m24;
  510. m.m34 = -(
  511. this.m11 * this.m22 * this.m34 +
  512. this.m21 * this.m32 * this.m14 +
  513. this.m31 * this.m12 * this.m24 -
  514. this.m31 * this.m22 * this.m14 -
  515. this.m21 * this.m12 * this.m34 -
  516. this.m11 * this.m32 * this.m24
  517. );
  518. m.m41 = -(
  519. this.m21 * this.m32 * this.m43 +
  520. this.m31 * this.m42 * this.m23 +
  521. this.m41 * this.m22 * this.m33 -
  522. this.m41 * this.m32 * this.m23 -
  523. this.m31 * this.m22 * this.m43 -
  524. this.m21 * this.m42 * this.m33
  525. );
  526. m.m42 =
  527. this.m11 * this.m32 * this.m43 +
  528. this.m31 * this.m42 * this.m13 +
  529. this.m41 * this.m12 * this.m33 -
  530. this.m41 * this.m32 * this.m13 -
  531. this.m31 * this.m12 * this.m43 -
  532. this.m11 * this.m42 * this.m33;
  533. m.m43 = -(
  534. this.m11 * this.m22 * this.m43 +
  535. this.m21 * this.m42 * this.m13 +
  536. this.m41 * this.m12 * this.m23 -
  537. this.m41 * this.m22 * this.m13 -
  538. this.m21 * this.m12 * this.m43 -
  539. this.m11 * this.m42 * this.m23
  540. );
  541. m.m44 =
  542. this.m11 * this.m22 * this.m33 +
  543. this.m21 * this.m32 * this.m13 +
  544. this.m31 * this.m12 * this.m23 -
  545. this.m31 * this.m22 * this.m13 -
  546. this.m21 * this.m12 * this.m33 -
  547. this.m11 * this.m32 * this.m23;
  548. return m;
  549. }
  550. /**
  551. * 返回当前矩阵的值
  552. *
  553. * @return 当前矩阵的值
  554. * */
  555. value(): number {
  556. return (
  557. this.m11 *
  558. (this.m22 * this.m33 * this.m44 +
  559. this.m32 * this.m43 * this.m24 +
  560. this.m42 * this.m23 * this.m34 -
  561. this.m42 * this.m33 * this.m24 -
  562. this.m32 * this.m23 * this.m44 -
  563. this.m22 * this.m43 * this.m34) -
  564. this.m21 *
  565. (this.m12 * this.m33 * this.m44 +
  566. this.m32 * this.m43 * this.m14 +
  567. this.m42 * this.m13 * this.m34 -
  568. this.m42 * this.m33 * this.m14 -
  569. this.m32 * this.m13 * this.m44 -
  570. this.m12 * this.m43 * this.m34) +
  571. this.m31 *
  572. (this.m12 * this.m23 * this.m44 +
  573. this.m22 * this.m43 * this.m14 +
  574. this.m42 * this.m13 * this.m24 -
  575. this.m42 * this.m23 * this.m14 -
  576. this.m22 * this.m13 * this.m44 -
  577. this.m12 * this.m43 * this.m24) -
  578. this.m41 *
  579. (this.m12 * this.m23 * this.m34 +
  580. this.m22 * this.m33 * this.m14 +
  581. this.m32 * this.m13 * this.m24 -
  582. this.m32 * this.m23 * this.m14 -
  583. this.m22 * this.m13 * this.m34 -
  584. this.m12 * this.m33 * this.m24)
  585. );
  586. }
  587. }