PointEx.cs 7.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198
  1. using Microsoft.Xna.Framework;
  2. using System;
  3. using System.Collections.Generic;
  4. using System.Linq;
  5. namespace OpenVIII
  6. {
  7. /// <summary>
  8. /// More Extensions
  9. /// </summary>
  10. public static class PointEx
  11. {
  12. #region Methods
  13. /// <see cref="https://stackoverflow.com/questions/4615410/random-element-of-listt-from-linq-sql"/>
  14. public static T Random<T>(this IEnumerable<T> input) => input.ElementAt(Memory.Random.Next(input.Count()));
  15. public static T RandomOrDefault<T>(this IEnumerable<T> input) => input.ElementAtOrDefault(Memory.Random.Next(input.Count()));
  16. /// <summary>
  17. /// Rotate a Vector2 by degrees
  18. /// </summary>
  19. /// <param name="v"></param>
  20. /// <param name="degrees"></param>
  21. /// <returns></returns>
  22. /// <see cref="https://answers.unity.com/questions/661383/whats-the-most-efficient-way-to-rotate-a-vector2-o.html"/>
  23. public static Vector2 Rotate(this Vector2 v, float degrees)
  24. {
  25. var rad = MathHelper.ToRadians(degrees);
  26. var sin = (float)Math.Sin(rad);
  27. var cos = (float)Math.Cos(rad);
  28. var tx = v.X;
  29. var ty = v.Y;
  30. v.X = (cos * tx) - (sin * ty);
  31. v.Y = (sin * tx) + (cos * ty);
  32. return v;
  33. }
  34. public static Point Offset(this ref Point source, Point offset)
  35. {
  36. source = (source.ToVector2() + offset.ToVector2()).ToPoint();
  37. return source;
  38. }
  39. public static Point Offset(this ref Point source, int x,int y)
  40. {
  41. var offset = new Point(x, y);
  42. return source.Offset(offset);
  43. }
  44. public static Point Offset(this ref Point source, Vector2 offset)
  45. {
  46. return source = (source.ToVector2() + offset).ToPoint();
  47. }
  48. public static Point Transform(this Point point, Matrix matrix)
  49. {
  50. point = Vector2.Transform(point.ToVector2(), Matrix.Invert(matrix)).RoundedPoint();
  51. return point;
  52. }
  53. public static Rectangle Scale(this Rectangle source, Matrix matrix)
  54. {
  55. var scale = Memory.Scale();
  56. var loc = source.Location.ToVector2();
  57. source.Offset(matrix.Translation.X, matrix.Translation.Y);
  58. source.Location = Vector2.Transform(loc, Matrix.Invert(matrix)).RoundedPoint();
  59. source.Size = (source.Size.ToVector2() * scale).RoundedPoint();
  60. return source;
  61. }
  62. public static Rectangle Scale(this Rectangle source, Vector2 scale)
  63. {
  64. source.Location = (source.Location.ToVector2() * scale).RoundedPoint();
  65. source.Size = (source.Size.ToVector2() * scale).RoundedPoint();
  66. return source;
  67. }
  68. public static Rectangle Scale(this Rectangle source)
  69. {
  70. var scale = Memory.Scale();
  71. source.Location = (source.Location.ToVector2() * scale).RoundedPoint();
  72. source.Size = (source.Size.ToVector2() * scale).RoundedPoint();
  73. return source;
  74. }
  75. public static Point Scale(this Point source, Vector2 scale)
  76. {
  77. source = (source.ToVector2() * scale).RoundedPoint();
  78. return source;
  79. }
  80. public static Point Scale(this Point source)
  81. {
  82. var scale = Memory.Scale();
  83. source = (source.ToVector2() * scale).RoundedPoint();
  84. return source;
  85. }
  86. public static Point RoundedPoint(this Vector2 v) => new Point((int)Math.Round(v.X), (int)Math.Round(v.Y));
  87. public static Point CeilingPoint(this Vector2 v) => v.Ceiling().ToPoint();
  88. public static Point FloorPoint(this Vector2 v) => v.Floor().ToPoint();
  89. public static Vector2 Round(this Vector2 v) => new Vector2((float)Math.Round(v.X), (float)Math.Round(v.Y));
  90. public static Vector2 Ceiling(this Vector2 v) => new Vector2((float)Math.Ceiling(v.X), (float)Math.Ceiling(v.Y));
  91. public static Vector2 Abs(this Vector2 v) => new Vector2((float)Math.Abs(v.X), (float)Math.Abs(v.Y));
  92. public static Vector2 Floor(this Vector2 v) => new Vector2((float)Math.Floor(v.X), (float)Math.Floor(v.Y));
  93. public static Vector2 FloorOrCeiling(this Vector2 v, Vector2 target)
  94. {
  95. float X, Y;
  96. X = v.X < target.X ? (float)Math.Ceiling(v.X) : (float)Math.Floor(v.X);
  97. Y = v.Y < target.Y ? (float)Math.Ceiling(v.Y) : (float)Math.Floor(v.Y);
  98. return new Vector2(X, Y);
  99. }
  100. /// <summary>
  101. /// Count how many flags set in enum.
  102. /// </summary>
  103. /// <param name="statuses">varible you need to number of flags set.</param>
  104. /// <returns>Count</returns>
  105. /// <see cref="https://stackoverflow.com/questions/677204/counting-the-number-of-flags-set-on-an-enumeration"/>
  106. public static uint Count(this Kernel.JunctionStatuses statuses)
  107. {
  108. var v = (uint)statuses;
  109. v = v - ((v >> 1) & 0x55555555); // reuse input as temporary
  110. v = (v & 0x33333333) + ((v >> 2) & 0x33333333); // temp
  111. return ((v + (v >> 4) & 0xF0F0F0F) * 0x1010101) >> 24; // Count
  112. }
  113. /// <summary>
  114. /// Count how many flags set in enum.
  115. /// </summary>
  116. /// <param name="element">varible you need to number of flags set.</param>
  117. /// <returns>Count</returns>
  118. /// <see cref="https://stackoverflow.com/questions/677204/counting-the-number-of-flags-set-on-an-enumeration"/>
  119. public static uint Count(this Kernel.Element element)
  120. {
  121. var v = (uint)element;
  122. v = v - ((v >> 1) & 0x55555555); // reuse input as temporary
  123. v = (v & 0x33333333) + ((v >> 2) & 0x33333333); // temp
  124. return ((v + (v >> 4) & 0xF0F0F0F) * 0x1010101) >> 24; // Count
  125. }
  126. /// <summary>
  127. /// Count how many flags set in enum.
  128. /// </summary>
  129. /// <param name="element">varible you need to number of flags set.</param>
  130. /// <returns>Count</returns>
  131. /// <see cref="https://stackoverflow.com/questions/677204/counting-the-number-of-flags-set-on-an-enumeration"/>
  132. public static uint Count(this Kernel.BattleOnlyStatuses element)
  133. {
  134. var v = (uint)element;
  135. v = v - ((v >> 1) & 0x55555555); // reuse input as temporary
  136. v = (v & 0x33333333) + ((v >> 2) & 0x33333333); // temp
  137. return ((v + (v >> 4) & 0xF0F0F0F) * 0x1010101) >> 24; // Count
  138. }
  139. /// <summary>
  140. /// Count how many flags set in enum.
  141. /// </summary>
  142. /// <param name="element">varible you need to number of flags set.</param>
  143. /// <returns>Count</returns>
  144. /// <see cref="https://stackoverflow.com/questions/677204/counting-the-number-of-flags-set-on-an-enumeration"/>
  145. public static uint Count(this Kernel.PersistentStatuses element)
  146. {
  147. var v = (uint)element;
  148. v = v - ((v >> 1) & 0x55555555); // reuse input as temporary
  149. v = (v & 0x33333333) + ((v >> 2) & 0x33333333); // temp
  150. return ((v + (v >> 4) & 0xF0F0F0F) * 0x1010101) >> 24; // Count
  151. }
  152. public static Characters ToCharacters(this Faces.ID id)
  153. {
  154. if ((byte)id > 10)
  155. return Characters.Blank;
  156. return (Characters)id;
  157. }
  158. public static GFs ToGFs(this Faces.ID id)
  159. {
  160. if ((byte)id < 16 || (byte)id > 31)
  161. return GFs.Blank;
  162. return (GFs)(id - 16);
  163. }
  164. public static Faces.ID ToFacesID(this Characters id) => (Faces.ID)id;
  165. public static Faces.ID ToFacesID(this GFs id)
  166. {
  167. if (GFs.All == id || GFs.Blank == id)
  168. return Faces.ID.Blank;
  169. return (Faces.ID)(id + 16);
  170. }
  171. #endregion Methods
  172. }
  173. }