2
0

Matrix2.h 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242
  1. // Copyright (c) 2008-2023 the Urho3D project
  2. // License: MIT
  3. #pragma once
  4. #include "../Math/Vector2.h"
  5. namespace Urho3D
  6. {
  7. /// 2x2 matrix for rotation and scaling.
  8. class URHO3D_API Matrix2
  9. {
  10. public:
  11. /// Construct an identity matrix.
  12. Matrix2() noexcept :
  13. m00_(1.0f),
  14. m01_(0.0f),
  15. m10_(0.0f),
  16. m11_(1.0f)
  17. {
  18. }
  19. /// Copy-construct from another matrix.
  20. Matrix2(const Matrix2& matrix) noexcept = default;
  21. /// Construct from values.
  22. Matrix2(float v00, float v01,
  23. float v10, float v11) noexcept :
  24. m00_(v00),
  25. m01_(v01),
  26. m10_(v10),
  27. m11_(v11)
  28. {
  29. }
  30. /// Construct from a float array.
  31. explicit Matrix2(const float* data) noexcept :
  32. m00_(data[0]),
  33. m01_(data[1]),
  34. m10_(data[2]),
  35. m11_(data[3])
  36. {
  37. }
  38. /// Assign from another matrix.
  39. Matrix2& operator =(const Matrix2& rhs) noexcept = default;
  40. /// Test for equality with another matrix without epsilon.
  41. bool operator ==(const Matrix2& rhs) const
  42. {
  43. const float* leftData = Data();
  44. const float* rightData = rhs.Data();
  45. for (unsigned i = 0; i != 4; ++i)
  46. {
  47. if (leftData[i] != rightData[i])
  48. return false;
  49. }
  50. return true;
  51. }
  52. /// Test for inequality with another matrix without epsilon.
  53. bool operator !=(const Matrix2& rhs) const { return !(*this == rhs); }
  54. /// Multiply a Vector2.
  55. Vector2 operator *(const Vector2& rhs) const
  56. {
  57. return Vector2(
  58. m00_ * rhs.x_ + m01_ * rhs.y_,
  59. m10_ * rhs.x_ + m11_ * rhs.y_
  60. );
  61. }
  62. /// Add a matrix.
  63. Matrix2 operator +(const Matrix2& rhs) const
  64. {
  65. return Matrix2(
  66. m00_ + rhs.m00_,
  67. m01_ + rhs.m01_,
  68. m10_ + rhs.m10_,
  69. m11_ + rhs.m11_
  70. );
  71. }
  72. /// Subtract a matrix.
  73. Matrix2 operator -(const Matrix2& rhs) const
  74. {
  75. return Matrix2(
  76. m00_ - rhs.m00_,
  77. m01_ - rhs.m01_,
  78. m10_ - rhs.m10_,
  79. m11_ - rhs.m11_
  80. );
  81. }
  82. /// Multiply with a scalar.
  83. Matrix2 operator *(float rhs) const
  84. {
  85. return Matrix2(
  86. m00_ * rhs,
  87. m01_ * rhs,
  88. m10_ * rhs,
  89. m11_ * rhs
  90. );
  91. }
  92. /// Multiply a matrix.
  93. Matrix2 operator *(const Matrix2& rhs) const
  94. {
  95. return Matrix2(
  96. m00_ * rhs.m00_ + m01_ * rhs.m10_,
  97. m00_ * rhs.m01_ + m01_ * rhs.m11_,
  98. m10_ * rhs.m00_ + m11_ * rhs.m10_,
  99. m10_ * rhs.m01_ + m11_ * rhs.m11_
  100. );
  101. }
  102. /// Set scaling elements.
  103. void SetScale(const Vector2& scale)
  104. {
  105. m00_ = scale.x_;
  106. m11_ = scale.y_;
  107. }
  108. /// Set uniform scaling elements.
  109. void SetScale(float scale)
  110. {
  111. m00_ = scale;
  112. m11_ = scale;
  113. }
  114. /// Return the scaling part.
  115. Vector2 Scale() const
  116. {
  117. return Vector2(
  118. sqrtf(m00_ * m00_ + m10_ * m10_),
  119. sqrtf(m01_ * m01_ + m11_ * m11_)
  120. );
  121. }
  122. /// Return transpose.
  123. Matrix2 Transpose() const
  124. {
  125. return Matrix2(
  126. m00_,
  127. m10_,
  128. m01_,
  129. m11_
  130. );
  131. }
  132. /// Return scaled by a vector.
  133. Matrix2 Scaled(const Vector2& scale) const
  134. {
  135. return Matrix2(
  136. m00_ * scale.x_,
  137. m01_ * scale.y_,
  138. m10_ * scale.x_,
  139. m11_ * scale.y_
  140. );
  141. }
  142. /// Test for equality with another matrix with epsilon.
  143. bool Equals(const Matrix2& rhs) const
  144. {
  145. const float* leftData = Data();
  146. const float* rightData = rhs.Data();
  147. for (unsigned i = 0; i != 4; ++i)
  148. {
  149. if (!Urho3D::Equals(leftData[i], rightData[i]))
  150. return false;
  151. }
  152. return true;
  153. }
  154. /// Return inverse.
  155. Matrix2 Inverse() const;
  156. /// Return float data.
  157. const float* Data() const { return &m00_; }
  158. /// Return whether any element is NaN.
  159. bool IsNaN() const
  160. {
  161. const float* data = Data();
  162. for (unsigned i = 0; i < 4; ++i)
  163. {
  164. if (Urho3D::IsNaN(data[i]))
  165. return true;
  166. }
  167. return false;
  168. }
  169. /// Return whether any element is Inf.
  170. bool IsInf() const
  171. {
  172. const float* data = Data();
  173. for (unsigned i = 0; i < 4; ++i)
  174. {
  175. if (Urho3D::IsInf(data[i]))
  176. return true;
  177. }
  178. return false;
  179. }
  180. /// Return as string.
  181. String ToString() const;
  182. float m00_;
  183. float m01_;
  184. float m10_;
  185. float m11_;
  186. /// Bulk transpose matrices.
  187. static void BulkTranspose(float* dest, const float* src, unsigned count)
  188. {
  189. for (unsigned i = 0; i < count; ++i)
  190. {
  191. dest[0] = src[0];
  192. dest[1] = src[2];
  193. dest[2] = src[1];
  194. dest[3] = src[3];
  195. dest += 4;
  196. src += 4;
  197. }
  198. }
  199. /// Zero matrix.
  200. static const Matrix2 ZERO;
  201. /// Identity matrix.
  202. static const Matrix2 IDENTITY;
  203. };
  204. /// Multiply a 2x2 matrix with a scalar.
  205. inline Matrix2 operator *(float lhs, const Matrix2& rhs) { return rhs * lhs; }
  206. }