Matrix3x3.h 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142
  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/Vector3.h>
  10. namespace WwiseGTE
  11. {
  12. // Template alias for convenience.
  13. template <typename Real>
  14. using Matrix3x3 = Matrix<3, 3, Real>;
  15. // Geometric operations.
  16. template <typename Real>
  17. Matrix3x3<Real> Inverse(Matrix3x3<Real> const& M, bool* reportInvertibility = nullptr)
  18. {
  19. Matrix3x3<Real> inverse;
  20. bool invertible;
  21. Real c00 = M(1, 1) * M(2, 2) - M(1, 2) * M(2, 1);
  22. Real c10 = M(1, 2) * M(2, 0) - M(1, 0) * M(2, 2);
  23. Real c20 = M(1, 0) * M(2, 1) - M(1, 1) * M(2, 0);
  24. Real det = M(0, 0) * c00 + M(0, 1) * c10 + M(0, 2) * c20;
  25. if (det != (Real)0)
  26. {
  27. Real invDet = (Real)1 / det;
  28. inverse = Matrix3x3<Real>
  29. {
  30. c00 * invDet,
  31. (M(0, 2) * M(2, 1) - M(0, 1) * M(2, 2)) * invDet,
  32. (M(0, 1) * M(1, 2) - M(0, 2) * M(1, 1)) * invDet,
  33. c10 * invDet,
  34. (M(0, 0) * M(2, 2) - M(0, 2) * M(2, 0)) * invDet,
  35. (M(0, 2) * M(1, 0) - M(0, 0) * M(1, 2)) * invDet,
  36. c20 * invDet,
  37. (M(0, 1) * M(2, 0) - M(0, 0) * M(2, 1)) * invDet,
  38. (M(0, 0) * M(1, 1) - M(0, 1) * M(1, 0)) * invDet
  39. };
  40. invertible = true;
  41. }
  42. else
  43. {
  44. inverse.MakeZero();
  45. invertible = false;
  46. }
  47. if (reportInvertibility)
  48. {
  49. *reportInvertibility = invertible;
  50. }
  51. return inverse;
  52. }
  53. template <typename Real>
  54. Matrix3x3<Real> Adjoint(Matrix3x3<Real> const& M)
  55. {
  56. return Matrix3x3<Real>
  57. {
  58. M(1, 1)* M(2, 2) - M(1, 2) * M(2, 1),
  59. M(0, 2)* M(2, 1) - M(0, 1) * M(2, 2),
  60. M(0, 1)* M(1, 2) - M(0, 2) * M(1, 1),
  61. M(1, 2)* M(2, 0) - M(1, 0) * M(2, 2),
  62. M(0, 0)* M(2, 2) - M(0, 2) * M(2, 0),
  63. M(0, 2)* M(1, 0) - M(0, 0) * M(1, 2),
  64. M(1, 0)* M(2, 1) - M(1, 1) * M(2, 0),
  65. M(0, 1)* M(2, 0) - M(0, 0) * M(2, 1),
  66. M(0, 0)* M(1, 1) - M(0, 1) * M(1, 0)
  67. };
  68. }
  69. template <typename Real>
  70. Real Determinant(Matrix3x3<Real> const& M)
  71. {
  72. Real c00 = M(1, 1) * M(2, 2) - M(1, 2) * M(2, 1);
  73. Real c10 = M(1, 2) * M(2, 0) - M(1, 0) * M(2, 2);
  74. Real c20 = M(1, 0) * M(2, 1) - M(1, 1) * M(2, 0);
  75. Real det = M(0, 0) * c00 + M(0, 1) * c10 + M(0, 2) * c20;
  76. return det;
  77. }
  78. template <typename Real>
  79. Real Trace(Matrix3x3<Real> const& M)
  80. {
  81. Real trace = M(0, 0) + M(1, 1) + M(2, 2);
  82. return trace;
  83. }
  84. // Multiply M and V according to the user-selected convention. If it is
  85. // GTE_USE_MAT_VEC, the function returns M*V. If it is GTE_USE_VEC_MAT,
  86. // the function returns V*M. This function is provided to hide the
  87. // preprocessor symbols in the GTEngine sample applications.
  88. template <typename Real>
  89. Vector3<Real> DoTransform(Matrix3x3<Real> const& M, Vector3<Real> const& V)
  90. {
  91. #if defined(GTE_USE_MAT_VEC)
  92. return M * V;
  93. #else
  94. return V * M;
  95. #endif
  96. }
  97. template <typename Real>
  98. Matrix3x3<Real> DoTransform(Matrix3x3<Real> const& A, Matrix3x3<Real> const& B)
  99. {
  100. #if defined(GTE_USE_MAT_VEC)
  101. return A * B;
  102. #else
  103. return B * A;
  104. #endif
  105. }
  106. // For GTE_USE_MAT_VEC, the columns of an invertible matrix form a basis
  107. // for the range of the matrix. For GTE_USE_VEC_MAT, the rows of an
  108. // invertible matrix form a basis for the range of the matrix. These
  109. // functions allow you to access the basis vectors. The caller is
  110. // responsible for ensuring that the matrix is invertible (although the
  111. // inverse is not calculated by these functions).
  112. template <typename Real>
  113. void SetBasis(Matrix3x3<Real>& M, int i, Vector3<Real> const& V)
  114. {
  115. #if defined(GTE_USE_MAT_VEC)
  116. return M.SetCol(i, V);
  117. #else
  118. return M.SetRow(i, V);
  119. #endif
  120. }
  121. template <typename Real>
  122. Vector3<Real> GetBasis(Matrix3x3<Real> const& M, int i)
  123. {
  124. #if defined(GTE_USE_MAT_VEC)
  125. return M.GetCol(i);
  126. #else
  127. return M.GetRow(i);
  128. #endif
  129. }
  130. }