PageRenderTime 44ms CodeModel.GetById 21ms RepoModel.GetById 0ms app.codeStats 0ms

/NetGore/Core/Extensions/Vector2Extensions.cs

http://netgore.googlecode.com/
C# | 297 lines | 117 code | 28 blank | 152 comment | 16 complexity | 3eed5962c335caa594d7cc0dbe03d2b3 MD5 | raw file
Possible License(s): MIT
  1. using System;
  2. using System.Linq;
  3. using SFML.Graphics;
  4. namespace NetGore
  5. {
  6. /// <summary>
  7. /// Extension methods for the <see cref="Vector2"/>.
  8. /// </summary>
  9. public static class Vector2Extensions
  10. {
  11. /// <summary>
  12. /// Gets the absolute value of the components of the <see cref="Vector2"/>.
  13. /// </summary>
  14. /// <param name="source"><see cref="Vector2"/> to get the absolute value of.</param>
  15. /// <returns>A <see cref="Vector2"/> containing the absolute value of the <paramref name="source"/>
  16. /// <see cref="Vector2"/>.</returns>
  17. public static Vector2 Abs(this Vector2 source)
  18. {
  19. return new Vector2(Math.Abs(source.X), Math.Abs(source.Y));
  20. }
  21. /// <summary>
  22. /// Gets a <see cref="Vector2"/> with the X and Y components rounded up.
  23. /// </summary>
  24. /// <param name="source"><see cref="Vector2"/> to round.</param>
  25. /// <returns>A <see cref="Vector2"/> containing the ceiling-down value of the <paramref name="source"/>
  26. /// <see cref="Vector2"/>.</returns>
  27. public static Vector2 Ceiling(this Vector2 source)
  28. {
  29. return new Vector2((float)Math.Ceiling(source.X), (float)Math.Ceiling(source.Y));
  30. }
  31. /// <summary>
  32. /// Gets a <see cref="Vector2"/> with the X and Y components rounded down.
  33. /// </summary>
  34. /// <param name="source"><see cref="Vector2"/> to round.</param>
  35. /// <returns>A <see cref="Vector2"/> containing the rounded-down value of the <paramref name="source"/>
  36. /// <see cref="Vector2"/>.</returns>
  37. public static Vector2 Floor(this Vector2 source)
  38. {
  39. return new Vector2((float)Math.Floor(source.X), (float)Math.Floor(source.Y));
  40. }
  41. /// <summary>
  42. /// Checks if both of a <see cref="Vector2"/>'s coordinates are greater than or equal to the
  43. /// corresponding coordinates in another <see cref="Vector2"/>.
  44. /// </summary>
  45. /// <param name="source"><see cref="Vector2"/> to check.</param>
  46. /// <param name="other"><see cref="Vector2"/> containing the coordinates to check if are greater than or equal to the
  47. /// <paramref name="source"/>'s coordinates.</param>
  48. /// <returns>True if both of the coordinates in the <paramref name="source"/> are greater than or equal to the
  49. /// corresponding coordinates in the <paramref name="other"/> <see cref="Vector2"/>. False if either or both
  50. /// coordinates are less than their equivalent in the <paramref name="other"/> <see cref="Vector2"/>.</returns>
  51. public static bool IsGreaterOrEqual(this Vector2 source, Vector2 other)
  52. {
  53. return source.X >= other.X && source.Y >= other.Y;
  54. }
  55. /// <summary>
  56. /// Checks if both of a <see cref="Vector2"/>'s coordinates are greater than the corresponding coordinates in another
  57. /// <see cref="Vector2"/>.
  58. /// </summary>
  59. /// <param name="source"><see cref="Vector2"/> to check.</param>
  60. /// <param name="other"><see cref="Vector2"/> containing the coordinates to check if are greater than the
  61. /// <paramref name="source"/>'s coordinates.</param>
  62. /// <returns>True if both of the coordinates in the <paramref name="source"/> are greater than the
  63. /// corresponding coordinates in the <paramref name="other"/> <see cref="Vector2"/>. False if either or both
  64. /// coordinates are less than or equal to their equivalent in the <paramref name="other"/>
  65. /// <see cref="Vector2"/>.</returns>
  66. public static bool IsGreaterThan(this Vector2 source, Vector2 other)
  67. {
  68. return source.X > other.X && source.Y > other.Y;
  69. }
  70. /// <summary>
  71. /// Checks if both of a <see cref="Vector2"/>'s coordinates are less than or equal to the
  72. /// corresponding coordinates in another Vector2.
  73. /// </summary>
  74. /// <param name="source"><see cref="Vector2"/> to check.</param>
  75. /// <param name="other"><see cref="Vector2"/> containing the coordinates to check if are less than or equal to the
  76. /// <paramref name="source"/>'s coordinates.</param>
  77. /// <returns>True if both of the coordinates in the <paramref name="source"/> are less than or equal to the
  78. /// corresponding coordinates in the <paramref name="other"/> <see cref="Vector2"/>. False if either or both
  79. /// coordinates are greater than their equivalent in the <paramref name="other"/> <see cref="Vector2"/>.</returns>
  80. public static bool IsLessOrEqual(this Vector2 source, Vector2 other)
  81. {
  82. return source.X <= other.X && source.Y <= other.Y;
  83. }
  84. /// <summary>
  85. /// Checks if both of a <see cref="Vector2"/>'s coordinates are less than the corresponding coordinates
  86. /// in another <see cref="Vector2"/>.
  87. /// </summary>
  88. /// <param name="source"><see cref="Vector2"/> to check.</param>
  89. /// <param name="other"><see cref="Vector2"/> containing the coordinates to check if are less than the
  90. /// <paramref name="source"/>'s coordinates.</param>
  91. /// <returns>True if both of the coordinates in the <paramref name="source"/> are less than the
  92. /// corresponding coordinates in the <paramref name="other"/> <see cref="Vector2"/>. False if either or both
  93. /// coordinates are greater than or equal to their equivalent in the <paramref name="other"/>
  94. /// <see cref="Vector2"/>.</returns>
  95. public static bool IsLessThan(this Vector2 source, Vector2 other)
  96. {
  97. return source.X < other.X && source.Y < other.Y;
  98. }
  99. /// <summary>
  100. /// Gets a <see cref="Vector2"/> composed of the max value of the given components for the respective property.
  101. /// </summary>
  102. /// <param name="a">The first argument.</param>
  103. /// <param name="b">The second argument.</param>
  104. /// <returns>A <see cref="Vector2"/> composed of the max value of the given components for the respective
  105. /// property.</returns>
  106. public static Vector2 Max(this Vector2 a, Vector2 b)
  107. {
  108. return new Vector2(Math.Max(a.X, b.X), Math.Max(a.Y, b.Y));
  109. }
  110. /// <summary>
  111. /// Gets a <see cref="Vector2"/> composed of the min value of the given components for the respective property.
  112. /// </summary>
  113. /// <param name="a">The first argument.</param>
  114. /// <param name="b">The second argument.</param>
  115. /// <returns>A <see cref="Vector2"/> composed of the max value of the given components for the respective
  116. /// property.</returns>
  117. public static Vector2 Min(this Vector2 a, Vector2 b)
  118. {
  119. return new Vector2(Math.Min(a.X, b.X), Math.Min(a.Y, b.Y));
  120. }
  121. /// <summary>
  122. /// Calculates the <see cref="Vector2"/> position to use to make the <paramref name="source"/> travel towards
  123. /// the <paramref name="target"/>.
  124. /// </summary>
  125. /// <param name="source">The <see cref="Vector2"/> that will be moving.</param>
  126. /// <param name="target">The <see cref="Vector2"/> containing the position to move towards.</param>
  127. /// <param name="distance">The total number of units to move. When moving objects based on elapsed time, this will typically
  128. /// contain the number of pixels to move per millisecond (speed * elapsedTime).</param>
  129. /// <returns>The new <see cref="Vector2"/> position to give the <paramref name="source"/>.</returns>
  130. public static Vector2 MoveTowards(this Vector2 source, Vector2 target, float distance)
  131. {
  132. // Get the difference between the source and target
  133. var diff = source - target;
  134. // Find the angle to travel
  135. var angle = Math.Atan2(diff.Y, diff.X);
  136. // Get the offset vector
  137. var cos = Math.Cos(angle);
  138. var sin = Math.Sin(angle);
  139. var offset = new Vector2((float)(cos * distance), (float)(sin * distance));
  140. return source - offset;
  141. }
  142. /// <summary>
  143. /// Calculates the <see cref="Vector2"/> position to use to make the <paramref name="source"/> travel towards
  144. /// the <paramref name="target"/>.
  145. /// </summary>
  146. /// <param name="source">The <see cref="Vector2"/> that will be moving.</param>
  147. /// <param name="target">The <see cref="Vector2"/> containing the position to move towards.</param>
  148. /// <param name="distance">The total number of units to move. When moving objects based on elapsed time, this will typically
  149. /// contain the number of pixels to move per millisecond (speed * elapsedTime).</param>
  150. /// <param name="doNotPass">If true, the <paramref name="source"/> will stop at the <paramref name="target"/> when it has
  151. /// been reached instead of going past it.</param>
  152. /// <returns>
  153. /// The new <see cref="Vector2"/> position to give the <paramref name="source"/>.
  154. /// </returns>
  155. public static Vector2 MoveTowards(this Vector2 source, Vector2 target, float distance, bool doNotPass = true)
  156. {
  157. // Get the difference between the source and target
  158. var diff = source - target;
  159. // Find the angle to travel
  160. var angle = Math.Atan2(diff.Y, diff.X);
  161. // Get the offset vector
  162. var cos = Math.Cos(angle);
  163. var sin = Math.Sin(angle);
  164. var offset = new Vector2((float)(cos * distance), (float)(sin * distance));
  165. // Apply the offset to get the new position
  166. var newPos = source - offset;
  167. // Make sure we do not overshoot
  168. if (doNotPass)
  169. {
  170. if (offset.X > float.Epsilon)
  171. {
  172. if (newPos.X > target.X)
  173. newPos.X = target.X;
  174. }
  175. else if (offset.X < -float.Epsilon)
  176. {
  177. if (newPos.X < target.X)
  178. newPos.X = target.X;
  179. }
  180. if (offset.Y > float.Epsilon)
  181. {
  182. if (newPos.Y > target.Y)
  183. newPos.Y = target.Y;
  184. }
  185. else if (offset.Y < -float.Epsilon)
  186. {
  187. if (newPos.Y < target.Y)
  188. newPos.Y = target.Y;
  189. }
  190. }
  191. return newPos;
  192. }
  193. /// <summary>
  194. /// Gets the distance between this <see cref="Vector2"/> and another <see cref="Vector2"/> by getting the
  195. /// sum of the differences for the components of the <see cref="Vector2"/>s. This is a much quicker but less accurate
  196. /// version of Distance().
  197. /// </summary>
  198. /// <param name="source">Source <see cref="Vector2"/>.</param>
  199. /// <param name="target">Target <see cref="Vector2"/>.</param>
  200. /// <returns>The distance between this <see cref="Vector2"/> and another <see cref="Vector2"/> by getting the
  201. /// sum of the differences for the components of the <see cref="Vector2"/>s.</returns>
  202. public static float QuickDistance(this Vector2 source, Vector2 target)
  203. {
  204. var diff = source - target;
  205. return Abs(diff).Sum();
  206. }
  207. /// <summary>
  208. /// Gets the proper distance between two vectors. Slower than QuickDistance, but more accurate.
  209. /// </summary>
  210. /// <param name="source">Source <see cref="Vector2"/>.</param>
  211. /// <param name="target">Target <see cref="Vector2"/>.</param>
  212. /// <returns>The distance between the two vectors.</returns>
  213. public static float Distance(this Vector2 source, Vector2 target)
  214. {
  215. return Vector2.Distance(source, target);
  216. }
  217. /// <summary>
  218. /// Gets a <see cref="Vector2"/> with the X and Y components rounded.
  219. /// </summary>
  220. /// <param name="source"><see cref="Vector2"/> to round.</param>
  221. /// <returns>A <see cref="Vector2"/> containing the rounded value of the <paramref name="source"/>
  222. /// <see cref="Vector2"/>.</returns>
  223. public static Vector2 Round(this Vector2 source)
  224. {
  225. return new Vector2((float)Math.Round(source.X), (float)Math.Round(source.Y));
  226. }
  227. /// <summary>
  228. /// Gets the sum of the x and y components of the <see cref="Vector2"/>.
  229. /// </summary>
  230. /// <param name="source"><see cref="Vector2"/> to get the sum of the components of.</param>
  231. /// <returns>Sum of the x and y components of the <see cref="Vector2"/>.</returns>
  232. public static float Sum(this Vector2 source)
  233. {
  234. return source.X + source.Y;
  235. }
  236. /// <summary>
  237. /// Gets a <see cref="Rectangle"/> that describes the area around a <see cref="Vector2"/>.
  238. /// </summary>
  239. /// <param name="source">The source <see cref="Vector2"/>.</param>
  240. /// <param name="size">The size of the <see cref="Rectangle"/>.</param>
  241. /// <param name="center">If true, the <paramref name="source"/> will be at the center of the returned
  242. /// <see cref="Rectangle"/>. If false, the <paramref name="source"/> will be the top-left corner (min)
  243. /// of the <see cref="Rectangle"/>.</param>
  244. /// <returns>The <see cref="Rectangle"/>.</returns>
  245. public static Rectangle ToRectangle(this Vector2 source, Vector2 size, bool center)
  246. {
  247. return ToRectangle(source, size.X, size.Y, center);
  248. }
  249. /// <summary>
  250. /// Gets a <see cref="Rectangle"/> that describes the area around a <see cref="Vector2"/>.
  251. /// </summary>
  252. /// <param name="source">The source <see cref="Vector2"/>.</param>
  253. /// <param name="width">The width of the <see cref="Rectangle"/>.</param>
  254. /// <param name="height">The height of the <see cref="Rectangle"/>.</param>
  255. /// <param name="center">If true, the <paramref name="source"/> will be at the center of the returned
  256. /// <see cref="Rectangle"/>. If false, the <paramref name="source"/> will be the top-left corner (min)
  257. /// of the <see cref="Rectangle"/>.</param>
  258. /// <returns>The <see cref="Rectangle"/>.</returns>
  259. public static Rectangle ToRectangle(this Vector2 source, float width, float height, bool center)
  260. {
  261. Vector2 min;
  262. if (center)
  263. min = source - new Vector2(width / 2f, height / 2f);
  264. else
  265. min = source;
  266. return new Rectangle(Math.Round(min.X), Math.Round(min.Y), Math.Round(width), Math.Round(height));
  267. }
  268. }
  269. }