docs(core): Vector2D

This commit is contained in:
Syntriax 2024-02-01 12:46:09 +03:00
parent ab0e868d52
commit 81a0cf645a
2 changed files with 378 additions and 10 deletions

View File

@ -1,35 +1,187 @@
namespace Syntriax.Engine.Core;
/// <summary>
/// Provides extension methods for <see cref="Vector2D"/> type.
/// </summary>
public static class Vector2DExtensions
{
/// <summary>
/// Calculates the length of the <see cref="Vector2D"/>.
/// </summary>
/// <param name="vector">The input <see cref="Vector2D"/>.</param>
/// <returns>The length of the <see cref="Vector2D"/>.</returns>
public static float Length(this Vector2D vector) => Vector2D.Length(vector);
/// <summary>
/// Calculates the squared length of the <see cref="Vector2D"/>.
/// </summary>
/// <param name="vector">The input <see cref="Vector2D"/>.</param>
/// <returns>The squared length of the <see cref="Vector2D"/>.</returns>
public static float LengthSquared(this Vector2D vector) => Vector2D.LengthSquared(vector);
/// <summary>
/// Calculates the distance between two <see cref="Vector2D"/>s.
/// </summary>
/// <param name="from">The starting <see cref="Vector2D"/>.</param>
/// <param name="to">The ending <see cref="Vector2D"/>.</param>
/// <returns>The distance between the two <see cref="Vector2D"/>s.</returns>
public static float Distance(this Vector2D from, Vector2D to) => Vector2D.Distance(from, to);
/// <summary>
/// Returns the <see cref="Vector2D"/> with its components inverted.
/// </summary>
/// <param name="vector">The input <see cref="Vector2D"/>.</param>
/// <returns>The inverted <see cref="Vector2D"/>.</returns>
public static Vector2D Invert(this Vector2D vector) => Vector2D.Invert(vector);
/// <summary>
/// Adds two <see cref="Vector2D"/>s component-wise.
/// </summary>
/// <param name="vector">The first <see cref="Vector2D"/>.</param>
/// <param name="vectorToAdd">The vector <see cref="Vector2D"/> to be added.</param>
/// <returns>The result of the addition.</returns>
public static Vector2D Add(this Vector2D vector, Vector2D vectorToAdd) => Vector2D.Add(vector, vectorToAdd);
/// <summary>
/// Subtracts one <see cref="Vector2D"/> from another component-wise.
/// </summary>
/// <param name="vector">The first <see cref="Vector2D"/>.</param>
/// <param name="vectorToSubtract">The <see cref="Vector2D"/> to be subtracted.</param>
/// <returns>The result of the subtraction.</returns>
public static Vector2D Subtract(this Vector2D vector, Vector2D vectorToSubtract) => Vector2D.Subtract(vector, vectorToSubtract);
/// <summary>
/// Multiplies a <see cref="Vector2D"/> by a scalar value.
/// </summary>
/// <param name="vector">The <see cref="Vector2D"/> to multiply.</param>
/// <param name="value">The scalar value to multiply with.</param>
/// <returns>The result of the multiplication.</returns>
public static Vector2D Multiply(this Vector2D vector, float value) => Vector2D.Multiply(vector, value);
/// <summary>
/// Divides a <see cref="Vector2D"/> by a scalar value.
/// </summary>
/// <param name="vector">The <see cref="Vector2D"/> to divide.</param>
/// <param name="value">The scalar value to divide with.</param>
/// <returns>The result of the division.</returns>
public static Vector2D Subdivide(this Vector2D vector, float value) => Vector2D.Subdivide(vector, value);
/// <summary>
/// Returns a <see cref="Vector2D"/> with the absolute values of each component.
/// </summary>
/// <param name="vector">The input <see cref="Vector2D"/>.</param>
/// <returns>The <see cref="Vector2D"/> with absolute values.</returns>
public static Vector2D Abs(this Vector2D vector) => Vector2D.Abs(vector);
/// <summary>
/// Reflects a <see cref="Vector2D"/> off a surface with the specified normal.
/// </summary>
/// <param name="vector">The <see cref="Vector2D"/> to reflect.</param>
/// <param name="normal">The normal <see cref="Vector2D"/> of the reflecting surface.</param>
/// <returns>The reflected <see cref="Vector2D"/>.</returns>
public static Vector2D Reflect(this Vector2D vector, Vector2D normal) => Vector2D.Reflect(vector, normal);
/// <summary>
/// Normalizes the <see cref="Vector2D"/> (creates a <see cref="Vector2D"/> with the same direction but with a length of 1).
/// </summary>
/// <param name="vector">The input <see cref="Vector2D"/>.</param>
/// <returns>The normalized <see cref="Vector2D"/>.</returns>
public static Vector2D Normalize(this Vector2D vector) => Vector2D.Normalize(vector);
/// <summary>
/// Creates a <see cref="Vector2D"/> pointing from one point to another.
/// </summary>
/// <param name="from">The starting point.</param>
/// <param name="to">The ending point.</param>
/// <returns>The <see cref="Vector2D"/> pointing from <paramref name="from"/> to <paramref name="to"/>.</returns>
public static Vector2D FromTo(this Vector2D from, Vector2D to) => Vector2D.FromTo(from, to);
/// <summary>
/// Scales a <see cref="Vector2D"/> by another <see cref="Vector2D"/> component-wise.
/// </summary>
/// <param name="vector">The <see cref="Vector2D"/> to scale.</param>
/// <param name="scale">The <see cref="Vector2D"/> containing the scaling factors for each component.</param>
/// <returns>The scaled <see cref="Vector2D"/>.</returns>
public static Vector2D Scale(this Vector2D vector, Vector2D scale) => Vector2D.Scale(vector, scale);
/// <summary>
/// Calculates the perpendicular <see cref="Vector2D"/> to the given <see cref="Vector2D"/>.
/// </summary>
/// <param name="vector">The input <see cref="Vector2D"/>.</param>
/// <returns>A <see cref="Vector2D"/> perpendicular to the input <see cref="Vector2D"/>.</returns>
public static Vector2D Perpendicular(this Vector2D vector) => Vector2D.Perpendicular(vector);
/// <summary>
/// Rotates a <see cref="Vector2D"/> by the specified angle (in radians).
/// </summary>
/// <param name="vector">The <see cref="Vector2D"/> to rotate.</param>
/// <param name="angleInRadian">The angle to rotate by, in radians.</param>
/// <returns>The rotated <see cref="Vector2D"/>.</returns>
public static Vector2D Rotate(this Vector2D vector, float angleInRadian) => Vector2D.Rotate(vector, angleInRadian);
/// <summary>
/// Returns the component-wise minimum of two <see cref="Vector2D"/>s.
/// </summary>
/// <param name="left">The first <see cref="Vector2D"/>.</param>
/// <param name="right">The second <see cref="Vector2D"/>.</param>
/// <returns>The <see cref="Vector2D"/> containing the minimum components from both input <see cref="Vector2D"/>s.</returns>
public static Vector2D Min(this Vector2D left, Vector2D right) => Vector2D.Min(left, right);
/// <summary>
/// Returns the component-wise maximum of two <see cref="Vector2D"/>s.
/// </summary>
/// <param name="left">The first <see cref="Vector2D"/>.</param>
/// <param name="right">The second <see cref="Vector2D"/>.</param>
/// <returns>The <see cref="Vector2D"/> containing the maximum components from both input <see cref="Vector2D"/>s.</returns>
public static Vector2D Max(this Vector2D left, Vector2D right) => Vector2D.Max(left, right);
/// <summary>
/// Clamps each component of a <see cref="Vector2D"/> between the corresponding component of two other <see cref="Vector2D"/>s.
/// </summary>
/// <param name="vector">The <see cref="Vector2D"/> to clamp.</param>
/// <param name="min">The <see cref="Vector2D"/> representing the minimum values for each component.</param>
/// <param name="max">The <see cref="Vector2D"/> representing the maximum values for each component.</param>
/// <returns>The clamped <see cref="Vector2D"/>.</returns>
public static Vector2D Clamp(this Vector2D vector, Vector2D min, Vector2D max) => Vector2D.Clamp(vector, min, max);
/// <summary>
/// Linearly interpolates between two <see cref="Vector2D"/>s.
/// </summary>
/// <param name="from">The start <see cref="Vector2D"/>.</param>
/// <param name="to">The end <see cref="Vector2D"/>.</param>
/// <param name="t">The interpolation parameter (between 0 and 1).</param>
/// <returns>The interpolated <see cref="Vector2D"/>.</returns>
public static Vector2D Lerp(this Vector2D from, Vector2D to, float t) => Vector2D.Lerp(from, to, t);
/// <summary>
/// Calculates the cross product of two <see cref="Vector2D"/>s.
/// </summary>
/// <param name="left">The first <see cref="Vector2D"/>.</param>
/// <param name="right">The second <see cref="Vector2D"/>.</param>
/// <returns>The cross product of the two <see cref="Vector2D"/>s.</returns>
public static float Cross(this Vector2D left, Vector2D right) => Vector2D.Cross(left, right);
/// <summary>
/// Calculates the angle in radians between two <see cref="Vector2D"/>s.
/// </summary>
/// <param name="left">The first <see cref="Vector2D"/>.</param>
/// <param name="right">The second <see cref="Vector2D"/>.</param>
/// <returns>The angle between the two <see cref="Vector2D"/>s in radians.</returns>
public static float AngleBetween(this Vector2D left, Vector2D right) => Vector2D.Angle(left, right);
/// <summary>
/// Calculates the dot product of two <see cref="Vector2D"/>s.
/// </summary>
/// <param name="left">The first <see cref="Vector2D"/>.</param>
/// <param name="right">The second <see cref="Vector2D"/>.</param>
/// <returns>The dot product of the two <see cref="Vector2D"/>s.</returns>
public static float Dot(this Vector2D left, Vector2D right) => Vector2D.Dot(left, right);
/// <summary>
/// Checks whether two <see cref="Vector2D"/>s are approximately equal within a certain epsilon range.
/// </summary>
/// <param name="left">The first <see cref="Vector2D"/>.</param>
/// <param name="right">The second <see cref="Vector2D"/>.</param>
/// <param name="epsilon">The maximum difference allowed between components.</param>
/// <returns>True if the <see cref="Vector2D"/>s are approximately equal, false otherwise.</returns>
public static bool ApproximatelyEquals(this Vector2D left, Vector2D right, float epsilon = float.Epsilon) => Vector2D.ApproximatelyEquals(left, right, epsilon);
}

View File

@ -2,21 +2,65 @@ using System;
namespace Syntriax.Engine.Core;
/// <summary>
/// Represents a two-dimensional vector.
/// </summary>
[System.Diagnostics.DebuggerDisplay("{ToString(),nq}, Length: {Magnitude}, LengthSquared: {MagnitudeSquared}, Normalized: {Normalized.ToString(),nq}")]
public readonly struct Vector2D(float X, float Y)
public readonly struct Vector2D(float x, float y)
{
public readonly float X { get; init; } = X;
public readonly float Y { get; init; } = Y;
/// <summary>
/// The X coordinate of the <see cref="Vector2D"/>.
/// </summary>
public readonly float X = x;
public readonly float Magnitude => Length(this);
public readonly float MagnitudeSquared => LengthSquared(this);
public readonly Vector2D Normalized => Normalize(this);
/// <summary>
/// The Y coordinate of the <see cref="Vector2D"/>.
/// </summary>
public readonly float Y = y;
/// <summary>
/// The magnitude (length) of the <see cref="Vector2D"/>.
/// </summary>
public float Magnitude => Length(this);
/// <summary>
/// The squared magnitude (length) of the <see cref="Vector2D"/>.
/// </summary>
public float MagnitudeSquared => LengthSquared(this);
/// <summary>
/// The normalized form of the <see cref="Vector2D"/> (a <see cref="Vector2D"/> with the same direction and a magnitude of 1).
/// </summary>
public Vector2D Normalized => Normalize(this);
/// <summary>
/// Represents the unit <see cref="Vector2D"/> pointing upwards.
/// </summary>
public readonly static Vector2D Up = new(0f, 1f);
/// <summary>
/// Represents the unit <see cref="Vector2D"/> pointing downwards.
/// </summary>
public readonly static Vector2D Down = new(0f, -1f);
/// <summary>
/// Represents the unit <see cref="Vector2D"/> pointing leftwards.
/// </summary>
public readonly static Vector2D Left = new(-1f, 0f);
/// <summary>
/// Represents the unit <see cref="Vector2D"/> pointing rightwards.
/// </summary>
public readonly static Vector2D Right = new(1f, 0f);
/// <summary>
/// Represents the zero <see cref="Vector2D"/>.
/// </summary>
public readonly static Vector2D Zero = new(0f, 0f);
/// <summary>
/// Represents the <see cref="Vector2D"/> with both components equal to 1.
/// </summary>
public readonly static Vector2D One = new(1f, 1f);
public static Vector2D operator -(Vector2D vector) => new(0f - vector.X, 0f - vector.Y);
@ -28,38 +72,189 @@ public readonly struct Vector2D(float X, float Y)
public static bool operator ==(Vector2D left, Vector2D right) => left.X == right.X && left.Y == right.Y;
public static bool operator !=(Vector2D left, Vector2D right) => left.X != right.X || left.Y != right.Y;
/// <summary>
/// Calculates the length of the <see cref="Vector2D"/>.
/// </summary>
/// <param name="vector">The <see cref="Vector2D"/>.</param>
/// <returns>The length of the <see cref="Vector2D"/>.</returns>
public static float Length(Vector2D vector) => MathF.Sqrt(LengthSquared(vector));
/// <summary>
/// Calculates the squared length of the <see cref="Vector2D"/>.
/// </summary>
/// <param name="vector">The <see cref="Vector2D"/>.</param>
/// <returns>The squared length of the <see cref="Vector2D"/>.</returns>
public static float LengthSquared(Vector2D vector) => vector.X * vector.X + vector.Y * vector.Y;
/// <summary>
/// Calculates the distance between two <see cref="Vector2D"/>s.
/// </summary>
/// <param name="from">The start <see cref="Vector2D"/>.</param>
/// <param name="to">The end <see cref="Vector2D"/>.</param>
/// <returns>The distance between the two <see cref="Vector2D"/>s.</returns>
public static float Distance(Vector2D from, Vector2D to) => Length(FromTo(from, to));
/// <summary>
/// Inverts the direction of the <see cref="Vector2D"/>.
/// </summary>
/// <param name="vector">The <see cref="Vector2D"/>.</param>
/// <returns>The inverted <see cref="Vector2D"/>.</returns>
public static Vector2D Invert(Vector2D vector) => -vector;
/// <summary>
/// Adds two <see cref="Vector2D"/>s.
/// </summary>
/// <param name="left">The first <see cref="Vector2D"/>.</param>
/// <param name="right">The second <see cref="Vector2D"/>.</param>
/// <returns>The sum of the two <see cref="Vector2D"/>s.</returns>
public static Vector2D Add(Vector2D left, Vector2D right) => left + right;
/// <summary>
/// Subtracts one <see cref="Vector2D"/> from another.
/// </summary>
/// <param name="left">The <see cref="Vector2D"/> to subtract from.</param>
/// <param name="right">The <see cref="Vector2D"/> to subtract.</param>
/// <returns>The result of subtracting the second <see cref="Vector2D"/> from the first.</returns>
public static Vector2D Subtract(Vector2D left, Vector2D right) => left - right;
/// <summary>
/// Multiplies a <see cref="Vector2D"/> by a scalar value.
/// </summary>
/// <param name="vector">The <see cref="Vector2D"/>.</param>
/// <param name="value">The scalar value.</param>
/// <returns>The result of multiplying the <see cref="Vector2D"/> by the scalar value.</returns>
public static Vector2D Multiply(Vector2D vector, float value) => vector * value;
/// <summary>
/// Divides a <see cref="Vector2D"/> by a scalar value.
/// </summary>
/// <param name="vector">The <see cref="Vector2D"/>.</param>
/// <param name="value">The scalar value.</param>
/// <returns>The result of dividing the <see cref="Vector2D"/> by the scalar value.</returns>
public static Vector2D Subdivide(Vector2D vector, float value) => vector / value;
/// <summary>
/// Calculates the absolute value of each component of the vector.
/// </summary>
/// <param name="vector">The <see cref="Vector2D"/>.</param>
/// <returns>The <see cref="Vector2D"/> with each component's absolute value.</returns>
public static Vector2D Abs(Vector2D vector) => new(Math.Abs(vector.X), Math.Abs(vector.Y));
/// <summary>
/// Normalizes the <see cref="Vector2D"/> (creates a unit <see cref="Vector2D"/> with the same direction).
/// </summary>
/// <param name="vector">The <see cref="Vector2D"/> to normalize.</param>
/// <returns>The normalized <see cref="Vector2D"/>.</returns>
public static Vector2D Normalize(Vector2D vector) => vector / Length(vector);
/// <summary>
/// Reflects a <see cref="Vector2D"/> off a surface with the specified normal.
/// </summary>
/// <param name="vector">The incident <see cref="Vector2D"/>.</param>
/// <param name="normal">The normal <see cref="Vector2D"/> of the surface.</param>
/// <returns>The reflected <see cref="Vector2D"/>.</returns>
public static Vector2D Reflect(Vector2D vector, Vector2D normal) => vector - 2f * Dot(vector, normal) * normal;
/// <summary>
/// Calculates the <see cref="Vector2D"/> from one point to another.
/// </summary>
/// <param name="from">The starting point.</param>
/// <param name="to">The ending point.</param>
/// <returns>The <see cref="Vector2D"/> from the starting point to the ending point.</returns>
public static Vector2D FromTo(Vector2D from, Vector2D to) => to - from;
/// <summary>
/// Scales a <see cref="Vector2D"/> by another <see cref="Vector2D"/> component-wise.
/// </summary>
/// <param name="vector">The <see cref="Vector2D"/> to scale.</param>
/// <param name="scale">The <see cref="Vector2D"/> containing the scaling factors for each component.</param>
/// <returns>The scaled <see cref="Vector2D"/>.</returns>
public static Vector2D Scale(Vector2D vector, Vector2D scale) => new(vector.X * scale.X, vector.Y * scale.Y);
/// <summary>
/// Calculates a perpendicular <see cref="Vector2D"/> to the given <see cref="Vector2D"/>.
/// </summary>
/// <param name="vector">The input <see cref="Vector2D"/>.</param>
/// <returns>A <see cref="Vector2D"/> perpendicular to the input <see cref="Vector2D"/>.</returns>
public static Vector2D Perpendicular(Vector2D vector) => new(-vector.Y, vector.X);
/// <summary>
/// Rotates a <see cref="Vector2D"/> by the specified angle (in radians).
/// </summary>
/// <param name="vector">The <see cref="Vector2D"/> to rotate.</param>
/// <param name="angleInRadian">The angle to rotate by, in radians.</param>
/// <returns>The rotated <see cref="Vector2D"/>.</returns>
public static Vector2D Rotate(Vector2D vector, float angleInRadian) => new(MathF.Cos(angleInRadian) * vector.X - MathF.Sin(angleInRadian) * vector.Y, MathF.Sin(angleInRadian) * vector.X + MathF.Cos(angleInRadian) * vector.Y);
/// <summary>
/// Returns the component-wise minimum of two <see cref="Vector2D"/>s.
/// </summary>
/// <param name="left">The first <see cref="Vector2D"/>.</param>
/// <param name="right">The second <see cref="Vector2D"/>.</param>
/// <returns>The <see cref="Vector2D"/> containing the minimum components from both input <see cref="Vector2D"/>s.</returns>
public static Vector2D Min(Vector2D left, Vector2D right) => new((left.X < right.X) ? left.X : right.X, (left.Y < right.Y) ? left.Y : right.Y);
/// <summary>
/// Returns the component-wise maximum of two <see cref="Vector2D"/>s.
/// </summary>
/// <param name="left">The first <see cref="Vector2D"/>.</param>
/// <param name="right">The second <see cref="Vector2D"/>.</param>
/// <returns>The <see cref="Vector2D"/> containing the maximum components from both input <see cref="Vector2D"/>s.</returns>
public static Vector2D Max(Vector2D left, Vector2D right) => new((left.X > right.X) ? left.X : right.X, (left.Y > right.Y) ? left.Y : right.Y);
/// <summary>
/// Clamps each component of a <see cref="Vector2D"/> between the corresponding component of two other <see cref="Vector2D"/>s.
/// </summary>
/// <param name="vector">The <see cref="Vector2D"/> to clamp.</param>
/// <param name="min">The <see cref="Vector2D"/> representing the minimum values for each component.</param>
/// <param name="max">The <see cref="Vector2D"/> representing the maximum values for each component.</param>
/// <returns>A <see cref="Vector2D"/> with each component clamped between the corresponding components of the min and max <see cref="Vector2D"/>s.</returns>
public static Vector2D Clamp(Vector2D vector, Vector2D min, Vector2D max) => new(Math.Clamp(vector.X, min.X, max.X), Math.Clamp(vector.Y, min.Y, max.Y));
/// <summary>
/// Performs linear interpolation between two <see cref="Vector2D"/>s.
/// </summary>
/// <param name="from">The starting <see cref="Vector2D"/> (t = 0).</param>
/// <param name="to">The ending <see cref="Vector2D"/> (t = 1).</param>
/// <param name="t">The interpolation parameter.</param>
/// <returns>The interpolated <see cref="Vector2D"/>.</returns>
public static Vector2D Lerp(Vector2D from, Vector2D to, float t) => from + FromTo(from, to) * t;
/// <summary>
/// Calculates the cross product of two <see cref="Vector2D"/>s.
/// </summary>
/// <param name="left">The first <see cref="Vector2D"/>.</param>
/// <param name="right">The second <see cref="Vector2D"/>.</param>
/// <returns>The cross product of the two <see cref="Vector2D"/>s.</returns>
public static float Cross(Vector2D left, Vector2D right) => left.X * right.Y - left.Y * right.X;
/// <summary>
/// Calculates the angle between two <see cref="Vector2D"/>s.
/// </summary>
/// <param name="left">The first <see cref="Vector2D"/>.</param>
/// <param name="right">The second <see cref="Vector2D"/>.</param>
/// <returns>The angle between the two <see cref="Vector2D"/>s in radians.</returns>
public static float Angle(Vector2D left, Vector2D right) => MathF.Acos(Dot(left, right) / (Length(left) * Length(right)));
/// <summary>
/// Calculates the dot product of two <see cref="Vector2D"/>s.
/// </summary>
/// <param name="left">The first <see cref="Vector2D"/>.</param>
/// <param name="right">The second <see cref="Vector2D"/>.</param>
/// <returns>The dot product of the two <see cref="Vector2D"/>s.</returns>
public static float Dot(Vector2D left, Vector2D right) => left.X * right.X + left.Y * right.Y;
/// <summary>
/// Finds the Orientation of 3 <see cref="Vector2D"/>s
/// Determines the orientation of three points represented by <see cref="Vector2D"/>s.
/// </summary>
/// <returns>0 -> Collinear, 1 -> Clockwise, 2 -> Counterclockwise</returns>
/// <param name="left">The first <see cref="Vector2D"/>.</param>
/// <param name="middle">The second <see cref="Vector2D"/>.</param>
/// <param name="right">The third <see cref="Vector2D"/>.</param>
/// <returns>
/// <para>0 - Collinear.</para>
/// <para>1 - Clockwise.</para>
/// <para>2 - Counterclockwise.</para>
/// </returns>
public static int Orientation(Vector2D left, Vector2D middle, Vector2D right)
{
Vector2D leftToMiddle = left.FromTo(middle);
@ -73,11 +268,32 @@ public readonly struct Vector2D(float X, float Y)
return 0;
}
/// <summary>
/// Checks if two <see cref="Vector2D"/>s are approximately equal within a specified epsilon range.
/// </summary>
/// <param name="left">The first <see cref="Vector2D"/>.</param>
/// <param name="right">The second <see cref="Vector2D"/>.</param>
/// <param name="epsilon">The epsilon range.</param>
/// <returns><see cref="true"/> if the <see cref="Vector2D"/>s are approximately equal; otherwise, <see cref="false"/>.</returns>
public static bool ApproximatelyEquals(Vector2D left, Vector2D right, float epsilon = float.Epsilon)
=> left.X.ApproximatelyEquals(right.X, epsilon) && left.Y.ApproximatelyEquals(right.Y, epsilon);
/// <summary>
/// Converts the <see cref="Vector2D"/> to its string representation.
/// </summary>
/// <returns>A string representation of the <see cref="Vector2D"/>.</returns>
public override string ToString() => $"{nameof(Vector2D)}({X}, {Y})";
/// <summary>
/// Determines whether the specified object is equal to the current <see cref="Vector2D"/>.
/// </summary>
/// <param name="obj">The object to compare with the current <see cref="Vector2D"/>.</param>
/// <returns><see cref="true"/> if the specified object is equal to the current <see cref="Vector2D"/>; otherwise, <see cref="false"/>.</returns>
public override bool Equals(object? obj) => obj is Vector2D objVec && X.Equals(objVec.X) && Y.Equals(objVec.Y);
/// <summary>
/// Generates a hash code for the <see cref="Vector2D"/>.
/// </summary>
/// <returns>A hash code for the <see cref="Vector2D"/>.</returns>
public override int GetHashCode() => HashCode.Combine(X, Y);
}