CmVector2.h 9.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411
  1. /*
  2. -----------------------------------------------------------------------------
  3. This source file is part of OGRE
  4. (Object-oriented Graphics Rendering Engine)
  5. For the latest info, see http://www.ogre3d.org/
  6. Copyright (c) 2000-2011 Torus Knot Software Ltd
  7. Permission is hereby granted, free of charge, to any person obtaining a copy
  8. of this software and associated documentation files (the "Software"), to deal
  9. in the Software without restriction, including without limitation the rights
  10. to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  11. copies of the Software, and to permit persons to whom the Software is
  12. furnished to do so, subject to the following conditions:
  13. The above copyright notice and this permission notice shall be included in
  14. all copies or substantial portions of the Software.
  15. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  16. IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  17. FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  18. AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  19. LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  20. OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  21. THE SOFTWARE.
  22. -----------------------------------------------------------------------------
  23. */
  24. #pragma once
  25. #include "CmPrerequisitesUtil.h"
  26. #include "CmMath.h"
  27. namespace CamelotFramework
  28. {
  29. class CM_UTILITY_EXPORT Vector2
  30. {
  31. public:
  32. float x, y;
  33. public:
  34. Vector2()
  35. { }
  36. Vector2(float x, float y)
  37. : x(x), y(y)
  38. { }
  39. /**
  40. * @brief Exchange the contents of this vector with another.
  41. */
  42. void swap(Vector2& other)
  43. {
  44. std::swap(x, other.x);
  45. std::swap(y, other.y);
  46. }
  47. float operator[] (size_t i) const
  48. {
  49. assert(i < 2);
  50. return *(&x+i);
  51. }
  52. float& operator[] (size_t i)
  53. {
  54. assert(i < 2);
  55. return *(&x+i);
  56. }
  57. float* ptr()
  58. {
  59. return &x;
  60. }
  61. const float* ptr() const
  62. {
  63. return &x;
  64. }
  65. Vector2& operator= (const Vector2& rhs)
  66. {
  67. x = rhs.x;
  68. y = rhs.y;
  69. return *this;
  70. }
  71. Vector2& operator= (float rhs)
  72. {
  73. x = rhs;
  74. y = rhs;
  75. return *this;
  76. }
  77. bool operator== (const Vector2& rhs) const
  78. {
  79. return (x == rhs.x && y == rhs.y);
  80. }
  81. bool operator!= (const Vector2& rhs) const
  82. {
  83. return (x != rhs.x || y != rhs.y);
  84. }
  85. Vector2 operator+ (const Vector2& rhs) const
  86. {
  87. return Vector2(x + rhs.x, y + rhs.y);
  88. }
  89. Vector2 operator- (const Vector2& rhs) const
  90. {
  91. return Vector2(x - rhs.x, y - rhs.y);
  92. }
  93. Vector2 operator* (const float rhs) const
  94. {
  95. return Vector2(x * rhs, y * rhs);
  96. }
  97. Vector2 operator* (const Vector2& rhs) const
  98. {
  99. return Vector2(x * rhs.x, y * rhs.y);
  100. }
  101. Vector2 operator/ (const float rhs) const
  102. {
  103. assert(rhs != 0.0);
  104. float fInv = 1.0f / rhs;
  105. return Vector2(x * fInv, y * fInv);
  106. }
  107. Vector2 operator/ (const Vector2& rhs) const
  108. {
  109. return Vector2(x / rhs.x, y / rhs.y);
  110. }
  111. const Vector2& operator+ () const
  112. {
  113. return *this;
  114. }
  115. Vector2 operator- () const
  116. {
  117. return Vector2(-x, -y);
  118. }
  119. friend Vector2 operator* (float lhs, const Vector2& rhs)
  120. {
  121. return Vector2(lhs * rhs.x, lhs * rhs.y);
  122. }
  123. friend Vector2 operator/ (float lhs, const Vector2& rhs)
  124. {
  125. return Vector2(lhs / rhs.x, lhs / rhs.y);
  126. }
  127. friend Vector2 operator+ (Vector2& lhs, float rhs)
  128. {
  129. return Vector2(lhs.x + rhs, lhs.y + rhs);
  130. }
  131. friend Vector2 operator+ (float lhs, const Vector2& rhs)
  132. {
  133. return Vector2(lhs + rhs.x, lhs + rhs.y);
  134. }
  135. friend Vector2 operator- (const Vector2& lhs, float rhs)
  136. {
  137. return Vector2(lhs.x - rhs, lhs.y - rhs);
  138. }
  139. friend Vector2 operator- (const float lhs, const Vector2& rhs)
  140. {
  141. return Vector2(lhs - rhs.x, lhs - rhs.y);
  142. }
  143. Vector2& operator+= (const Vector2& rhs)
  144. {
  145. x += rhs.x;
  146. y += rhs.y;
  147. return *this;
  148. }
  149. Vector2& operator+= (float rhs)
  150. {
  151. x += rhs;
  152. y += rhs;
  153. return *this;
  154. }
  155. Vector2& operator-= (const Vector2& rhs)
  156. {
  157. x -= rhs.x;
  158. y -= rhs.y;
  159. return *this;
  160. }
  161. Vector2& operator-= (float rhs)
  162. {
  163. x -= rhs;
  164. y -= rhs;
  165. return *this;
  166. }
  167. Vector2& operator*= (float rhs)
  168. {
  169. x *= rhs;
  170. y *= rhs;
  171. return *this;
  172. }
  173. Vector2& operator*= (const Vector2& rhs)
  174. {
  175. x *= rhs.x;
  176. y *= rhs.y;
  177. return *this;
  178. }
  179. Vector2& operator/= (float rhs)
  180. {
  181. assert(rhs != 0.0f);
  182. float inv = 1.0f / rhs;
  183. x *= inv;
  184. y *= inv;
  185. return *this;
  186. }
  187. Vector2& operator/= (const Vector2& rhs)
  188. {
  189. x /= rhs.x;
  190. y /= rhs.y;
  191. return *this;
  192. }
  193. /**
  194. * @brief Returns the length (magnitude) of the vector.
  195. */
  196. float length() const
  197. {
  198. return Math::sqrt(x * x + y * y);
  199. }
  200. /**
  201. * @brief Returns the square of the length(magnitude) of the vector.
  202. */
  203. float squaredLength() const
  204. {
  205. return x * x + y * y;
  206. }
  207. /**
  208. * @brief Returns the distance to another vector.
  209. */
  210. float distance(const Vector2& rhs) const
  211. {
  212. return (*this - rhs).length();
  213. }
  214. /**
  215. * @brief Returns the square of the distance to another vector.
  216. */
  217. float sqrdDistance(const Vector2& rhs) const
  218. {
  219. return (*this - rhs).squaredLength();
  220. }
  221. /**
  222. * @brief Calculates the dot (scalar) product of this vector with another.
  223. */
  224. float dot(const Vector2& vec) const
  225. {
  226. return x * vec.x + y * vec.y;
  227. }
  228. /**
  229. * @brief Normalizes the vector.
  230. */
  231. float normalize()
  232. {
  233. float len = Math::sqrt(x * x + y * y);
  234. // Will also work for zero-sized vectors, but will change nothing
  235. if (len > 1e-08)
  236. {
  237. float invLen = 1.0f / len;
  238. x *= invLen;
  239. y *= invLen;
  240. }
  241. return len;
  242. }
  243. /**
  244. * @brief Generates a vector perpendicular to this vector.
  245. */
  246. Vector2 perpendicular() const
  247. {
  248. return Vector2 (-y, x);
  249. }
  250. /**
  251. * @brief Calculates the 2 dimensional cross-product of 2 vectors, which results
  252. * in a single floating point value which is 2 times the area of the triangle.
  253. */
  254. float cross(const Vector2& other) const
  255. {
  256. return x * other.y - y * other.x;
  257. }
  258. /**
  259. * @brief Sets this vector's components to the minimum of its own and the
  260. * ones of the passed in vector.
  261. */
  262. void floor(const Vector2& cmp)
  263. {
  264. if(cmp.x < x) x = cmp.x;
  265. if(cmp.y < y) y = cmp.y;
  266. }
  267. /**
  268. * @brief Sets this vector's components to the maximum of its own and the
  269. * ones of the passed in vector.
  270. */
  271. void ceil(const Vector2& cmp)
  272. {
  273. if(cmp.x > x) x = cmp.x;
  274. if(cmp.y > y) y = cmp.y;
  275. }
  276. /**
  277. * @brief Returns true if this vector is zero length.
  278. */
  279. bool isZeroLength() const
  280. {
  281. float sqlen = (x * x) + (y * y);
  282. return (sqlen < (1e-06 * 1e-06));
  283. }
  284. /**
  285. * @brief Calculates a reflection vector to the plane with the given normal.
  286. */
  287. Vector2 reflect(const Vector2& normal) const
  288. {
  289. return Vector2(*this - (2 * this->dot(normal) * normal));
  290. }
  291. /**
  292. * @brief Performs Gram-Schmidt orthonormalization
  293. */
  294. static void orthonormalize(Vector2& u, Vector2& v)
  295. {
  296. u.normalize();
  297. float dot = u.dot(v);
  298. v -= u*dot;
  299. v.normalize();
  300. }
  301. static Vector2 normalize(const Vector2& val)
  302. {
  303. float len = Math::sqrt(val.x * val.x + val.y * val.y);
  304. // Will also work for zero-sized vectors, but will change nothing
  305. Vector2 normalizedVec;
  306. if (len > 1e-08)
  307. {
  308. float invLen = 1.0f / len;
  309. normalizedVec.x *= invLen;
  310. normalizedVec.y *= invLen;
  311. }
  312. return normalizedVec;
  313. }
  314. bool isNaN() const
  315. {
  316. return Math::isNaN(x) || Math::isNaN(y);
  317. }
  318. static Vector2 min(const Vector2& a, const Vector2& b)
  319. {
  320. return Vector2(std::min(a.x, b.x), std::min(a.y, b.y));
  321. }
  322. static Vector2 max(const Vector2& a, const Vector2& b)
  323. {
  324. return Vector2(std::max(a.x, b.x), std::max(a.y, b.y));
  325. }
  326. static const Vector2 ZERO;
  327. static const Vector2 ONE;
  328. static const Vector2 UNIT_X;
  329. static const Vector2 UNIT_Y;
  330. };
  331. CM_ALLOW_MEMCPY_SERIALIZATION(Vector2);
  332. }