Vector2.h 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434
  1. // Copyright (c) 2008-2023 the Urho3D project
  2. // License: MIT
  3. #pragma once
  4. #include "../Container/Str.h"
  5. #include "../Math/MathDefs.h"
  6. namespace Urho3D
  7. {
  8. /// Two-dimensional vector with integer values.
  9. class URHO3D_API IntVector2
  10. {
  11. public:
  12. /// Construct a zero vector.
  13. IntVector2() noexcept :
  14. x_(0),
  15. y_(0)
  16. {
  17. }
  18. /// Construct from coordinates.
  19. IntVector2(int x, int y) noexcept :
  20. x_(x),
  21. y_(y)
  22. {
  23. }
  24. /// Construct from an int array.
  25. explicit IntVector2(const int* data) noexcept :
  26. x_(data[0]),
  27. y_(data[1])
  28. {
  29. }
  30. /// Construct from an float array.
  31. explicit IntVector2(const float* data) :
  32. x_((int)data[0]),
  33. y_((int)data[1])
  34. {
  35. }
  36. /// Copy-construct from another vector.
  37. IntVector2(const IntVector2& rhs) noexcept = default;
  38. /// Assign from another vector.
  39. IntVector2& operator =(const IntVector2& rhs) noexcept = default;
  40. /// Test for equality with another vector.
  41. bool operator ==(const IntVector2& rhs) const { return x_ == rhs.x_ && y_ == rhs.y_; }
  42. /// Test for inequality with another vector.
  43. bool operator !=(const IntVector2& rhs) const { return x_ != rhs.x_ || y_ != rhs.y_; }
  44. /// Add a vector.
  45. IntVector2 operator +(const IntVector2& rhs) const { return IntVector2(x_ + rhs.x_, y_ + rhs.y_); }
  46. /// Return negation.
  47. IntVector2 operator -() const { return IntVector2(-x_, -y_); }
  48. /// Subtract a vector.
  49. IntVector2 operator -(const IntVector2& rhs) const { return IntVector2(x_ - rhs.x_, y_ - rhs.y_); }
  50. /// Multiply with a scalar.
  51. IntVector2 operator *(int rhs) const { return IntVector2(x_ * rhs, y_ * rhs); }
  52. /// Multiply with a vector.
  53. IntVector2 operator *(const IntVector2& rhs) const { return IntVector2(x_ * rhs.x_, y_ * rhs.y_); }
  54. /// Divide by a scalar.
  55. IntVector2 operator /(int rhs) const { return IntVector2(x_ / rhs, y_ / rhs); }
  56. /// Divide by a vector.
  57. IntVector2 operator /(const IntVector2& rhs) const { return IntVector2(x_ / rhs.x_, y_ / rhs.y_); }
  58. /// Add-assign a vector.
  59. IntVector2& operator +=(const IntVector2& rhs)
  60. {
  61. x_ += rhs.x_;
  62. y_ += rhs.y_;
  63. return *this;
  64. }
  65. /// Subtract-assign a vector.
  66. IntVector2& operator -=(const IntVector2& rhs)
  67. {
  68. x_ -= rhs.x_;
  69. y_ -= rhs.y_;
  70. return *this;
  71. }
  72. /// Multiply-assign a scalar.
  73. IntVector2& operator *=(int rhs)
  74. {
  75. x_ *= rhs;
  76. y_ *= rhs;
  77. return *this;
  78. }
  79. /// Multiply-assign a vector.
  80. IntVector2& operator *=(const IntVector2& rhs)
  81. {
  82. x_ *= rhs.x_;
  83. y_ *= rhs.y_;
  84. return *this;
  85. }
  86. /// Divide-assign a scalar.
  87. IntVector2& operator /=(int rhs)
  88. {
  89. x_ /= rhs;
  90. y_ /= rhs;
  91. return *this;
  92. }
  93. /// Divide-assign a vector.
  94. IntVector2& operator /=(const IntVector2& rhs)
  95. {
  96. x_ /= rhs.x_;
  97. y_ /= rhs.y_;
  98. return *this;
  99. }
  100. /// Return integer data.
  101. const int* Data() const { return &x_; }
  102. /// Return as string.
  103. String ToString() const;
  104. /// Return hash value for HashSet & HashMap.
  105. hash32 ToHash() const { return (hash32)x_ * 31 + (hash32)y_; }
  106. /// Return length.
  107. float Length() const { return sqrtf((float)(x_ * x_ + y_ * y_)); }
  108. /// X coordinate.
  109. int x_;
  110. /// Y coordinate.
  111. int y_;
  112. /// Zero vector.
  113. static const IntVector2 ZERO;
  114. /// (-1,0) vector.
  115. static const IntVector2 LEFT;
  116. /// (1,0) vector.
  117. static const IntVector2 RIGHT;
  118. /// (0,1) vector.
  119. static const IntVector2 UP;
  120. /// (0,-1) vector.
  121. static const IntVector2 DOWN;
  122. /// (1,1) vector.
  123. static const IntVector2 ONE;
  124. };
  125. /// Two-dimensional vector.
  126. class URHO3D_API Vector2
  127. {
  128. public:
  129. /// Construct a zero vector.
  130. Vector2() noexcept :
  131. x_(0.0f),
  132. y_(0.0f)
  133. {
  134. }
  135. /// Copy-construct from another vector.
  136. Vector2(const Vector2& vector) noexcept = default;
  137. /// Construct from an IntVector2.
  138. explicit Vector2(const IntVector2& vector) noexcept :
  139. x_((float)vector.x_),
  140. y_((float)vector.y_)
  141. {
  142. }
  143. /// Construct from coordinates.
  144. Vector2(float x, float y) noexcept :
  145. x_(x),
  146. y_(y)
  147. {
  148. }
  149. /// Construct from int coordinates.
  150. Vector2(i32 x, i32 y) noexcept :
  151. x_((float)x),
  152. y_((float)y)
  153. {
  154. }
  155. /// Construct from a float array.
  156. explicit Vector2(const float* data) noexcept :
  157. x_(data[0]),
  158. y_(data[1])
  159. {
  160. }
  161. /// Assign from another vector.
  162. Vector2& operator =(const Vector2& rhs) noexcept = default;
  163. /// Test for equality with another vector without epsilon.
  164. bool operator ==(const Vector2& rhs) const { return x_ == rhs.x_ && y_ == rhs.y_; }
  165. /// Test for inequality with another vector without epsilon.
  166. bool operator !=(const Vector2& rhs) const { return x_ != rhs.x_ || y_ != rhs.y_; }
  167. /// Add a vector.
  168. Vector2 operator +(const Vector2& rhs) const { return Vector2(x_ + rhs.x_, y_ + rhs.y_); }
  169. /// Return negation.
  170. Vector2 operator -() const { return Vector2(-x_, -y_); }
  171. /// Subtract a vector.
  172. Vector2 operator -(const Vector2& rhs) const { return Vector2(x_ - rhs.x_, y_ - rhs.y_); }
  173. /// Multiply with a scalar.
  174. Vector2 operator *(float rhs) const { return Vector2(x_ * rhs, y_ * rhs); }
  175. /// Multiply with a vector.
  176. Vector2 operator *(const Vector2& rhs) const { return Vector2(x_ * rhs.x_, y_ * rhs.y_); }
  177. /// Divide by a scalar.
  178. Vector2 operator /(float rhs) const { return Vector2(x_ / rhs, y_ / rhs); }
  179. /// Divide by a vector.
  180. Vector2 operator /(const Vector2& rhs) const { return Vector2(x_ / rhs.x_, y_ / rhs.y_); }
  181. /// Add-assign a vector.
  182. Vector2& operator +=(const Vector2& rhs)
  183. {
  184. x_ += rhs.x_;
  185. y_ += rhs.y_;
  186. return *this;
  187. }
  188. /// Subtract-assign a vector.
  189. Vector2& operator -=(const Vector2& rhs)
  190. {
  191. x_ -= rhs.x_;
  192. y_ -= rhs.y_;
  193. return *this;
  194. }
  195. /// Multiply-assign a scalar.
  196. Vector2& operator *=(float rhs)
  197. {
  198. x_ *= rhs;
  199. y_ *= rhs;
  200. return *this;
  201. }
  202. /// Multiply-assign a vector.
  203. Vector2& operator *=(const Vector2& rhs)
  204. {
  205. x_ *= rhs.x_;
  206. y_ *= rhs.y_;
  207. return *this;
  208. }
  209. /// Divide-assign a scalar.
  210. Vector2& operator /=(float rhs)
  211. {
  212. float invRhs = 1.0f / rhs;
  213. x_ *= invRhs;
  214. y_ *= invRhs;
  215. return *this;
  216. }
  217. /// Divide-assign a vector.
  218. Vector2& operator /=(const Vector2& rhs)
  219. {
  220. x_ /= rhs.x_;
  221. y_ /= rhs.y_;
  222. return *this;
  223. }
  224. /// Normalize to unit length.
  225. void Normalize()
  226. {
  227. float lenSquared = LengthSquared();
  228. if (!Urho3D::Equals(lenSquared, 1.0f) && lenSquared > 0.0f)
  229. {
  230. float invLen = 1.0f / sqrtf(lenSquared);
  231. x_ *= invLen;
  232. y_ *= invLen;
  233. }
  234. }
  235. /// Return length.
  236. /// @property
  237. float Length() const { return sqrtf(x_ * x_ + y_ * y_); }
  238. /// Return squared length.
  239. /// @property
  240. float LengthSquared() const { return x_ * x_ + y_ * y_; }
  241. /// Calculate dot product.
  242. float DotProduct(const Vector2& rhs) const { return x_ * rhs.x_ + y_ * rhs.y_; }
  243. /// Calculate absolute dot product.
  244. float AbsDotProduct(const Vector2& rhs) const { return Urho3D::Abs(x_ * rhs.x_) + Urho3D::Abs(y_ * rhs.y_); }
  245. /// Project vector onto axis.
  246. float ProjectOntoAxis(const Vector2& axis) const { return DotProduct(axis.Normalized()); }
  247. /// Returns the angle between this vector and another vector in degrees.
  248. float Angle(const Vector2& rhs) const { return Urho3D::Acos(DotProduct(rhs) / (Length() * rhs.Length())); }
  249. /// Return absolute vector.
  250. Vector2 Abs() const { return Vector2(Urho3D::Abs(x_), Urho3D::Abs(y_)); }
  251. /// Linear interpolation with another vector.
  252. Vector2 Lerp(const Vector2& rhs, float t) const { return *this * (1.0f - t) + rhs * t; }
  253. /// Test for equality with another vector with epsilon.
  254. bool Equals(const Vector2& rhs) const { return Urho3D::Equals(x_, rhs.x_) && Urho3D::Equals(y_, rhs.y_); }
  255. /// Return whether any component is NaN.
  256. bool IsNaN() const { return Urho3D::IsNaN(x_) || Urho3D::IsNaN(y_); }
  257. /// Return whether any component is Inf.
  258. bool IsInf() const { return Urho3D::IsInf(x_) || Urho3D::IsInf(y_); }
  259. /// Return normalized to unit length.
  260. Vector2 Normalized() const
  261. {
  262. const float lenSquared = LengthSquared();
  263. if (!Urho3D::Equals(lenSquared, 1.0f) && lenSquared > 0.0f)
  264. {
  265. const float invLen = 1.0f / sqrtf(lenSquared);
  266. return *this * invLen;
  267. }
  268. else
  269. return *this;
  270. }
  271. /// Return normalized to unit length or zero if length is too small.
  272. Vector2 NormalizedOrDefault(const Vector2& defaultValue = Vector2::ZERO, float eps = M_LARGE_EPSILON) const
  273. {
  274. const float lenSquared = LengthSquared();
  275. if (lenSquared < eps * eps)
  276. return defaultValue;
  277. return *this / sqrtf(lenSquared);
  278. }
  279. /// Return normalized vector with length in given range.
  280. Vector2 ReNormalized(float minLength, float maxLength, const Vector2& defaultValue = Vector2::ZERO, float eps = M_LARGE_EPSILON) const
  281. {
  282. const float lenSquared = LengthSquared();
  283. if (lenSquared < eps * eps)
  284. return defaultValue;
  285. const float len = sqrtf(lenSquared);
  286. const float newLen = Clamp(len, minLength, maxLength);
  287. return *this * (newLen / len);
  288. }
  289. /// Return float data.
  290. const float* Data() const { return &x_; }
  291. /// Return as string.
  292. String ToString() const;
  293. /// X coordinate.
  294. float x_;
  295. /// Y coordinate.
  296. float y_;
  297. /// Zero vector.
  298. static const Vector2 ZERO;
  299. /// (-1,0) vector.
  300. static const Vector2 LEFT;
  301. /// (1,0) vector.
  302. static const Vector2 RIGHT;
  303. /// (0,1) vector.
  304. static const Vector2 UP;
  305. /// (0,-1) vector.
  306. static const Vector2 DOWN;
  307. /// (1,1) vector.
  308. static const Vector2 ONE;
  309. };
  310. /// Multiply Vector2 with a scalar.
  311. inline Vector2 operator *(float lhs, const Vector2& rhs) { return rhs * lhs; }
  312. /// Multiply IntVector2 with a scalar.
  313. inline IntVector2 operator *(int lhs, const IntVector2& rhs) { return rhs * lhs; }
  314. /// Per-component linear interpolation between two 2-vectors.
  315. inline Vector2 VectorLerp(const Vector2& lhs, const Vector2& rhs, const Vector2& t) { return lhs + (rhs - lhs) * t; }
  316. /// Per-component min of two 2-vectors.
  317. inline Vector2 VectorMin(const Vector2& lhs, const Vector2& rhs) { return Vector2(Min(lhs.x_, rhs.x_), Min(lhs.y_, rhs.y_)); }
  318. /// Per-component max of two 2-vectors.
  319. inline Vector2 VectorMax(const Vector2& lhs, const Vector2& rhs) { return Vector2(Max(lhs.x_, rhs.x_), Max(lhs.y_, rhs.y_)); }
  320. /// Per-component floor of 2-vector.
  321. inline Vector2 VectorFloor(const Vector2& vec) { return Vector2(Floor(vec.x_), Floor(vec.y_)); }
  322. /// Per-component round of 2-vector.
  323. inline Vector2 VectorRound(const Vector2& vec) { return Vector2(Round(vec.x_), Round(vec.y_)); }
  324. /// Per-component ceil of 2-vector.
  325. inline Vector2 VectorCeil(const Vector2& vec) { return Vector2(Ceil(vec.x_), Ceil(vec.y_)); }
  326. /// Per-component absolute value of 2-vector.
  327. inline Vector2 VectorAbs(const Vector2& vec) { return Vector2(Abs(vec.x_), Abs(vec.y_)); }
  328. /// Per-component floor of 2-vector. Returns IntVector2.
  329. inline IntVector2 VectorFloorToInt(const Vector2& vec) { return IntVector2(FloorToInt(vec.x_), FloorToInt(vec.y_)); }
  330. /// Per-component round of 2-vector. Returns IntVector2.
  331. inline IntVector2 VectorRoundToInt(const Vector2& vec) { return IntVector2(RoundToInt(vec.x_), RoundToInt(vec.y_)); }
  332. /// Per-component ceil of 2-vector. Returns IntVector2.
  333. inline IntVector2 VectorCeilToInt(const Vector2& vec) { return IntVector2(CeilToInt(vec.x_), CeilToInt(vec.y_)); }
  334. /// Per-component min of two 2-vectors.
  335. inline IntVector2 VectorMin(const IntVector2& lhs, const IntVector2& rhs) { return IntVector2(Min(lhs.x_, rhs.x_), Min(lhs.y_, rhs.y_)); }
  336. /// Per-component max of two 2-vectors.
  337. inline IntVector2 VectorMax(const IntVector2& lhs, const IntVector2& rhs) { return IntVector2(Max(lhs.x_, rhs.x_), Max(lhs.y_, rhs.y_)); }
  338. /// Per-component absolute value of integer 2-vector.
  339. inline IntVector2 VectorAbs(const IntVector2& vec) { return IntVector2(Abs(vec.x_), Abs(vec.y_)); }
  340. /// Return a random value from [0, 1) from 2-vector seed.
  341. /// http://stackoverflow.com/questions/12964279/whats-the-origin-of-this-glsl-rand-one-liner
  342. inline float StableRandom(const Vector2& seed) { return Fract(Sin(seed.DotProduct(Vector2(12.9898f, 78.233f)) * M_RADTODEG) * 43758.5453f); }
  343. /// Return a random value from [0, 1) from scalar seed.
  344. inline float StableRandom(float seed) { return StableRandom(Vector2(seed, seed)); }
  345. }