LineSegment.cs 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181
  1. // Copyright (c) Craftwork Games. All rights reserved.
  2. // Licensed under the MIT license.
  3. // See LICENSE file in the project root for full license information.
  4. using System;
  5. using System.Diagnostics.CodeAnalysis;
  6. using Microsoft.Xna.Framework;
  7. using System.Runtime.InteropServices;
  8. namespace MonoGame.Extended.Particles.Primitives;
  9. /// <summary>
  10. /// Represents a line segment defined by two points in 2D space.
  11. /// </summary>
  12. [StructLayout(LayoutKind.Sequential)]
  13. public readonly struct LineSegment : IEquatable<LineSegment>
  14. {
  15. /// <summary>
  16. /// The first point of the line segment.
  17. /// </summary>
  18. internal readonly Vector2 _point1;
  19. /// <summary>
  20. /// The second point of the line segment.
  21. /// </summary>
  22. internal readonly Vector2 _point2;
  23. /// <summary>
  24. /// Gets the origin point of the line segment.
  25. /// </summary>
  26. /// <value>The first point of the line segment.</value>
  27. public readonly Vector2 Origin
  28. {
  29. get
  30. {
  31. return _point1;
  32. }
  33. }
  34. /// <summary>
  35. /// Gets the direction vector of the line segment.
  36. /// </summary>
  37. /// <value>A vector from the first point to the second point.</value>
  38. public readonly Vector2 Direction
  39. {
  40. get
  41. {
  42. return _point2 - _point1;
  43. }
  44. }
  45. /// <summary>
  46. /// Initializes a new instance of the <see cref="LineSegment"/> struct with the specified points.
  47. /// </summary>
  48. /// <param name="point1">The first point of the line segment.</param>
  49. /// <param name="point2">The second point of the line segment.</param>
  50. public LineSegment(Vector2 point1, Vector2 point2)
  51. {
  52. _point1 = point1;
  53. _point2 = point2;
  54. }
  55. /// <summary>
  56. /// Returns a new line segment that is a translated version of this line segment.
  57. /// </summary>
  58. /// <param name="vector">The vector by which to translate the line segment.</param>
  59. /// <returns>A new <see cref="LineSegment"/> that is offset by the specified vector.</returns>
  60. public LineSegment Translate(Vector2 vector)
  61. {
  62. return new LineSegment(_point1 + vector, _point2 + vector);
  63. }
  64. /// <summary>
  65. /// Converts the line segment to a vector representing its direction and magnitude.
  66. /// </summary>
  67. /// <returns>
  68. /// A <see cref="Vector2"/> representing the direction and length of the line segment, calculated as the second
  69. /// point minus the first point.
  70. /// </returns>
  71. public Vector2 ToVector2()
  72. {
  73. return _point2 - _point1;
  74. }
  75. /// <summary>
  76. /// Creates a new line segment from two points.
  77. /// </summary>
  78. /// <param name="point1">The first point of the line segment.</param>
  79. /// <param name="point2">The second point of the line segment.</param>
  80. /// <returns>A new <see cref="LineSegment"/> defined by the two points.</returns>
  81. public static LineSegment FromPoints(Vector2 point1, Vector2 point2)
  82. {
  83. return new LineSegment(point1, point2);
  84. }
  85. /// <summary>
  86. /// Creates a new line segment from an origin point and a direction vector.
  87. /// </summary>
  88. /// <param name="origin">The starting point of the line segment.</param>
  89. /// <param name="vector">The direction and length vector of the line segment.</param>
  90. /// <returns>
  91. /// A new <see cref="LineSegment"/> starting at the origin and extending by the specified vector.
  92. /// </returns>
  93. public static LineSegment FromOrigin(Vector2 origin, Vector2 vector)
  94. {
  95. return new LineSegment(origin, origin + vector);
  96. }
  97. /// <summary>
  98. /// Determines whether the specified object is equal to the current line segment.
  99. /// </summary>
  100. /// <param name="obj">The object to compare with the current line segment.</param>
  101. /// <returns>
  102. /// <see langword="true"/> if the specified object is a <see cref="LineSegment"/> and is equal to the
  103. /// current line segment; otherwise, <see langword="false"/>.
  104. /// </returns>
  105. public override readonly bool Equals([NotNullWhen(true)] object obj)
  106. {
  107. return obj is LineSegment other && Equals(other);
  108. }
  109. /// <summary>
  110. /// Determines whether the specified line segment is equal to the current line segment.
  111. /// </summary>
  112. /// <param name="other">The line segment to compare with the current line segment.</param>
  113. /// <returns>
  114. /// <see langword="true"/> if the specified line segment is equal to the current line segment;
  115. /// otherwise, <see langword="false"/>.
  116. /// </returns>
  117. public readonly bool Equals(LineSegment other)
  118. {
  119. return _point1.Equals(other._point1) && _point2.Equals(other._point2);
  120. }
  121. /// <summary>
  122. /// Returns the hash code for this line segment.
  123. /// </summary>
  124. /// <returns>A 32-bit signed integer that is the hash code for this instance.</returns>
  125. public override readonly int GetHashCode()
  126. {
  127. return HashCode.Combine(_point1, _point2);
  128. }
  129. /// <summary>
  130. /// Returns a string representation of this line segment.
  131. /// </summary>
  132. /// <returns>
  133. /// A string containing the coordinates of both points in the format:
  134. /// "(x1:y1,x2:y2)".
  135. /// </returns>
  136. public override readonly string ToString()
  137. {
  138. return $"({_point1:x}:{_point1:y},{_point2:x}:{_point2:y})";
  139. }
  140. /// <summary>
  141. /// Determines whether two line segments are equal.
  142. /// </summary>
  143. /// <param name="lhs">The first line segment to compare.</param>
  144. /// <param name="rhs">The second line segment to compare.</param>
  145. /// <returns>
  146. /// <see langword="true"/> if the line segments are equal; otherwise, <see langword="false"/>.
  147. /// </returns>
  148. public static bool operator ==(LineSegment lhs, LineSegment rhs)
  149. {
  150. return lhs.Equals(rhs);
  151. }
  152. /// <summary>
  153. /// Determines whether two line segments are not equal.
  154. /// </summary>
  155. /// <param name="lhs">The first line segment to compare.</param>
  156. /// <param name="rhs">The second line segment to compare.</param>
  157. /// <returns>
  158. /// <see langword="true"/> if the line segments are not equal; otherwise, <see langword="false"/>.
  159. /// </returns>
  160. public static bool operator !=(LineSegment lhs, LineSegment rhs)
  161. {
  162. return !lhs.Equals(rhs);
  163. }
  164. }