BsVector2.h 8.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408
  1. #pragma once
  2. #include "BsPrerequisitesUtil.h"
  3. #include "BsMath.h"
  4. namespace BansheeEngine
  5. {
  6. /**
  7. * @brief A two dimensional vector.
  8. */
  9. class BS_UTILITY_EXPORT Vector2
  10. {
  11. public:
  12. float x, y;
  13. public:
  14. Vector2()
  15. :x(0.0f), y(0.0f)
  16. { }
  17. Vector2(float x, float y)
  18. :x(x), y(y)
  19. { }
  20. /**
  21. * @brief Exchange the contents of this vector with another.
  22. */
  23. void swap(Vector2& other)
  24. {
  25. std::swap(x, other.x);
  26. std::swap(y, other.y);
  27. }
  28. float operator[] (UINT32 i) const
  29. {
  30. assert(i < 2);
  31. return *(&x+i);
  32. }
  33. float& operator[] (UINT32 i)
  34. {
  35. assert(i < 2);
  36. return *(&x+i);
  37. }
  38. /**
  39. * @brief Pointer accessor for direct copying.
  40. */
  41. float* ptr()
  42. {
  43. return &x;
  44. }
  45. /**
  46. * @brief Pointer accessor for direct copying.
  47. */
  48. const float* ptr() const
  49. {
  50. return &x;
  51. }
  52. Vector2& operator= (const Vector2& rhs)
  53. {
  54. x = rhs.x;
  55. y = rhs.y;
  56. return *this;
  57. }
  58. Vector2& operator= (float rhs)
  59. {
  60. x = rhs;
  61. y = rhs;
  62. return *this;
  63. }
  64. bool operator== (const Vector2& rhs) const
  65. {
  66. return (x == rhs.x && y == rhs.y);
  67. }
  68. bool operator!= (const Vector2& rhs) const
  69. {
  70. return (x != rhs.x || y != rhs.y);
  71. }
  72. Vector2 operator+ (const Vector2& rhs) const
  73. {
  74. return Vector2(x + rhs.x, y + rhs.y);
  75. }
  76. Vector2 operator- (const Vector2& rhs) const
  77. {
  78. return Vector2(x - rhs.x, y - rhs.y);
  79. }
  80. Vector2 operator* (const float rhs) const
  81. {
  82. return Vector2(x * rhs, y * rhs);
  83. }
  84. Vector2 operator* (const Vector2& rhs) const
  85. {
  86. return Vector2(x * rhs.x, y * rhs.y);
  87. }
  88. Vector2 operator/ (const float rhs) const
  89. {
  90. assert(rhs != 0.0);
  91. float fInv = 1.0f / rhs;
  92. return Vector2(x * fInv, y * fInv);
  93. }
  94. Vector2 operator/ (const Vector2& rhs) const
  95. {
  96. return Vector2(x / rhs.x, y / rhs.y);
  97. }
  98. const Vector2& operator+ () const
  99. {
  100. return *this;
  101. }
  102. Vector2 operator- () const
  103. {
  104. return Vector2(-x, -y);
  105. }
  106. friend Vector2 operator* (float lhs, const Vector2& rhs)
  107. {
  108. return Vector2(lhs * rhs.x, lhs * rhs.y);
  109. }
  110. friend Vector2 operator/ (float lhs, const Vector2& rhs)
  111. {
  112. return Vector2(lhs / rhs.x, lhs / rhs.y);
  113. }
  114. friend Vector2 operator+ (Vector2& lhs, float rhs)
  115. {
  116. return Vector2(lhs.x + rhs, lhs.y + rhs);
  117. }
  118. friend Vector2 operator+ (float lhs, const Vector2& rhs)
  119. {
  120. return Vector2(lhs + rhs.x, lhs + rhs.y);
  121. }
  122. friend Vector2 operator- (const Vector2& lhs, float rhs)
  123. {
  124. return Vector2(lhs.x - rhs, lhs.y - rhs);
  125. }
  126. friend Vector2 operator- (const float lhs, const Vector2& rhs)
  127. {
  128. return Vector2(lhs - rhs.x, lhs - rhs.y);
  129. }
  130. Vector2& operator+= (const Vector2& rhs)
  131. {
  132. x += rhs.x;
  133. y += rhs.y;
  134. return *this;
  135. }
  136. Vector2& operator+= (float rhs)
  137. {
  138. x += rhs;
  139. y += rhs;
  140. return *this;
  141. }
  142. Vector2& operator-= (const Vector2& rhs)
  143. {
  144. x -= rhs.x;
  145. y -= rhs.y;
  146. return *this;
  147. }
  148. Vector2& operator-= (float rhs)
  149. {
  150. x -= rhs;
  151. y -= rhs;
  152. return *this;
  153. }
  154. Vector2& operator*= (float rhs)
  155. {
  156. x *= rhs;
  157. y *= rhs;
  158. return *this;
  159. }
  160. Vector2& operator*= (const Vector2& rhs)
  161. {
  162. x *= rhs.x;
  163. y *= rhs.y;
  164. return *this;
  165. }
  166. Vector2& operator/= (float rhs)
  167. {
  168. assert(rhs != 0.0f);
  169. float inv = 1.0f / rhs;
  170. x *= inv;
  171. y *= inv;
  172. return *this;
  173. }
  174. Vector2& operator/= (const Vector2& rhs)
  175. {
  176. x /= rhs.x;
  177. y /= rhs.y;
  178. return *this;
  179. }
  180. /**
  181. * @brief Returns the length (magnitude) of the vector.
  182. */
  183. float length() const
  184. {
  185. return Math::sqrt(x * x + y * y);
  186. }
  187. /**
  188. * @brief Returns the square of the length(magnitude) of the vector.
  189. */
  190. float squaredLength() const
  191. {
  192. return x * x + y * y;
  193. }
  194. /**
  195. * @brief Returns the distance to another vector.
  196. */
  197. float distance(const Vector2& rhs) const
  198. {
  199. return (*this - rhs).length();
  200. }
  201. /**
  202. * @brief Returns the square of the distance to another vector.
  203. */
  204. float sqrdDistance(const Vector2& rhs) const
  205. {
  206. return (*this - rhs).squaredLength();
  207. }
  208. /**
  209. * @brief Calculates the dot (scalar) product of this vector with another.
  210. */
  211. float dot(const Vector2& vec) const
  212. {
  213. return x * vec.x + y * vec.y;
  214. }
  215. /**
  216. * @brief Normalizes the vector.
  217. */
  218. float normalize()
  219. {
  220. float len = Math::sqrt(x * x + y * y);
  221. // Will also work for zero-sized vectors, but will change nothing
  222. if (len > 1e-08)
  223. {
  224. float invLen = 1.0f / len;
  225. x *= invLen;
  226. y *= invLen;
  227. }
  228. return len;
  229. }
  230. /**
  231. * @brief Generates a vector perpendicular to this vector.
  232. */
  233. Vector2 perpendicular() const
  234. {
  235. return Vector2 (-y, x);
  236. }
  237. /**
  238. * @brief Calculates the 2 dimensional cross-product of 2 vectors, which results
  239. * in a single floating point value which is 2 times the area of the triangle.
  240. */
  241. float cross(const Vector2& other) const
  242. {
  243. return x * other.y - y * other.x;
  244. }
  245. /**
  246. * @brief Sets this vector's components to the minimum of its own and the
  247. * ones of the passed in vector.
  248. */
  249. void floor(const Vector2& cmp)
  250. {
  251. if(cmp.x < x) x = cmp.x;
  252. if(cmp.y < y) y = cmp.y;
  253. }
  254. /**
  255. * @brief Sets this vector's components to the maximum of its own and the
  256. * ones of the passed in vector.
  257. */
  258. void ceil(const Vector2& cmp)
  259. {
  260. if(cmp.x > x) x = cmp.x;
  261. if(cmp.y > y) y = cmp.y;
  262. }
  263. /**
  264. * @brief Returns true if this vector is zero length.
  265. */
  266. bool isZeroLength() const
  267. {
  268. float sqlen = (x * x) + (y * y);
  269. return (sqlen < (1e-06 * 1e-06));
  270. }
  271. /**
  272. * @brief Calculates a reflection vector to the plane with the given normal.
  273. */
  274. Vector2 reflect(const Vector2& normal) const
  275. {
  276. return Vector2(*this - (2 * this->dot(normal) * normal));
  277. }
  278. /**
  279. * @brief Performs Gram-Schmidt orthonormalization
  280. */
  281. static void orthonormalize(Vector2& u, Vector2& v)
  282. {
  283. u.normalize();
  284. float dot = u.dot(v);
  285. v -= u*dot;
  286. v.normalize();
  287. }
  288. /**
  289. * @brief Normalizes the provided vector and returns a new normalized instance.
  290. */
  291. static Vector2 normalize(const Vector2& val)
  292. {
  293. float len = Math::sqrt(val.x * val.x + val.y * val.y);
  294. // Will also work for zero-sized vectors, but will change nothing
  295. Vector2 normalizedVec;
  296. if (len > 1e-08)
  297. {
  298. float invLen = 1.0f / len;
  299. normalizedVec.x *= invLen;
  300. normalizedVec.y *= invLen;
  301. }
  302. return normalizedVec;
  303. }
  304. /**
  305. * @brief Checks are any of the vector components NaN.
  306. */
  307. bool isNaN() const
  308. {
  309. return Math::isNaN(x) || Math::isNaN(y);
  310. }
  311. /**
  312. * @brief Returns the minimum of all the vector components as a
  313. * new vector.
  314. */
  315. static Vector2 min(const Vector2& a, const Vector2& b)
  316. {
  317. return Vector2(std::min(a.x, b.x), std::min(a.y, b.y));
  318. }
  319. /**
  320. * @brief Returns the maximum of all the vector components as a
  321. * new vector.
  322. */
  323. static Vector2 max(const Vector2& a, const Vector2& b)
  324. {
  325. return Vector2(std::max(a.x, b.x), std::max(a.y, b.y));
  326. }
  327. static const Vector2 ZERO;
  328. static const Vector2 ONE;
  329. static const Vector2 UNIT_X;
  330. static const Vector2 UNIT_Y;
  331. };
  332. BS_ALLOW_MEMCPY_SERIALIZATION(Vector2);
  333. }