// Copyright (c) Craftwork Games. All rights reserved. // Licensed under the MIT license. // See LICENSE file in the project root for full license information. using System; using System.Diagnostics.CodeAnalysis; using Microsoft.Xna.Framework; using System.Runtime.InteropServices; namespace MonoGame.Extended.Particles.Primitives; /// /// Represents a line segment defined by two points in 2D space. /// [StructLayout(LayoutKind.Sequential)] public readonly struct LineSegment : IEquatable { /// /// The first point of the line segment. /// internal readonly Vector2 _point1; /// /// The second point of the line segment. /// internal readonly Vector2 _point2; /// /// Gets the origin point of the line segment. /// /// The first point of the line segment. public readonly Vector2 Origin { get { return _point1; } } /// /// Gets the direction vector of the line segment. /// /// A vector from the first point to the second point. public readonly Vector2 Direction { get { return _point2 - _point1; } } /// /// Initializes a new instance of the struct with the specified points. /// /// The first point of the line segment. /// The second point of the line segment. public LineSegment(Vector2 point1, Vector2 point2) { _point1 = point1; _point2 = point2; } /// /// Returns a new line segment that is a translated version of this line segment. /// /// The vector by which to translate the line segment. /// A new that is offset by the specified vector. public LineSegment Translate(Vector2 vector) { return new LineSegment(_point1 + vector, _point2 + vector); } /// /// Converts the line segment to a vector representing its direction and magnitude. /// /// /// A representing the direction and length of the line segment, calculated as the second /// point minus the first point. /// public Vector2 ToVector2() { return _point2 - _point1; } /// /// Creates a new line segment from two points. /// /// The first point of the line segment. /// The second point of the line segment. /// A new defined by the two points. public static LineSegment FromPoints(Vector2 point1, Vector2 point2) { return new LineSegment(point1, point2); } /// /// Creates a new line segment from an origin point and a direction vector. /// /// The starting point of the line segment. /// The direction and length vector of the line segment. /// /// A new starting at the origin and extending by the specified vector. /// public static LineSegment FromOrigin(Vector2 origin, Vector2 vector) { return new LineSegment(origin, origin + vector); } /// /// Determines whether the specified object is equal to the current line segment. /// /// The object to compare with the current line segment. /// /// if the specified object is a and is equal to the /// current line segment; otherwise, . /// public override readonly bool Equals([NotNullWhen(true)] object obj) { return obj is LineSegment other && Equals(other); } /// /// Determines whether the specified line segment is equal to the current line segment. /// /// The line segment to compare with the current line segment. /// /// if the specified line segment is equal to the current line segment; /// otherwise, . /// public readonly bool Equals(LineSegment other) { return _point1.Equals(other._point1) && _point2.Equals(other._point2); } /// /// Returns the hash code for this line segment. /// /// A 32-bit signed integer that is the hash code for this instance. public override readonly int GetHashCode() { return HashCode.Combine(_point1, _point2); } /// /// Returns a string representation of this line segment. /// /// /// A string containing the coordinates of both points in the format: /// "(x1:y1,x2:y2)". /// public override readonly string ToString() { return $"({_point1:x}:{_point1:y},{_point2:x}:{_point2:y})"; } /// /// Determines whether two line segments are equal. /// /// The first line segment to compare. /// The second line segment to compare. /// /// if the line segments are equal; otherwise, . /// public static bool operator ==(LineSegment lhs, LineSegment rhs) { return lhs.Equals(rhs); } /// /// Determines whether two line segments are not equal. /// /// The first line segment to compare. /// The second line segment to compare. /// /// if the line segments are not equal; otherwise, . /// public static bool operator !=(LineSegment lhs, LineSegment rhs) { return !lhs.Equals(rhs); } }