Matrix3x2.cs 28 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807
  1. // Licensed to the .NET Foundation under one or more agreements.
  2. // The .NET Foundation licenses this file to you under the MIT license.
  3. // See the LICENSE file in the project root for more information.
  4. using System.Globalization;
  5. namespace System.Numerics
  6. {
  7. /// <summary>
  8. /// A structure encapsulating a 3x2 matrix.
  9. /// </summary>
  10. public struct Matrix3x2 : IEquatable<Matrix3x2>
  11. {
  12. private const float RotationEpsilon = 0.001f * MathF.PI / 180f; // 0.1% of a degree
  13. #region Public Fields
  14. /// <summary>
  15. /// The first element of the first row
  16. /// </summary>
  17. public float M11;
  18. /// <summary>
  19. /// The second element of the first row
  20. /// </summary>
  21. public float M12;
  22. /// <summary>
  23. /// The first element of the second row
  24. /// </summary>
  25. public float M21;
  26. /// <summary>
  27. /// The second element of the second row
  28. /// </summary>
  29. public float M22;
  30. /// <summary>
  31. /// The first element of the third row
  32. /// </summary>
  33. public float M31;
  34. /// <summary>
  35. /// The second element of the third row
  36. /// </summary>
  37. public float M32;
  38. #endregion Public Fields
  39. private static readonly Matrix3x2 _identity = new Matrix3x2
  40. (
  41. 1f, 0f,
  42. 0f, 1f,
  43. 0f, 0f
  44. );
  45. /// <summary>
  46. /// Returns the multiplicative identity matrix.
  47. /// </summary>
  48. public static Matrix3x2 Identity
  49. {
  50. get { return _identity; }
  51. }
  52. /// <summary>
  53. /// Returns whether the matrix is the identity matrix.
  54. /// </summary>
  55. public readonly bool IsIdentity
  56. {
  57. get
  58. {
  59. return M11 == 1f && M22 == 1f && // Check diagonal element first for early out.
  60. M12 == 0f &&
  61. M21 == 0f &&
  62. M31 == 0f && M32 == 0f;
  63. }
  64. }
  65. /// <summary>
  66. /// Gets or sets the translation component of this matrix.
  67. /// </summary>
  68. public Vector2 Translation
  69. {
  70. readonly get
  71. {
  72. return new Vector2(M31, M32);
  73. }
  74. set
  75. {
  76. M31 = value.X;
  77. M32 = value.Y;
  78. }
  79. }
  80. /// <summary>
  81. /// Constructs a Matrix3x2 from the given components.
  82. /// </summary>
  83. public Matrix3x2(float m11, float m12,
  84. float m21, float m22,
  85. float m31, float m32)
  86. {
  87. this.M11 = m11;
  88. this.M12 = m12;
  89. this.M21 = m21;
  90. this.M22 = m22;
  91. this.M31 = m31;
  92. this.M32 = m32;
  93. }
  94. /// <summary>
  95. /// Creates a translation matrix from the given vector.
  96. /// </summary>
  97. /// <param name="position">The translation position.</param>
  98. /// <returns>A translation matrix.</returns>
  99. public static Matrix3x2 CreateTranslation(Vector2 position)
  100. {
  101. Matrix3x2 result;
  102. result.M11 = 1.0f;
  103. result.M12 = 0.0f;
  104. result.M21 = 0.0f;
  105. result.M22 = 1.0f;
  106. result.M31 = position.X;
  107. result.M32 = position.Y;
  108. return result;
  109. }
  110. /// <summary>
  111. /// Creates a translation matrix from the given X and Y components.
  112. /// </summary>
  113. /// <param name="xPosition">The X position.</param>
  114. /// <param name="yPosition">The Y position.</param>
  115. /// <returns>A translation matrix.</returns>
  116. public static Matrix3x2 CreateTranslation(float xPosition, float yPosition)
  117. {
  118. Matrix3x2 result;
  119. result.M11 = 1.0f;
  120. result.M12 = 0.0f;
  121. result.M21 = 0.0f;
  122. result.M22 = 1.0f;
  123. result.M31 = xPosition;
  124. result.M32 = yPosition;
  125. return result;
  126. }
  127. /// <summary>
  128. /// Creates a scale matrix from the given X and Y components.
  129. /// </summary>
  130. /// <param name="xScale">Value to scale by on the X-axis.</param>
  131. /// <param name="yScale">Value to scale by on the Y-axis.</param>
  132. /// <returns>A scaling matrix.</returns>
  133. public static Matrix3x2 CreateScale(float xScale, float yScale)
  134. {
  135. Matrix3x2 result;
  136. result.M11 = xScale;
  137. result.M12 = 0.0f;
  138. result.M21 = 0.0f;
  139. result.M22 = yScale;
  140. result.M31 = 0.0f;
  141. result.M32 = 0.0f;
  142. return result;
  143. }
  144. /// <summary>
  145. /// Creates a scale matrix that is offset by a given center point.
  146. /// </summary>
  147. /// <param name="xScale">Value to scale by on the X-axis.</param>
  148. /// <param name="yScale">Value to scale by on the Y-axis.</param>
  149. /// <param name="centerPoint">The center point.</param>
  150. /// <returns>A scaling matrix.</returns>
  151. public static Matrix3x2 CreateScale(float xScale, float yScale, Vector2 centerPoint)
  152. {
  153. Matrix3x2 result;
  154. float tx = centerPoint.X * (1 - xScale);
  155. float ty = centerPoint.Y * (1 - yScale);
  156. result.M11 = xScale;
  157. result.M12 = 0.0f;
  158. result.M21 = 0.0f;
  159. result.M22 = yScale;
  160. result.M31 = tx;
  161. result.M32 = ty;
  162. return result;
  163. }
  164. /// <summary>
  165. /// Creates a scale matrix from the given vector scale.
  166. /// </summary>
  167. /// <param name="scales">The scale to use.</param>
  168. /// <returns>A scaling matrix.</returns>
  169. public static Matrix3x2 CreateScale(Vector2 scales)
  170. {
  171. Matrix3x2 result;
  172. result.M11 = scales.X;
  173. result.M12 = 0.0f;
  174. result.M21 = 0.0f;
  175. result.M22 = scales.Y;
  176. result.M31 = 0.0f;
  177. result.M32 = 0.0f;
  178. return result;
  179. }
  180. /// <summary>
  181. /// Creates a scale matrix from the given vector scale with an offset from the given center point.
  182. /// </summary>
  183. /// <param name="scales">The scale to use.</param>
  184. /// <param name="centerPoint">The center offset.</param>
  185. /// <returns>A scaling matrix.</returns>
  186. public static Matrix3x2 CreateScale(Vector2 scales, Vector2 centerPoint)
  187. {
  188. Matrix3x2 result;
  189. float tx = centerPoint.X * (1 - scales.X);
  190. float ty = centerPoint.Y * (1 - scales.Y);
  191. result.M11 = scales.X;
  192. result.M12 = 0.0f;
  193. result.M21 = 0.0f;
  194. result.M22 = scales.Y;
  195. result.M31 = tx;
  196. result.M32 = ty;
  197. return result;
  198. }
  199. /// <summary>
  200. /// Creates a scale matrix that scales uniformly with the given scale.
  201. /// </summary>
  202. /// <param name="scale">The uniform scale to use.</param>
  203. /// <returns>A scaling matrix.</returns>
  204. public static Matrix3x2 CreateScale(float scale)
  205. {
  206. Matrix3x2 result;
  207. result.M11 = scale;
  208. result.M12 = 0.0f;
  209. result.M21 = 0.0f;
  210. result.M22 = scale;
  211. result.M31 = 0.0f;
  212. result.M32 = 0.0f;
  213. return result;
  214. }
  215. /// <summary>
  216. /// Creates a scale matrix that scales uniformly with the given scale with an offset from the given center.
  217. /// </summary>
  218. /// <param name="scale">The uniform scale to use.</param>
  219. /// <param name="centerPoint">The center offset.</param>
  220. /// <returns>A scaling matrix.</returns>
  221. public static Matrix3x2 CreateScale(float scale, Vector2 centerPoint)
  222. {
  223. Matrix3x2 result;
  224. float tx = centerPoint.X * (1 - scale);
  225. float ty = centerPoint.Y * (1 - scale);
  226. result.M11 = scale;
  227. result.M12 = 0.0f;
  228. result.M21 = 0.0f;
  229. result.M22 = scale;
  230. result.M31 = tx;
  231. result.M32 = ty;
  232. return result;
  233. }
  234. /// <summary>
  235. /// Creates a skew matrix from the given angles in radians.
  236. /// </summary>
  237. /// <param name="radiansX">The X angle, in radians.</param>
  238. /// <param name="radiansY">The Y angle, in radians.</param>
  239. /// <returns>A skew matrix.</returns>
  240. public static Matrix3x2 CreateSkew(float radiansX, float radiansY)
  241. {
  242. Matrix3x2 result;
  243. float xTan = MathF.Tan(radiansX);
  244. float yTan = MathF.Tan(radiansY);
  245. result.M11 = 1.0f;
  246. result.M12 = yTan;
  247. result.M21 = xTan;
  248. result.M22 = 1.0f;
  249. result.M31 = 0.0f;
  250. result.M32 = 0.0f;
  251. return result;
  252. }
  253. /// <summary>
  254. /// Creates a skew matrix from the given angles in radians and a center point.
  255. /// </summary>
  256. /// <param name="radiansX">The X angle, in radians.</param>
  257. /// <param name="radiansY">The Y angle, in radians.</param>
  258. /// <param name="centerPoint">The center point.</param>
  259. /// <returns>A skew matrix.</returns>
  260. public static Matrix3x2 CreateSkew(float radiansX, float radiansY, Vector2 centerPoint)
  261. {
  262. Matrix3x2 result;
  263. float xTan = MathF.Tan(radiansX);
  264. float yTan = MathF.Tan(radiansY);
  265. float tx = -centerPoint.Y * xTan;
  266. float ty = -centerPoint.X * yTan;
  267. result.M11 = 1.0f;
  268. result.M12 = yTan;
  269. result.M21 = xTan;
  270. result.M22 = 1.0f;
  271. result.M31 = tx;
  272. result.M32 = ty;
  273. return result;
  274. }
  275. /// <summary>
  276. /// Creates a rotation matrix using the given rotation in radians.
  277. /// </summary>
  278. /// <param name="radians">The amount of rotation, in radians.</param>
  279. /// <returns>A rotation matrix.</returns>
  280. public static Matrix3x2 CreateRotation(float radians)
  281. {
  282. Matrix3x2 result;
  283. radians = MathF.IEEERemainder(radians, MathF.PI * 2);
  284. float c, s;
  285. if (radians > -RotationEpsilon && radians < RotationEpsilon)
  286. {
  287. // Exact case for zero rotation.
  288. c = 1;
  289. s = 0;
  290. }
  291. else if (radians > MathF.PI / 2 - RotationEpsilon && radians < MathF.PI / 2 + RotationEpsilon)
  292. {
  293. // Exact case for 90 degree rotation.
  294. c = 0;
  295. s = 1;
  296. }
  297. else if (radians < -MathF.PI + RotationEpsilon || radians > MathF.PI - RotationEpsilon)
  298. {
  299. // Exact case for 180 degree rotation.
  300. c = -1;
  301. s = 0;
  302. }
  303. else if (radians > -MathF.PI / 2 - RotationEpsilon && radians < -MathF.PI / 2 + RotationEpsilon)
  304. {
  305. // Exact case for 270 degree rotation.
  306. c = 0;
  307. s = -1;
  308. }
  309. else
  310. {
  311. // Arbitrary rotation.
  312. c = MathF.Cos(radians);
  313. s = MathF.Sin(radians);
  314. }
  315. // [ c s ]
  316. // [ -s c ]
  317. // [ 0 0 ]
  318. result.M11 = c;
  319. result.M12 = s;
  320. result.M21 = -s;
  321. result.M22 = c;
  322. result.M31 = 0.0f;
  323. result.M32 = 0.0f;
  324. return result;
  325. }
  326. /// <summary>
  327. /// Creates a rotation matrix using the given rotation in radians and a center point.
  328. /// </summary>
  329. /// <param name="radians">The amount of rotation, in radians.</param>
  330. /// <param name="centerPoint">The center point.</param>
  331. /// <returns>A rotation matrix.</returns>
  332. public static Matrix3x2 CreateRotation(float radians, Vector2 centerPoint)
  333. {
  334. Matrix3x2 result;
  335. radians = MathF.IEEERemainder(radians, MathF.PI * 2);
  336. float c, s;
  337. if (radians > -RotationEpsilon && radians < RotationEpsilon)
  338. {
  339. // Exact case for zero rotation.
  340. c = 1;
  341. s = 0;
  342. }
  343. else if (radians > MathF.PI / 2 - RotationEpsilon && radians < MathF.PI / 2 + RotationEpsilon)
  344. {
  345. // Exact case for 90 degree rotation.
  346. c = 0;
  347. s = 1;
  348. }
  349. else if (radians < -MathF.PI + RotationEpsilon || radians > MathF.PI - RotationEpsilon)
  350. {
  351. // Exact case for 180 degree rotation.
  352. c = -1;
  353. s = 0;
  354. }
  355. else if (radians > -MathF.PI / 2 - RotationEpsilon && radians < -MathF.PI / 2 + RotationEpsilon)
  356. {
  357. // Exact case for 270 degree rotation.
  358. c = 0;
  359. s = -1;
  360. }
  361. else
  362. {
  363. // Arbitrary rotation.
  364. c = MathF.Cos(radians);
  365. s = MathF.Sin(radians);
  366. }
  367. float x = centerPoint.X * (1 - c) + centerPoint.Y * s;
  368. float y = centerPoint.Y * (1 - c) - centerPoint.X * s;
  369. // [ c s ]
  370. // [ -s c ]
  371. // [ x y ]
  372. result.M11 = c;
  373. result.M12 = s;
  374. result.M21 = -s;
  375. result.M22 = c;
  376. result.M31 = x;
  377. result.M32 = y;
  378. return result;
  379. }
  380. /// <summary>
  381. /// Calculates the determinant for this matrix.
  382. /// The determinant is calculated by expanding the matrix with a third column whose values are (0,0,1).
  383. /// </summary>
  384. /// <returns>The determinant.</returns>
  385. public readonly float GetDeterminant()
  386. {
  387. // There isn't actually any such thing as a determinant for a non-square matrix,
  388. // but this 3x2 type is really just an optimization of a 3x3 where we happen to
  389. // know the rightmost column is always (0, 0, 1). So we expand to 3x3 format:
  390. //
  391. // [ M11, M12, 0 ]
  392. // [ M21, M22, 0 ]
  393. // [ M31, M32, 1 ]
  394. //
  395. // Sum the diagonal products:
  396. // (M11 * M22 * 1) + (M12 * 0 * M31) + (0 * M21 * M32)
  397. //
  398. // Subtract the opposite diagonal products:
  399. // (M31 * M22 * 0) + (M32 * 0 * M11) + (1 * M21 * M12)
  400. //
  401. // Collapse out the constants and oh look, this is just a 2x2 determinant!
  402. return (M11 * M22) - (M21 * M12);
  403. }
  404. /// <summary>
  405. /// Attempts to invert the given matrix. If the operation succeeds, the inverted matrix is stored in the result parameter.
  406. /// </summary>
  407. /// <param name="matrix">The source matrix.</param>
  408. /// <param name="result">The output matrix.</param>
  409. /// <returns>True if the operation succeeded, False otherwise.</returns>
  410. public static bool Invert(Matrix3x2 matrix, out Matrix3x2 result)
  411. {
  412. float det = (matrix.M11 * matrix.M22) - (matrix.M21 * matrix.M12);
  413. if (MathF.Abs(det) < float.Epsilon)
  414. {
  415. result = new Matrix3x2(float.NaN, float.NaN, float.NaN, float.NaN, float.NaN, float.NaN);
  416. return false;
  417. }
  418. float invDet = 1.0f / det;
  419. result.M11 = matrix.M22 * invDet;
  420. result.M12 = -matrix.M12 * invDet;
  421. result.M21 = -matrix.M21 * invDet;
  422. result.M22 = matrix.M11 * invDet;
  423. result.M31 = (matrix.M21 * matrix.M32 - matrix.M31 * matrix.M22) * invDet;
  424. result.M32 = (matrix.M31 * matrix.M12 - matrix.M11 * matrix.M32) * invDet;
  425. return true;
  426. }
  427. /// <summary>
  428. /// Linearly interpolates from matrix1 to matrix2, based on the third parameter.
  429. /// </summary>
  430. /// <param name="matrix1">The first source matrix.</param>
  431. /// <param name="matrix2">The second source matrix.</param>
  432. /// <param name="amount">The relative weighting of matrix2.</param>
  433. /// <returns>The interpolated matrix.</returns>
  434. public static Matrix3x2 Lerp(Matrix3x2 matrix1, Matrix3x2 matrix2, float amount)
  435. {
  436. Matrix3x2 result;
  437. // First row
  438. result.M11 = matrix1.M11 + (matrix2.M11 - matrix1.M11) * amount;
  439. result.M12 = matrix1.M12 + (matrix2.M12 - matrix1.M12) * amount;
  440. // Second row
  441. result.M21 = matrix1.M21 + (matrix2.M21 - matrix1.M21) * amount;
  442. result.M22 = matrix1.M22 + (matrix2.M22 - matrix1.M22) * amount;
  443. // Third row
  444. result.M31 = matrix1.M31 + (matrix2.M31 - matrix1.M31) * amount;
  445. result.M32 = matrix1.M32 + (matrix2.M32 - matrix1.M32) * amount;
  446. return result;
  447. }
  448. /// <summary>
  449. /// Negates the given matrix by multiplying all values by -1.
  450. /// </summary>
  451. /// <param name="value">The source matrix.</param>
  452. /// <returns>The negated matrix.</returns>
  453. public static Matrix3x2 Negate(Matrix3x2 value)
  454. {
  455. Matrix3x2 result;
  456. result.M11 = -value.M11;
  457. result.M12 = -value.M12;
  458. result.M21 = -value.M21;
  459. result.M22 = -value.M22;
  460. result.M31 = -value.M31;
  461. result.M32 = -value.M32;
  462. return result;
  463. }
  464. /// <summary>
  465. /// Adds each matrix element in value1 with its corresponding element in value2.
  466. /// </summary>
  467. /// <param name="value1">The first source matrix.</param>
  468. /// <param name="value2">The second source matrix.</param>
  469. /// <returns>The matrix containing the summed values.</returns>
  470. public static Matrix3x2 Add(Matrix3x2 value1, Matrix3x2 value2)
  471. {
  472. Matrix3x2 result;
  473. result.M11 = value1.M11 + value2.M11;
  474. result.M12 = value1.M12 + value2.M12;
  475. result.M21 = value1.M21 + value2.M21;
  476. result.M22 = value1.M22 + value2.M22;
  477. result.M31 = value1.M31 + value2.M31;
  478. result.M32 = value1.M32 + value2.M32;
  479. return result;
  480. }
  481. /// <summary>
  482. /// Subtracts each matrix element in value2 from its corresponding element in value1.
  483. /// </summary>
  484. /// <param name="value1">The first source matrix.</param>
  485. /// <param name="value2">The second source matrix.</param>
  486. /// <returns>The matrix containing the resulting values.</returns>
  487. public static Matrix3x2 Subtract(Matrix3x2 value1, Matrix3x2 value2)
  488. {
  489. Matrix3x2 result;
  490. result.M11 = value1.M11 - value2.M11;
  491. result.M12 = value1.M12 - value2.M12;
  492. result.M21 = value1.M21 - value2.M21;
  493. result.M22 = value1.M22 - value2.M22;
  494. result.M31 = value1.M31 - value2.M31;
  495. result.M32 = value1.M32 - value2.M32;
  496. return result;
  497. }
  498. /// <summary>
  499. /// Multiplies two matrices together and returns the resulting matrix.
  500. /// </summary>
  501. /// <param name="value1">The first source matrix.</param>
  502. /// <param name="value2">The second source matrix.</param>
  503. /// <returns>The product matrix.</returns>
  504. public static Matrix3x2 Multiply(Matrix3x2 value1, Matrix3x2 value2)
  505. {
  506. Matrix3x2 result;
  507. // First row
  508. result.M11 = value1.M11 * value2.M11 + value1.M12 * value2.M21;
  509. result.M12 = value1.M11 * value2.M12 + value1.M12 * value2.M22;
  510. // Second row
  511. result.M21 = value1.M21 * value2.M11 + value1.M22 * value2.M21;
  512. result.M22 = value1.M21 * value2.M12 + value1.M22 * value2.M22;
  513. // Third row
  514. result.M31 = value1.M31 * value2.M11 + value1.M32 * value2.M21 + value2.M31;
  515. result.M32 = value1.M31 * value2.M12 + value1.M32 * value2.M22 + value2.M32;
  516. return result;
  517. }
  518. /// <summary>
  519. /// Scales all elements in a matrix by the given scalar factor.
  520. /// </summary>
  521. /// <param name="value1">The source matrix.</param>
  522. /// <param name="value2">The scaling value to use.</param>
  523. /// <returns>The resulting matrix.</returns>
  524. public static Matrix3x2 Multiply(Matrix3x2 value1, float value2)
  525. {
  526. Matrix3x2 result;
  527. result.M11 = value1.M11 * value2;
  528. result.M12 = value1.M12 * value2;
  529. result.M21 = value1.M21 * value2;
  530. result.M22 = value1.M22 * value2;
  531. result.M31 = value1.M31 * value2;
  532. result.M32 = value1.M32 * value2;
  533. return result;
  534. }
  535. /// <summary>
  536. /// Negates the given matrix by multiplying all values by -1.
  537. /// </summary>
  538. /// <param name="value">The source matrix.</param>
  539. /// <returns>The negated matrix.</returns>
  540. public static Matrix3x2 operator -(Matrix3x2 value)
  541. {
  542. Matrix3x2 m;
  543. m.M11 = -value.M11;
  544. m.M12 = -value.M12;
  545. m.M21 = -value.M21;
  546. m.M22 = -value.M22;
  547. m.M31 = -value.M31;
  548. m.M32 = -value.M32;
  549. return m;
  550. }
  551. /// <summary>
  552. /// Adds each matrix element in value1 with its corresponding element in value2.
  553. /// </summary>
  554. /// <param name="value1">The first source matrix.</param>
  555. /// <param name="value2">The second source matrix.</param>
  556. /// <returns>The matrix containing the summed values.</returns>
  557. public static Matrix3x2 operator +(Matrix3x2 value1, Matrix3x2 value2)
  558. {
  559. Matrix3x2 m;
  560. m.M11 = value1.M11 + value2.M11;
  561. m.M12 = value1.M12 + value2.M12;
  562. m.M21 = value1.M21 + value2.M21;
  563. m.M22 = value1.M22 + value2.M22;
  564. m.M31 = value1.M31 + value2.M31;
  565. m.M32 = value1.M32 + value2.M32;
  566. return m;
  567. }
  568. /// <summary>
  569. /// Subtracts each matrix element in value2 from its corresponding element in value1.
  570. /// </summary>
  571. /// <param name="value1">The first source matrix.</param>
  572. /// <param name="value2">The second source matrix.</param>
  573. /// <returns>The matrix containing the resulting values.</returns>
  574. public static Matrix3x2 operator -(Matrix3x2 value1, Matrix3x2 value2)
  575. {
  576. Matrix3x2 m;
  577. m.M11 = value1.M11 - value2.M11;
  578. m.M12 = value1.M12 - value2.M12;
  579. m.M21 = value1.M21 - value2.M21;
  580. m.M22 = value1.M22 - value2.M22;
  581. m.M31 = value1.M31 - value2.M31;
  582. m.M32 = value1.M32 - value2.M32;
  583. return m;
  584. }
  585. /// <summary>
  586. /// Multiplies two matrices together and returns the resulting matrix.
  587. /// </summary>
  588. /// <param name="value1">The first source matrix.</param>
  589. /// <param name="value2">The second source matrix.</param>
  590. /// <returns>The product matrix.</returns>
  591. public static Matrix3x2 operator *(Matrix3x2 value1, Matrix3x2 value2)
  592. {
  593. Matrix3x2 m;
  594. // First row
  595. m.M11 = value1.M11 * value2.M11 + value1.M12 * value2.M21;
  596. m.M12 = value1.M11 * value2.M12 + value1.M12 * value2.M22;
  597. // Second row
  598. m.M21 = value1.M21 * value2.M11 + value1.M22 * value2.M21;
  599. m.M22 = value1.M21 * value2.M12 + value1.M22 * value2.M22;
  600. // Third row
  601. m.M31 = value1.M31 * value2.M11 + value1.M32 * value2.M21 + value2.M31;
  602. m.M32 = value1.M31 * value2.M12 + value1.M32 * value2.M22 + value2.M32;
  603. return m;
  604. }
  605. /// <summary>
  606. /// Scales all elements in a matrix by the given scalar factor.
  607. /// </summary>
  608. /// <param name="value1">The source matrix.</param>
  609. /// <param name="value2">The scaling value to use.</param>
  610. /// <returns>The resulting matrix.</returns>
  611. public static Matrix3x2 operator *(Matrix3x2 value1, float value2)
  612. {
  613. Matrix3x2 m;
  614. m.M11 = value1.M11 * value2;
  615. m.M12 = value1.M12 * value2;
  616. m.M21 = value1.M21 * value2;
  617. m.M22 = value1.M22 * value2;
  618. m.M31 = value1.M31 * value2;
  619. m.M32 = value1.M32 * value2;
  620. return m;
  621. }
  622. /// <summary>
  623. /// Returns a boolean indicating whether the given matrices are equal.
  624. /// </summary>
  625. /// <param name="value1">The first source matrix.</param>
  626. /// <param name="value2">The second source matrix.</param>
  627. /// <returns>True if the matrices are equal; False otherwise.</returns>
  628. public static bool operator ==(Matrix3x2 value1, Matrix3x2 value2)
  629. {
  630. return (value1.M11 == value2.M11 && value1.M22 == value2.M22 && // Check diagonal element first for early out.
  631. value1.M12 == value2.M12 &&
  632. value1.M21 == value2.M21 &&
  633. value1.M31 == value2.M31 && value1.M32 == value2.M32);
  634. }
  635. /// <summary>
  636. /// Returns a boolean indicating whether the given matrices are not equal.
  637. /// </summary>
  638. /// <param name="value1">The first source matrix.</param>
  639. /// <param name="value2">The second source matrix.</param>
  640. /// <returns>True if the matrices are not equal; False if they are equal.</returns>
  641. public static bool operator !=(Matrix3x2 value1, Matrix3x2 value2)
  642. {
  643. return (value1.M11 != value2.M11 || value1.M12 != value2.M12 ||
  644. value1.M21 != value2.M21 || value1.M22 != value2.M22 ||
  645. value1.M31 != value2.M31 || value1.M32 != value2.M32);
  646. }
  647. /// <summary>
  648. /// Returns a boolean indicating whether the matrix is equal to the other given matrix.
  649. /// </summary>
  650. /// <param name="other">The other matrix to test equality against.</param>
  651. /// <returns>True if this matrix is equal to other; False otherwise.</returns>
  652. public readonly bool Equals(Matrix3x2 other)
  653. {
  654. return (M11 == other.M11 && M22 == other.M22 && // Check diagonal element first for early out.
  655. M12 == other.M12 &&
  656. M21 == other.M21 &&
  657. M31 == other.M31 && M32 == other.M32);
  658. }
  659. /// <summary>
  660. /// Returns a boolean indicating whether the given Object is equal to this matrix instance.
  661. /// </summary>
  662. /// <param name="obj">The Object to compare against.</param>
  663. /// <returns>True if the Object is equal to this matrix; False otherwise.</returns>
  664. public override readonly bool Equals(object? obj)
  665. {
  666. if (obj is Matrix3x2)
  667. {
  668. return Equals((Matrix3x2)obj);
  669. }
  670. return false;
  671. }
  672. /// <summary>
  673. /// Returns a String representing this matrix instance.
  674. /// </summary>
  675. /// <returns>The string representation.</returns>
  676. public override readonly string ToString()
  677. {
  678. return string.Format(CultureInfo.CurrentCulture, "{{ {{M11:{0} M12:{1}}} {{M21:{2} M22:{3}}} {{M31:{4} M32:{5}}} }}",
  679. M11, M12,
  680. M21, M22,
  681. M31, M32);
  682. }
  683. /// <summary>
  684. /// Returns the hash code for this instance.
  685. /// </summary>
  686. /// <returns>The hash code.</returns>
  687. public override readonly int GetHashCode()
  688. {
  689. return unchecked(M11.GetHashCode() + M12.GetHashCode() +
  690. M21.GetHashCode() + M22.GetHashCode() +
  691. M31.GetHashCode() + M32.GetHashCode());
  692. }
  693. }
  694. }