VecI.cs 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174
  1. using System;
  2. using PixiEditor.DrawingApi.Core.Surface;
  3. namespace PixiEditor.DrawingApi.Core.Numerics;
  4. public struct VecI : IEquatable<VecI>
  5. {
  6. public int X { set; get; }
  7. public int Y { set; get; }
  8. public int TaxicabLength => Math.Abs(X) + Math.Abs(Y);
  9. public double Length => Math.Sqrt(LengthSquared);
  10. public int LengthSquared => X * X + Y * Y;
  11. public int LongestAxis => (Math.Abs(X) < Math.Abs(Y)) ? Y : X;
  12. public int ShortestAxis => (Math.Abs(X) < Math.Abs(Y)) ? X : Y;
  13. public static VecI Zero { get; } = new(0, 0);
  14. public static VecI One { get; } = new(1, 1);
  15. public VecI(int x, int y)
  16. {
  17. X = x;
  18. Y = y;
  19. }
  20. public VecI(int bothAxesValue)
  21. {
  22. X = bothAxesValue;
  23. Y = bothAxesValue;
  24. }
  25. public VecI Signs()
  26. {
  27. return new VecI(X >= 0 ? 1 : -1, Y >= 0 ? 1 : -1);
  28. }
  29. public VecI Multiply(VecI other)
  30. {
  31. return new VecI(X * other.X, Y * other.Y);
  32. }
  33. public VecI Add(int value)
  34. {
  35. return new VecI(X + value, Y + value);
  36. }
  37. /// <summary>
  38. /// Reflects the vector across a vertical line with the specified x position
  39. /// </summary>
  40. public VecI ReflectX(int lineX)
  41. {
  42. return new(2 * lineX - X, Y);
  43. }
  44. /// <summary>
  45. /// Reflects the vector across a horizontal line with the specified y position
  46. /// </summary>
  47. public VecI ReflectY(int lineY)
  48. {
  49. return new(X, 2 * lineY - Y);
  50. }
  51. /// <summary>
  52. /// Reflects the vector across a vertical line with the specified x position
  53. /// </summary>
  54. public VecD ReflectX(double lineX)
  55. {
  56. return new(2 * lineX - X, Y);
  57. }
  58. /// <summary>
  59. /// Reflects the vector across a horizontal line with the specified y position
  60. /// </summary>
  61. public VecD ReflectY(double lineY)
  62. {
  63. return new(X, 2 * lineY - Y);
  64. }
  65. public static VecI operator +(VecI a, VecI b)
  66. {
  67. return new VecI(a.X + b.X, a.Y + b.Y);
  68. }
  69. public static VecI operator -(VecI a, VecI b)
  70. {
  71. return new VecI(a.X - b.X, a.Y - b.Y);
  72. }
  73. public static VecI operator -(VecI a)
  74. {
  75. return new VecI(-a.X, -a.Y);
  76. }
  77. public static VecI operator *(int b, VecI a)
  78. {
  79. return new VecI(a.X * b, a.Y * b);
  80. }
  81. public static int operator *(VecI a, VecI b)
  82. {
  83. return a.X * b.X + a.Y * b.Y;
  84. }
  85. public static VecI operator *(VecI a, int b)
  86. {
  87. return new VecI(a.X * b, a.Y * b);
  88. }
  89. public static VecD operator *(VecI a, double b)
  90. {
  91. return new VecD(a.X * b, a.Y * b);
  92. }
  93. public static VecI operator /(VecI a, int b)
  94. {
  95. return new VecI(a.X / b, a.Y / b);
  96. }
  97. public static VecD operator /(VecI a, double b)
  98. {
  99. return new VecD(a.X / b, a.Y / b);
  100. }
  101. public static VecI operator %(VecI a, int b)
  102. {
  103. return new(a.X % b, a.Y % b);
  104. }
  105. public static VecD operator %(VecI a, double b)
  106. {
  107. return new(a.X % b, a.Y % b);
  108. }
  109. public static bool operator ==(VecI a, VecI b)
  110. {
  111. return a.X == b.X && a.Y == b.Y;
  112. }
  113. public static bool operator !=(VecI a, VecI b)
  114. {
  115. return !(a.X == b.X && a.Y == b.Y);
  116. }
  117. public static implicit operator VecI(Point point)
  118. {
  119. return new VecI((int)point.X, (int)point.Y);
  120. }
  121. public static implicit operator Point(VecI vec)
  122. {
  123. return new(vec.X, vec.Y);
  124. }
  125. public static implicit operator VecD(VecI vec)
  126. {
  127. return new VecD(vec.X, vec.Y);
  128. }
  129. public static implicit operator VecI((int, int) tuple)
  130. {
  131. return new VecI(tuple.Item1, tuple.Item2);
  132. }
  133. public void Deconstruct(out int x, out int y)
  134. {
  135. x = X;
  136. y = Y;
  137. }
  138. public override string ToString()
  139. {
  140. return $"({X}; {Y})";
  141. }
  142. public override bool Equals(object? obj)
  143. {
  144. var item = obj as VecI?;
  145. if (item is null)
  146. return false;
  147. return this == item;
  148. }
  149. public override int GetHashCode()
  150. {
  151. return HashCode.Combine(X, Y);
  152. }
  153. public bool Equals(VecI other)
  154. {
  155. return other.X == X && other.Y == Y;
  156. }
  157. public VecD Normalized()
  158. {
  159. return this / Length;
  160. }
  161. }