Matrix2.h 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261
  1. //
  2. // Copyright (c) 2008-2020 the Urho3D project.
  3. //
  4. // Permission is hereby granted, free of charge, to any person obtaining a copy
  5. // of this software and associated documentation files (the "Software"), to deal
  6. // in the Software without restriction, including without limitation the rights
  7. // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  8. // copies of the Software, and to permit persons to whom the Software is
  9. // furnished to do so, subject to the following conditions:
  10. //
  11. // The above copyright notice and this permission notice shall be included in
  12. // all copies or substantial portions of the Software.
  13. //
  14. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  15. // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  16. // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  17. // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  18. // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  19. // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  20. // THE SOFTWARE.
  21. //
  22. #pragma once
  23. #include "../Math/Vector2.h"
  24. namespace Urho3D
  25. {
  26. /// 2x2 matrix for rotation and scaling.
  27. class URHO3D_API Matrix2
  28. {
  29. public:
  30. /// Construct an identity matrix.
  31. Matrix2() noexcept :
  32. m00_(1.0f),
  33. m01_(0.0f),
  34. m10_(0.0f),
  35. m11_(1.0f)
  36. {
  37. }
  38. /// Copy-construct from another matrix.
  39. Matrix2(const Matrix2& matrix) noexcept = default;
  40. /// Construct from values.
  41. Matrix2(float v00, float v01,
  42. float v10, float v11) noexcept :
  43. m00_(v00),
  44. m01_(v01),
  45. m10_(v10),
  46. m11_(v11)
  47. {
  48. }
  49. /// Construct from a float array.
  50. explicit Matrix2(const float* data) noexcept :
  51. m00_(data[0]),
  52. m01_(data[1]),
  53. m10_(data[2]),
  54. m11_(data[3])
  55. {
  56. }
  57. /// Assign from another matrix.
  58. Matrix2& operator =(const Matrix2& rhs) noexcept = default;
  59. /// Test for equality with another matrix without epsilon.
  60. bool operator ==(const Matrix2& rhs) const
  61. {
  62. const float* leftData = Data();
  63. const float* rightData = rhs.Data();
  64. for (unsigned i = 0; i != 4; ++i)
  65. {
  66. if (leftData[i] != rightData[i])
  67. return false;
  68. }
  69. return true;
  70. }
  71. /// Test for inequality with another matrix without epsilon.
  72. bool operator !=(const Matrix2& rhs) const { return !(*this == rhs); }
  73. /// Multiply a Vector2.
  74. Vector2 operator *(const Vector2& rhs) const
  75. {
  76. return Vector2(
  77. m00_ * rhs.x_ + m01_ * rhs.y_,
  78. m10_ * rhs.x_ + m11_ * rhs.y_
  79. );
  80. }
  81. /// Add a matrix.
  82. Matrix2 operator +(const Matrix2& rhs) const
  83. {
  84. return Matrix2(
  85. m00_ + rhs.m00_,
  86. m01_ + rhs.m01_,
  87. m10_ + rhs.m10_,
  88. m11_ + rhs.m11_
  89. );
  90. }
  91. /// Subtract a matrix.
  92. Matrix2 operator -(const Matrix2& rhs) const
  93. {
  94. return Matrix2(
  95. m00_ - rhs.m00_,
  96. m01_ - rhs.m01_,
  97. m10_ - rhs.m10_,
  98. m11_ - rhs.m11_
  99. );
  100. }
  101. /// Multiply with a scalar.
  102. Matrix2 operator *(float rhs) const
  103. {
  104. return Matrix2(
  105. m00_ * rhs,
  106. m01_ * rhs,
  107. m10_ * rhs,
  108. m11_ * rhs
  109. );
  110. }
  111. /// Multiply a matrix.
  112. Matrix2 operator *(const Matrix2& rhs) const
  113. {
  114. return Matrix2(
  115. m00_ * rhs.m00_ + m01_ * rhs.m10_,
  116. m00_ * rhs.m01_ + m01_ * rhs.m11_,
  117. m10_ * rhs.m00_ + m11_ * rhs.m10_,
  118. m10_ * rhs.m01_ + m11_ * rhs.m11_
  119. );
  120. }
  121. /// Set scaling elements.
  122. void SetScale(const Vector2& scale)
  123. {
  124. m00_ = scale.x_;
  125. m11_ = scale.y_;
  126. }
  127. /// Set uniform scaling elements.
  128. void SetScale(float scale)
  129. {
  130. m00_ = scale;
  131. m11_ = scale;
  132. }
  133. /// Return the scaling part.
  134. Vector2 Scale() const
  135. {
  136. return Vector2(
  137. sqrtf(m00_ * m00_ + m10_ * m10_),
  138. sqrtf(m01_ * m01_ + m11_ * m11_)
  139. );
  140. }
  141. /// Return transpose.
  142. Matrix2 Transpose() const
  143. {
  144. return Matrix2(
  145. m00_,
  146. m10_,
  147. m01_,
  148. m11_
  149. );
  150. }
  151. /// Return scaled by a vector.
  152. Matrix2 Scaled(const Vector2& scale) const
  153. {
  154. return Matrix2(
  155. m00_ * scale.x_,
  156. m01_ * scale.y_,
  157. m10_ * scale.x_,
  158. m11_ * scale.y_
  159. );
  160. }
  161. /// Test for equality with another matrix with epsilon.
  162. bool Equals(const Matrix2& rhs) const
  163. {
  164. const float* leftData = Data();
  165. const float* rightData = rhs.Data();
  166. for (unsigned i = 0; i != 4; ++i)
  167. {
  168. if (!Urho3D::Equals(leftData[i], rightData[i]))
  169. return false;
  170. }
  171. return true;
  172. }
  173. /// Return inverse.
  174. Matrix2 Inverse() const;
  175. /// Return float data.
  176. const float* Data() const { return &m00_; }
  177. /// Return whether any element is NaN.
  178. bool IsNaN() const
  179. {
  180. const float* data = Data();
  181. for (unsigned i = 0; i < 4; ++i)
  182. {
  183. if (Urho3D::IsNaN(data[i]))
  184. return true;
  185. }
  186. return false;
  187. }
  188. /// Return whether any element is Inf.
  189. bool IsInf() const
  190. {
  191. const float* data = Data();
  192. for (unsigned i = 0; i < 4; ++i)
  193. {
  194. if (Urho3D::IsInf(data[i]))
  195. return true;
  196. }
  197. return false;
  198. }
  199. /// Return as string.
  200. String ToString() const;
  201. float m00_;
  202. float m01_;
  203. float m10_;
  204. float m11_;
  205. /// Bulk transpose matrices.
  206. static void BulkTranspose(float* dest, const float* src, unsigned count)
  207. {
  208. for (unsigned i = 0; i < count; ++i)
  209. {
  210. dest[0] = src[0];
  211. dest[1] = src[2];
  212. dest[2] = src[1];
  213. dest[3] = src[3];
  214. dest += 4;
  215. src += 4;
  216. }
  217. }
  218. /// Zero matrix.
  219. static const Matrix2 ZERO;
  220. /// Identity matrix.
  221. static const Matrix2 IDENTITY;
  222. };
  223. /// Multiply a 2x2 matrix with a scalar.
  224. inline Matrix2 operator *(float lhs, const Matrix2& rhs) { return rhs * lhs; }
  225. }