Vector2.hpp 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276
  1. #ifndef VECTOR2_H
  2. #define VECTOR2_H
  3. #include <gdnative/vector2.h>
  4. #include "Defs.hpp"
  5. #include <Math.hpp>
  6. namespace godot {
  7. class String;
  8. struct Vector2 {
  9. enum Axis {
  10. AXIS_X = 0,
  11. AXIS_Y,
  12. AXIS_COUNT
  13. };
  14. static const Vector2 ZERO;
  15. static const Vector2 ONE;
  16. static const Vector2 INF;
  17. // Coordinate system of the 2D engine
  18. static const Vector2 LEFT;
  19. static const Vector2 RIGHT;
  20. static const Vector2 UP;
  21. static const Vector2 DOWN;
  22. union {
  23. real_t x;
  24. real_t width;
  25. };
  26. union {
  27. real_t y;
  28. real_t height;
  29. };
  30. inline Vector2(real_t p_x, real_t p_y) {
  31. x = p_x;
  32. y = p_y;
  33. }
  34. inline Vector2() {
  35. x = 0;
  36. y = 0;
  37. }
  38. inline real_t &operator[](int p_idx) {
  39. return p_idx ? y : x;
  40. }
  41. inline const real_t &operator[](int p_idx) const {
  42. return p_idx ? y : x;
  43. }
  44. inline Vector2 operator+(const Vector2 &p_v) const {
  45. return Vector2(x + p_v.x, y + p_v.y);
  46. }
  47. inline void operator+=(const Vector2 &p_v) {
  48. x += p_v.x;
  49. y += p_v.y;
  50. }
  51. inline Vector2 operator-(const Vector2 &p_v) const {
  52. return Vector2(x - p_v.x, y - p_v.y);
  53. }
  54. inline void operator-=(const Vector2 &p_v) {
  55. x -= p_v.x;
  56. y -= p_v.y;
  57. }
  58. inline Vector2 operator*(const Vector2 &p_v1) const {
  59. return Vector2(x * p_v1.x, y * p_v1.y);
  60. }
  61. inline Vector2 operator*(const real_t &rvalue) const {
  62. return Vector2(x * rvalue, y * rvalue);
  63. }
  64. inline void operator*=(const real_t &rvalue) {
  65. x *= rvalue;
  66. y *= rvalue;
  67. }
  68. inline void operator*=(const Vector2 &rvalue) {
  69. *this = *this * rvalue;
  70. }
  71. inline Vector2 operator/(const Vector2 &p_v1) const {
  72. return Vector2(x / p_v1.x, y / p_v1.y);
  73. }
  74. inline Vector2 operator/(const real_t &rvalue) const {
  75. return Vector2(x / rvalue, y / rvalue);
  76. }
  77. inline void operator/=(const real_t &rvalue) {
  78. x /= rvalue;
  79. y /= rvalue;
  80. }
  81. inline Vector2 operator-() const {
  82. return Vector2(-x, -y);
  83. }
  84. bool operator==(const Vector2 &p_vec2) const;
  85. bool operator!=(const Vector2 &p_vec2) const;
  86. inline bool operator<(const Vector2 &p_vec2) const { return (x == p_vec2.x) ? (y < p_vec2.y) : (x < p_vec2.x); }
  87. inline bool operator<=(const Vector2 &p_vec2) const { return (x == p_vec2.x) ? (y <= p_vec2.y) : (x <= p_vec2.x); }
  88. inline void normalize() {
  89. real_t l = x * x + y * y;
  90. if (l != 0) {
  91. l = sqrt(l);
  92. x /= l;
  93. y /= l;
  94. }
  95. }
  96. inline Vector2 normalized() const {
  97. Vector2 v = *this;
  98. v.normalize();
  99. return v;
  100. }
  101. inline real_t length() const {
  102. return sqrt(x * x + y * y);
  103. }
  104. inline real_t length_squared() const {
  105. return x * x + y * y;
  106. }
  107. inline real_t distance_to(const Vector2 &p_vector2) const {
  108. return sqrt((x - p_vector2.x) * (x - p_vector2.x) + (y - p_vector2.y) * (y - p_vector2.y));
  109. }
  110. inline real_t distance_squared_to(const Vector2 &p_vector2) const {
  111. return (x - p_vector2.x) * (x - p_vector2.x) + (y - p_vector2.y) * (y - p_vector2.y);
  112. }
  113. inline real_t angle_to(const Vector2 &p_vector2) const {
  114. return atan2(cross(p_vector2), dot(p_vector2));
  115. }
  116. inline real_t angle_to_point(const Vector2 &p_vector2) const {
  117. return atan2(y - p_vector2.y, x - p_vector2.x);
  118. }
  119. inline Vector2 direction_to(const Vector2 &p_b) const {
  120. Vector2 ret(p_b.x - x, p_b.y - y);
  121. ret.normalize();
  122. return ret;
  123. }
  124. inline real_t dot(const Vector2 &p_other) const {
  125. return x * p_other.x + y * p_other.y;
  126. }
  127. inline real_t cross(const Vector2 &p_other) const {
  128. return x * p_other.y - y * p_other.x;
  129. }
  130. inline Vector2 cross(real_t p_other) const {
  131. return Vector2(p_other * y, -p_other * x);
  132. }
  133. Vector2 project(const Vector2 &p_vec) const;
  134. Vector2 plane_project(real_t p_d, const Vector2 &p_vec) const;
  135. Vector2 clamped(real_t p_len) const;
  136. static inline Vector2 linear_interpolate(const Vector2 &p_a, const Vector2 &p_b, real_t p_t) {
  137. Vector2 res = p_a;
  138. res.x += (p_t * (p_b.x - p_a.x));
  139. res.y += (p_t * (p_b.y - p_a.y));
  140. return res;
  141. }
  142. inline Vector2 linear_interpolate(const Vector2 &p_b, real_t p_t) const {
  143. Vector2 res = *this;
  144. res.x += (p_t * (p_b.x - x));
  145. res.y += (p_t * (p_b.y - y));
  146. return res;
  147. }
  148. Vector2 cubic_interpolate(const Vector2 &p_b, const Vector2 &p_pre_a, const Vector2 &p_post_b, real_t p_t) const;
  149. Vector2 move_toward(const Vector2 &p_to, const real_t p_delta) const {
  150. Vector2 v = *this;
  151. Vector2 vd = p_to - v;
  152. real_t len = vd.length();
  153. return len <= p_delta || len < CMP_EPSILON ? p_to : v + vd / len * p_delta;
  154. }
  155. inline Vector2 slide(const Vector2 &p_vec) const {
  156. return p_vec - *this * this->dot(p_vec);
  157. }
  158. inline Vector2 bounce(const Vector2 &p_normal) const {
  159. return -reflect(p_normal);
  160. }
  161. inline Vector2 reflect(const Vector2 &p_normal) const {
  162. return -(*this - p_normal * this->dot(p_normal) * 2.0);
  163. }
  164. inline real_t angle() const {
  165. return atan2(y, x);
  166. }
  167. inline void set_rotation(real_t p_radians) {
  168. x = cosf(p_radians);
  169. y = sinf(p_radians);
  170. }
  171. inline Vector2 abs() const {
  172. return Vector2(fabs(x), fabs(y));
  173. }
  174. inline Vector2 rotated(real_t p_by) const {
  175. Vector2 v;
  176. v.set_rotation(angle() + p_by);
  177. v *= length();
  178. return v;
  179. }
  180. inline Vector2 tangent() const {
  181. return Vector2(y, -x);
  182. }
  183. inline Vector2 floor() const {
  184. return Vector2(Math::floor(x), Math::floor(y));
  185. }
  186. inline Vector2 snapped(const Vector2 &p_by) const {
  187. return Vector2(
  188. Math::stepify(x, p_by.x),
  189. Math::stepify(y, p_by.y));
  190. }
  191. inline real_t aspect() const { return width / height; }
  192. operator String() const;
  193. };
  194. inline Vector2 operator*(real_t p_scalar, const Vector2 &p_vec) {
  195. return p_vec * p_scalar;
  196. }
  197. namespace Math {
  198. // Convenience, since they exist in GDScript
  199. inline Vector2 cartesian2polar(Vector2 v) {
  200. return Vector2(Math::sqrt(v.x * v.x + v.y * v.y), Math::atan2(v.y, v.x));
  201. }
  202. inline Vector2 polar2cartesian(Vector2 v) {
  203. // x == radius
  204. // y == angle
  205. return Vector2(v.x * Math::cos(v.y), v.x * Math::sin(v.y));
  206. }
  207. } // namespace Math
  208. } // namespace godot
  209. #endif // VECTOR2_H