Matrix2.h 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250
  1. //
  2. // Copyright (c) 2008-2017 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 Atomic
  25. {
  26. /// 2x2 matrix for rotation and scaling.
  27. class ATOMIC_API Matrix2
  28. {
  29. public:
  30. /// Construct an identity matrix.
  31. Matrix2() :
  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) :
  40. m00_(matrix.m00_),
  41. m01_(matrix.m01_),
  42. m10_(matrix.m10_),
  43. m11_(matrix.m11_)
  44. {
  45. }
  46. /// Construct from values.
  47. Matrix2(float v00, float v01,
  48. float v10, float v11) :
  49. m00_(v00),
  50. m01_(v01),
  51. m10_(v10),
  52. m11_(v11)
  53. {
  54. }
  55. /// Construct from a float array.
  56. explicit Matrix2(const float* data) :
  57. m00_(data[0]),
  58. m01_(data[1]),
  59. m10_(data[2]),
  60. m11_(data[3])
  61. {
  62. }
  63. /// Assign from another matrix.
  64. Matrix2& operator =(const Matrix2& rhs)
  65. {
  66. m00_ = rhs.m00_;
  67. m01_ = rhs.m01_;
  68. m10_ = rhs.m10_;
  69. m11_ = rhs.m11_;
  70. return *this;
  71. }
  72. /// Test for equality with another matrix without epsilon.
  73. bool operator ==(const Matrix2& rhs) const
  74. {
  75. const float* leftData = Data();
  76. const float* rightData = rhs.Data();
  77. for (unsigned i = 0; i != 4; ++i)
  78. {
  79. if (leftData[i] != rightData[i])
  80. return false;
  81. }
  82. return true;
  83. }
  84. /// Test for inequality with another matrix without epsilon.
  85. bool operator !=(const Matrix2& rhs) const { return !(*this == rhs); }
  86. /// Multiply a Vector2.
  87. Vector2 operator *(const Vector2& rhs) const
  88. {
  89. return Vector2(
  90. m00_ * rhs.x_ + m01_ * rhs.y_,
  91. m10_ * rhs.x_ + m11_ * rhs.y_
  92. );
  93. }
  94. /// Add a matrix.
  95. Matrix2 operator +(const Matrix2& rhs) const
  96. {
  97. return Matrix2(
  98. m00_ + rhs.m00_,
  99. m01_ + rhs.m01_,
  100. m10_ + rhs.m10_,
  101. m11_ + rhs.m11_
  102. );
  103. }
  104. /// Subtract a matrix.
  105. Matrix2 operator -(const Matrix2& rhs) const
  106. {
  107. return Matrix2(
  108. m00_ - rhs.m00_,
  109. m01_ - rhs.m01_,
  110. m10_ - rhs.m10_,
  111. m11_ - rhs.m11_
  112. );
  113. }
  114. /// Multiply with a scalar.
  115. Matrix2 operator *(float rhs) const
  116. {
  117. return Matrix2(
  118. m00_ * rhs,
  119. m01_ * rhs,
  120. m10_ * rhs,
  121. m11_ * rhs
  122. );
  123. }
  124. /// Multiply a matrix.
  125. Matrix2 operator *(const Matrix2& rhs) const
  126. {
  127. return Matrix2(
  128. m00_ * rhs.m00_ + m01_ * rhs.m10_,
  129. m00_ * rhs.m01_ + m01_ * rhs.m11_,
  130. m10_ * rhs.m00_ + m11_ * rhs.m10_,
  131. m10_ * rhs.m01_ + m11_ * rhs.m11_
  132. );
  133. }
  134. /// Set scaling elements.
  135. void SetScale(const Vector2& scale)
  136. {
  137. m00_ = scale.x_;
  138. m11_ = scale.y_;
  139. }
  140. /// Set uniform scaling elements.
  141. void SetScale(float scale)
  142. {
  143. m00_ = scale;
  144. m11_ = scale;
  145. }
  146. /// Return the scaling part.
  147. Vector2 Scale() const
  148. {
  149. return Vector2(
  150. sqrtf(m00_ * m00_ + m10_ * m10_),
  151. sqrtf(m01_ * m01_ + m11_ * m11_)
  152. );
  153. }
  154. /// Return transpose.
  155. Matrix2 Transpose() const
  156. {
  157. return Matrix2(
  158. m00_,
  159. m10_,
  160. m01_,
  161. m11_
  162. );
  163. }
  164. /// Return scaled by a vector.
  165. Matrix2 Scaled(const Vector2& scale) const
  166. {
  167. return Matrix2(
  168. m00_ * scale.x_,
  169. m01_ * scale.y_,
  170. m10_ * scale.x_,
  171. m11_ * scale.y_
  172. );
  173. }
  174. /// Test for equality with another matrix with epsilon.
  175. bool Equals(const Matrix2& rhs) const
  176. {
  177. const float* leftData = Data();
  178. const float* rightData = rhs.Data();
  179. for (unsigned i = 0; i != 4; ++i)
  180. {
  181. if (!Atomic::Equals(leftData[i], rightData[i]))
  182. return false;
  183. }
  184. return true;
  185. }
  186. /// Return inverse.
  187. Matrix2 Inverse() const;
  188. /// Return float data.
  189. const float* Data() const { return &m00_; }
  190. /// Return as string.
  191. String ToString() const;
  192. float m00_;
  193. float m01_;
  194. float m10_;
  195. float m11_;
  196. /// Bulk transpose matrices.
  197. static void BulkTranspose(float* dest, const float* src, unsigned count)
  198. {
  199. for (unsigned i = 0; i < count; ++i)
  200. {
  201. dest[0] = src[0];
  202. dest[1] = src[2];
  203. dest[2] = src[1];
  204. dest[3] = src[3];
  205. dest += 4;
  206. src += 4;
  207. }
  208. }
  209. /// Zero matrix.
  210. static const Matrix2 ZERO;
  211. /// Identity matrix.
  212. static const Matrix2 IDENTITY;
  213. };
  214. /// Multiply a 2x2 matrix with a scalar.
  215. inline Matrix2 operator *(float lhs, const Matrix2& rhs) { return rhs * lhs; }
  216. }