matrix3_f.cc 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180
  1. // Copyright (c) 2013 The Chromium Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style license that can be
  3. // found in the LICENSE file.
  4. #include "ui/gfx/geometry/matrix3_f.h"
  5. #include <string.h>
  6. #include <algorithm>
  7. #include <cmath>
  8. #include <limits>
  9. #include "base/numerics/math_constants.h"
  10. #include "base/strings/stringprintf.h"
  11. namespace {
  12. // This is only to make accessing indices self-explanatory.
  13. enum MatrixCoordinates {
  14. M00,
  15. M01,
  16. M02,
  17. M10,
  18. M11,
  19. M12,
  20. M20,
  21. M21,
  22. M22,
  23. M_END
  24. };
  25. template<typename T>
  26. double Determinant3x3(T data[M_END]) {
  27. // This routine is separated from the Matrix3F::Determinant because in
  28. // computing inverse we do want higher precision afforded by the explicit
  29. // use of 'double'.
  30. return
  31. static_cast<double>(data[M00]) * (
  32. static_cast<double>(data[M11]) * data[M22] -
  33. static_cast<double>(data[M12]) * data[M21]) +
  34. static_cast<double>(data[M01]) * (
  35. static_cast<double>(data[M12]) * data[M20] -
  36. static_cast<double>(data[M10]) * data[M22]) +
  37. static_cast<double>(data[M02]) * (
  38. static_cast<double>(data[M10]) * data[M21] -
  39. static_cast<double>(data[M11]) * data[M20]);
  40. }
  41. } // namespace
  42. namespace gfx {
  43. Matrix3F::Matrix3F() {
  44. }
  45. Matrix3F::~Matrix3F() {
  46. }
  47. // static
  48. Matrix3F Matrix3F::Zeros() {
  49. Matrix3F matrix;
  50. matrix.set(0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f);
  51. return matrix;
  52. }
  53. // static
  54. Matrix3F Matrix3F::Ones() {
  55. Matrix3F matrix;
  56. matrix.set(1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f);
  57. return matrix;
  58. }
  59. // static
  60. Matrix3F Matrix3F::Identity() {
  61. Matrix3F matrix;
  62. matrix.set(1.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 1.0f);
  63. return matrix;
  64. }
  65. // static
  66. Matrix3F Matrix3F::FromOuterProduct(const Vector3dF& a, const Vector3dF& bt) {
  67. Matrix3F matrix;
  68. matrix.set(a.x() * bt.x(), a.x() * bt.y(), a.x() * bt.z(),
  69. a.y() * bt.x(), a.y() * bt.y(), a.y() * bt.z(),
  70. a.z() * bt.x(), a.z() * bt.y(), a.z() * bt.z());
  71. return matrix;
  72. }
  73. bool Matrix3F::IsEqual(const Matrix3F& rhs) const {
  74. return 0 == memcmp(data_, rhs.data_, sizeof(data_));
  75. }
  76. bool Matrix3F::IsNear(const Matrix3F& rhs, float precision) const {
  77. DCHECK(precision >= 0);
  78. for (int i = 0; i < M_END; ++i) {
  79. if (std::abs(data_[i] - rhs.data_[i]) > precision)
  80. return false;
  81. }
  82. return true;
  83. }
  84. Matrix3F Matrix3F::Add(const Matrix3F& rhs) const {
  85. Matrix3F result;
  86. for (int i = 0; i < M_END; ++i)
  87. result.data_[i] = data_[i] + rhs.data_[i];
  88. return result;
  89. }
  90. Matrix3F Matrix3F::Subtract(const Matrix3F& rhs) const {
  91. Matrix3F result;
  92. for (int i = 0; i < M_END; ++i)
  93. result.data_[i] = data_[i] - rhs.data_[i];
  94. return result;
  95. }
  96. Matrix3F Matrix3F::Inverse() const {
  97. Matrix3F inverse = Matrix3F::Zeros();
  98. double determinant = Determinant3x3(data_);
  99. if (std::numeric_limits<float>::epsilon() > std::abs(determinant))
  100. return inverse; // Singular matrix. Return Zeros().
  101. inverse.set(
  102. static_cast<float>((data_[M11] * data_[M22] - data_[M12] * data_[M21]) /
  103. determinant),
  104. static_cast<float>((data_[M02] * data_[M21] - data_[M01] * data_[M22]) /
  105. determinant),
  106. static_cast<float>((data_[M01] * data_[M12] - data_[M02] * data_[M11]) /
  107. determinant),
  108. static_cast<float>((data_[M12] * data_[M20] - data_[M10] * data_[M22]) /
  109. determinant),
  110. static_cast<float>((data_[M00] * data_[M22] - data_[M02] * data_[M20]) /
  111. determinant),
  112. static_cast<float>((data_[M02] * data_[M10] - data_[M00] * data_[M12]) /
  113. determinant),
  114. static_cast<float>((data_[M10] * data_[M21] - data_[M11] * data_[M20]) /
  115. determinant),
  116. static_cast<float>((data_[M01] * data_[M20] - data_[M00] * data_[M21]) /
  117. determinant),
  118. static_cast<float>((data_[M00] * data_[M11] - data_[M01] * data_[M10]) /
  119. determinant));
  120. return inverse;
  121. }
  122. Matrix3F Matrix3F::Transpose() const {
  123. Matrix3F transpose;
  124. transpose.set(data_[M00], data_[M10], data_[M20], data_[M01], data_[M11],
  125. data_[M21], data_[M02], data_[M12], data_[M22]);
  126. return transpose;
  127. }
  128. float Matrix3F::Determinant() const {
  129. return static_cast<float>(Determinant3x3(data_));
  130. }
  131. Matrix3F MatrixProduct(const Matrix3F& lhs, const Matrix3F& rhs) {
  132. Matrix3F result = Matrix3F::Zeros();
  133. for (int i = 0; i < 3; i++) {
  134. for (int j = 0; j < 3; j++) {
  135. result.set(i, j, DotProduct(lhs.get_row(i), rhs.get_column(j)));
  136. }
  137. }
  138. return result;
  139. }
  140. Vector3dF MatrixProduct(const Matrix3F& lhs, const Vector3dF& rhs) {
  141. return Vector3dF(DotProduct(lhs.get_row(0), rhs),
  142. DotProduct(lhs.get_row(1), rhs),
  143. DotProduct(lhs.get_row(2), rhs));
  144. }
  145. std::string Matrix3F::ToString() const {
  146. return base::StringPrintf(
  147. "[[%+0.4f, %+0.4f, %+0.4f],"
  148. " [%+0.4f, %+0.4f, %+0.4f],"
  149. " [%+0.4f, %+0.4f, %+0.4f]]",
  150. data_[M00], data_[M01], data_[M02], data_[M10], data_[M11], data_[M12],
  151. data_[M20], data_[M21], data_[M22]);
  152. }
  153. } // namespace gfx