Vector2.cs 9.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410
  1. // file: core/math/math_2d.h
  2. // commit: 7ad14e7a3e6f87ddc450f7e34621eb5200808451
  3. // file: core/math/math_2d.cpp
  4. // commit: 7ad14e7a3e6f87ddc450f7e34621eb5200808451
  5. // file: core/variant_call.cpp
  6. // commit: 5ad9be4c24e9d7dc5672fdc42cea896622fe5685
  7. using System;
  8. using System.Runtime.InteropServices;
  9. #if REAL_T_IS_DOUBLE
  10. using real_t = System.Double;
  11. #else
  12. using real_t = System.Single;
  13. #endif
  14. namespace Godot
  15. {
  16. [StructLayout(LayoutKind.Sequential)]
  17. public struct Vector2 : IEquatable<Vector2>
  18. {
  19. public real_t x;
  20. public real_t y;
  21. public real_t this[int index]
  22. {
  23. get
  24. {
  25. switch (index)
  26. {
  27. case 0:
  28. return x;
  29. case 1:
  30. return y;
  31. default:
  32. throw new IndexOutOfRangeException();
  33. }
  34. }
  35. set
  36. {
  37. switch (index)
  38. {
  39. case 0:
  40. x = value;
  41. return;
  42. case 1:
  43. y = value;
  44. return;
  45. default:
  46. throw new IndexOutOfRangeException();
  47. }
  48. }
  49. }
  50. internal void Normalize()
  51. {
  52. real_t length = x * x + y * y;
  53. if (length != 0f)
  54. {
  55. length = Mathf.Sqrt(length);
  56. x /= length;
  57. y /= length;
  58. }
  59. }
  60. public real_t Cross(Vector2 b)
  61. {
  62. return x * b.y - y * b.x;
  63. }
  64. public Vector2 Abs()
  65. {
  66. return new Vector2(Mathf.Abs(x), Mathf.Abs(y));
  67. }
  68. public real_t Angle()
  69. {
  70. return Mathf.Atan2(y, x);
  71. }
  72. public real_t AngleTo(Vector2 to)
  73. {
  74. return Mathf.Atan2(Cross(to), Dot(to));
  75. }
  76. public real_t AngleToPoint(Vector2 to)
  77. {
  78. return Mathf.Atan2(x - to.x, y - to.y);
  79. }
  80. public real_t Aspect()
  81. {
  82. return x / y;
  83. }
  84. public Vector2 Bounce(Vector2 n)
  85. {
  86. return -Reflect(n);
  87. }
  88. public Vector2 Ceil()
  89. {
  90. return new Vector2(Mathf.Ceil(x), Mathf.Ceil(y));
  91. }
  92. public Vector2 Clamped(real_t length)
  93. {
  94. var v = this;
  95. real_t l = Length();
  96. if (l > 0 && length < l)
  97. {
  98. v /= l;
  99. v *= length;
  100. }
  101. return v;
  102. }
  103. public Vector2 CubicInterpolate(Vector2 b, Vector2 preA, Vector2 postB, real_t t)
  104. {
  105. var p0 = preA;
  106. var p1 = this;
  107. var p2 = b;
  108. var p3 = postB;
  109. real_t t2 = t * t;
  110. real_t t3 = t2 * t;
  111. return 0.5f * (p1 * 2.0f +
  112. (-p0 + p2) * t +
  113. (2.0f * p0 - 5.0f * p1 + 4 * p2 - p3) * t2 +
  114. (-p0 + 3.0f * p1 - 3.0f * p2 + p3) * t3);
  115. }
  116. public real_t DistanceSquaredTo(Vector2 to)
  117. {
  118. return (x - to.x) * (x - to.x) + (y - to.y) * (y - to.y);
  119. }
  120. public real_t DistanceTo(Vector2 to)
  121. {
  122. return Mathf.Sqrt((x - to.x) * (x - to.x) + (y - to.y) * (y - to.y));
  123. }
  124. public real_t Dot(Vector2 with)
  125. {
  126. return x * with.x + y * with.y;
  127. }
  128. public Vector2 Floor()
  129. {
  130. return new Vector2(Mathf.Floor(x), Mathf.Floor(y));
  131. }
  132. public bool IsNormalized()
  133. {
  134. return Mathf.Abs(LengthSquared() - 1.0f) < Mathf.Epsilon;
  135. }
  136. public real_t Length()
  137. {
  138. return Mathf.Sqrt(x * x + y * y);
  139. }
  140. public real_t LengthSquared()
  141. {
  142. return x * x + y * y;
  143. }
  144. public Vector2 LinearInterpolate(Vector2 b, real_t t)
  145. {
  146. var res = this;
  147. res.x += t * (b.x - x);
  148. res.y += t * (b.y - y);
  149. return res;
  150. }
  151. public Vector2 Normalized()
  152. {
  153. var result = this;
  154. result.Normalize();
  155. return result;
  156. }
  157. public Vector2 Reflect(Vector2 n)
  158. {
  159. return 2.0f * n * Dot(n) - this;
  160. }
  161. public Vector2 Rotated(real_t phi)
  162. {
  163. real_t rads = Angle() + phi;
  164. return new Vector2(Mathf.Cos(rads), Mathf.Sin(rads)) * Length();
  165. }
  166. public Vector2 Round()
  167. {
  168. return new Vector2(Mathf.Round(x), Mathf.Round(y));
  169. }
  170. public void Set(real_t x, real_t y)
  171. {
  172. this.x = x;
  173. this.y = y;
  174. }
  175. public void Set(Vector2 v)
  176. {
  177. x = v.x;
  178. y = v.y;
  179. }
  180. public Vector2 Slerp(Vector2 b, real_t t)
  181. {
  182. real_t theta = AngleTo(b);
  183. return Rotated(theta * t);
  184. }
  185. public Vector2 Slide(Vector2 n)
  186. {
  187. return this - n * Dot(n);
  188. }
  189. public Vector2 Snapped(Vector2 by)
  190. {
  191. return new Vector2(Mathf.Stepify(x, by.x), Mathf.Stepify(y, by.y));
  192. }
  193. public Vector2 Tangent()
  194. {
  195. return new Vector2(y, -x);
  196. }
  197. private static readonly Vector2 zero = new Vector2 (0, 0);
  198. private static readonly Vector2 one = new Vector2 (1, 1);
  199. private static readonly Vector2 negOne = new Vector2 (-1, -1);
  200. private static readonly Vector2 up = new Vector2 (0, 1);
  201. private static readonly Vector2 down = new Vector2 (0, -1);
  202. private static readonly Vector2 right = new Vector2 (1, 0);
  203. private static readonly Vector2 left = new Vector2 (-1, 0);
  204. public static Vector2 Zero { get { return zero; } }
  205. public static Vector2 One { get { return one; } }
  206. public static Vector2 NegOne { get { return negOne; } }
  207. public static Vector2 Up { get { return up; } }
  208. public static Vector2 Down { get { return down; } }
  209. public static Vector2 Right { get { return right; } }
  210. public static Vector2 Left { get { return left; } }
  211. // Constructors
  212. public Vector2(real_t x, real_t y)
  213. {
  214. this.x = x;
  215. this.y = y;
  216. }
  217. public Vector2(Vector2 v)
  218. {
  219. x = v.x;
  220. y = v.y;
  221. }
  222. public static Vector2 operator +(Vector2 left, Vector2 right)
  223. {
  224. left.x += right.x;
  225. left.y += right.y;
  226. return left;
  227. }
  228. public static Vector2 operator -(Vector2 left, Vector2 right)
  229. {
  230. left.x -= right.x;
  231. left.y -= right.y;
  232. return left;
  233. }
  234. public static Vector2 operator -(Vector2 vec)
  235. {
  236. vec.x = -vec.x;
  237. vec.y = -vec.y;
  238. return vec;
  239. }
  240. public static Vector2 operator *(Vector2 vec, real_t scale)
  241. {
  242. vec.x *= scale;
  243. vec.y *= scale;
  244. return vec;
  245. }
  246. public static Vector2 operator *(real_t scale, Vector2 vec)
  247. {
  248. vec.x *= scale;
  249. vec.y *= scale;
  250. return vec;
  251. }
  252. public static Vector2 operator *(Vector2 left, Vector2 right)
  253. {
  254. left.x *= right.x;
  255. left.y *= right.y;
  256. return left;
  257. }
  258. public static Vector2 operator /(Vector2 vec, real_t scale)
  259. {
  260. vec.x /= scale;
  261. vec.y /= scale;
  262. return vec;
  263. }
  264. public static Vector2 operator /(Vector2 left, Vector2 right)
  265. {
  266. left.x /= right.x;
  267. left.y /= right.y;
  268. return left;
  269. }
  270. public static bool operator ==(Vector2 left, Vector2 right)
  271. {
  272. return left.Equals(right);
  273. }
  274. public static bool operator !=(Vector2 left, Vector2 right)
  275. {
  276. return !left.Equals(right);
  277. }
  278. public static bool operator <(Vector2 left, Vector2 right)
  279. {
  280. if (left.x.Equals(right.x))
  281. {
  282. return left.y < right.y;
  283. }
  284. return left.x < right.x;
  285. }
  286. public static bool operator >(Vector2 left, Vector2 right)
  287. {
  288. if (left.x.Equals(right.x))
  289. {
  290. return left.y > right.y;
  291. }
  292. return left.x > right.x;
  293. }
  294. public static bool operator <=(Vector2 left, Vector2 right)
  295. {
  296. if (left.x.Equals(right.x))
  297. {
  298. return left.y <= right.y;
  299. }
  300. return left.x <= right.x;
  301. }
  302. public static bool operator >=(Vector2 left, Vector2 right)
  303. {
  304. if (left.x.Equals(right.x))
  305. {
  306. return left.y >= right.y;
  307. }
  308. return left.x >= right.x;
  309. }
  310. public override bool Equals(object obj)
  311. {
  312. if (obj is Vector2)
  313. {
  314. return Equals((Vector2)obj);
  315. }
  316. return false;
  317. }
  318. public bool Equals(Vector2 other)
  319. {
  320. return x == other.x && y == other.y;
  321. }
  322. public override int GetHashCode()
  323. {
  324. return y.GetHashCode() ^ x.GetHashCode();
  325. }
  326. public override string ToString()
  327. {
  328. return String.Format("({0}, {1})", new object[]
  329. {
  330. x.ToString(),
  331. y.ToString()
  332. });
  333. }
  334. public string ToString(string format)
  335. {
  336. return String.Format("({0}, {1})", new object[]
  337. {
  338. x.ToString(format),
  339. y.ToString(format)
  340. });
  341. }
  342. }
  343. }