Matrix2x2.h 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159
  1. // David Eberly, Geometric Tools, Redmond WA 98052
  2. // Copyright (c) 1998-2020
  3. // Distributed under the Boost Software License, Version 1.0.
  4. // https://www.boost.org/LICENSE_1_0.txt
  5. // https://www.geometrictools.com/License/Boost/LICENSE_1_0.txt
  6. // Version: 4.0.2019.08.13
  7. #pragma once
  8. #include <Mathematics/Matrix.h>
  9. #include <Mathematics/Vector2.h>
  10. namespace WwiseGTE
  11. {
  12. // Template alias for convenience.
  13. template <typename Real>
  14. using Matrix2x2 = Matrix<2, 2, Real>;
  15. // Create a rotation matrix from an angle (in radians). The matrix is
  16. // [GTE_USE_MAT_VEC]
  17. // R(t) = {{c,-s},{s,c}}
  18. // [GTE_USE_VEC_MAT]
  19. // R(t) = {{c,s},{-s,c}}
  20. // where c = cos(t), s = sin(t), and the inner-brace pairs are rows of the
  21. // matrix.
  22. template <typename Real>
  23. void MakeRotation(Real angle, Matrix2x2<Real>& rotation)
  24. {
  25. Real cs = std::cos(angle);
  26. Real sn = std::sin(angle);
  27. #if defined(GTE_USE_MAT_VEC)
  28. rotation(0, 0) = cs;
  29. rotation(0, 1) = -sn;
  30. rotation(1, 0) = sn;
  31. rotation(1, 1) = cs;
  32. #else
  33. rotation(0, 0) = cs;
  34. rotation(0, 1) = sn;
  35. rotation(1, 0) = -sn;
  36. rotation(1, 1) = cs;
  37. #endif
  38. }
  39. // Get the angle (radians) from a rotation matrix. The caller is
  40. // responsible for ensuring the matrix is a rotation.
  41. template <typename Real>
  42. Real GetRotationAngle(Matrix2x2<Real> const& rotation)
  43. {
  44. #if defined(GTE_USE_MAT_VEC)
  45. return std::atan2(rotation(1, 0), rotation(0, 0));
  46. #else
  47. return std::atan2(rotation(0, 1), rotation(0, 0));
  48. #endif
  49. }
  50. // Geometric operations.
  51. template <typename Real>
  52. Matrix2x2<Real> Inverse(Matrix2x2<Real> const& M, bool* reportInvertibility = nullptr)
  53. {
  54. Matrix2x2<Real> inverse;
  55. bool invertible;
  56. Real det = M(0, 0) * M(1, 1) - M(0, 1) * M(1, 0);
  57. if (det != (Real)0)
  58. {
  59. Real invDet = ((Real)1) / det;
  60. inverse = Matrix2x2<Real>
  61. {
  62. M(1, 1) * invDet, -M(0, 1) * invDet,
  63. -M(1, 0) * invDet, M(0, 0) * invDet
  64. };
  65. invertible = true;
  66. }
  67. else
  68. {
  69. inverse.MakeZero();
  70. invertible = false;
  71. }
  72. if (reportInvertibility)
  73. {
  74. *reportInvertibility = invertible;
  75. }
  76. return inverse;
  77. }
  78. template <typename Real>
  79. Matrix2x2<Real> Adjoint(Matrix2x2<Real> const& M)
  80. {
  81. return Matrix2x2<Real>
  82. {
  83. M(1, 1), -M(0, 1),
  84. -M(1, 0), M(0, 0)
  85. };
  86. }
  87. template <typename Real>
  88. Real Determinant(Matrix2x2<Real> const& M)
  89. {
  90. Real det = M(0, 0) * M(1, 1) - M(0, 1) * M(1, 0);
  91. return det;
  92. }
  93. template <typename Real>
  94. Real Trace(Matrix2x2<Real> const& M)
  95. {
  96. Real trace = M(0, 0) + M(1, 1);
  97. return trace;
  98. }
  99. // Multiply M and V according to the user-selected convention. If it is
  100. // GTE_USE_MAT_VEC, the function returns M*V. If it is GTE_USE_VEC_MAT,
  101. // the function returns V*M. This function is provided to hide the
  102. // preprocessor symbols in the GTEngine sample applications.
  103. template <typename Real>
  104. Vector2<Real> DoTransform(Matrix2x2<Real> const& M, Vector2<Real> const& V)
  105. {
  106. #if defined(GTE_USE_MAT_VEC)
  107. return M * V;
  108. #else
  109. return V * M;
  110. #endif
  111. }
  112. template <typename Real>
  113. Matrix2x2<Real> DoTransform(Matrix2x2<Real> const& A, Matrix2x2<Real> const& B)
  114. {
  115. #if defined(GTE_USE_MAT_VEC)
  116. return A * B;
  117. #else
  118. return B * A;
  119. #endif
  120. }
  121. // For GTE_USE_MAT_VEC, the columns of an invertible matrix form a basis
  122. // for the range of the matrix. For GTE_USE_VEC_MAT, the rows of an
  123. // invertible matrix form a basis for the range of the matrix. These
  124. // functions allow you to access the basis vectors. The caller is
  125. // responsible for ensuring that the matrix is invertible (although the
  126. // inverse is not calculated by these functions).
  127. template <typename Real>
  128. void SetBasis(Matrix2x2<Real>& M, int i, Vector2<Real> const& V)
  129. {
  130. #if defined(GTE_USE_MAT_VEC)
  131. return M.SetCol(i, V);
  132. #else
  133. return M.SetRow(i, V);
  134. #endif
  135. }
  136. template <typename Real>
  137. Vector2<Real> GetBasis(Matrix2x2<Real> const& M, int i)
  138. {
  139. #if defined(GTE_USE_MAT_VEC)
  140. return M.GetCol(i);
  141. #else
  142. return M.GetRow(i);
  143. #endif
  144. }
  145. }