From 81a0cf645a5ed41d4b9e1fc87d470269763f2d86 Mon Sep 17 00:00:00 2001 From: Syntriax Date: Thu, 1 Feb 2024 12:46:09 +0300 Subject: [PATCH] docs(core): Vector2D --- Engine.Core/Extensions/Vector2DExtensions.cs | 156 ++++++++++++- Engine.Core/Vector2D.cs | 232 ++++++++++++++++++- 2 files changed, 378 insertions(+), 10 deletions(-) diff --git a/Engine.Core/Extensions/Vector2DExtensions.cs b/Engine.Core/Extensions/Vector2DExtensions.cs index 29995da..3bbd33e 100644 --- a/Engine.Core/Extensions/Vector2DExtensions.cs +++ b/Engine.Core/Extensions/Vector2DExtensions.cs @@ -1,35 +1,187 @@ namespace Syntriax.Engine.Core; - +/// +/// Provides extension methods for type. +/// public static class Vector2DExtensions { + /// + /// Calculates the length of the . + /// + /// The input . + /// The length of the . public static float Length(this Vector2D vector) => Vector2D.Length(vector); + + /// + /// Calculates the squared length of the . + /// + /// The input . + /// The squared length of the . public static float LengthSquared(this Vector2D vector) => Vector2D.LengthSquared(vector); + /// + /// Calculates the distance between two s. + /// + /// The starting . + /// The ending . + /// The distance between the two s. public static float Distance(this Vector2D from, Vector2D to) => Vector2D.Distance(from, to); + /// + /// Returns the with its components inverted. + /// + /// The input . + /// The inverted . public static Vector2D Invert(this Vector2D vector) => Vector2D.Invert(vector); + + /// + /// Adds two s component-wise. + /// + /// The first . + /// The vector to be added. + /// The result of the addition. public static Vector2D Add(this Vector2D vector, Vector2D vectorToAdd) => Vector2D.Add(vector, vectorToAdd); + + /// + /// Subtracts one from another component-wise. + /// + /// The first . + /// The to be subtracted. + /// The result of the subtraction. public static Vector2D Subtract(this Vector2D vector, Vector2D vectorToSubtract) => Vector2D.Subtract(vector, vectorToSubtract); + + /// + /// Multiplies a by a scalar value. + /// + /// The to multiply. + /// The scalar value to multiply with. + /// The result of the multiplication. public static Vector2D Multiply(this Vector2D vector, float value) => Vector2D.Multiply(vector, value); + + /// + /// Divides a by a scalar value. + /// + /// The to divide. + /// The scalar value to divide with. + /// The result of the division. public static Vector2D Subdivide(this Vector2D vector, float value) => Vector2D.Subdivide(vector, value); + /// + /// Returns a with the absolute values of each component. + /// + /// The input . + /// The with absolute values. public static Vector2D Abs(this Vector2D vector) => Vector2D.Abs(vector); + + /// + /// Reflects a off a surface with the specified normal. + /// + /// The to reflect. + /// The normal of the reflecting surface. + /// The reflected . public static Vector2D Reflect(this Vector2D vector, Vector2D normal) => Vector2D.Reflect(vector, normal); + + /// + /// Normalizes the (creates a with the same direction but with a length of 1). + /// + /// The input . + /// The normalized . public static Vector2D Normalize(this Vector2D vector) => Vector2D.Normalize(vector); + + /// + /// Creates a pointing from one point to another. + /// + /// The starting point. + /// The ending point. + /// The pointing from to . public static Vector2D FromTo(this Vector2D from, Vector2D to) => Vector2D.FromTo(from, to); + + /// + /// Scales a by another component-wise. + /// + /// The to scale. + /// The containing the scaling factors for each component. + /// The scaled . public static Vector2D Scale(this Vector2D vector, Vector2D scale) => Vector2D.Scale(vector, scale); + /// + /// Calculates the perpendicular to the given . + /// + /// The input . + /// A perpendicular to the input . public static Vector2D Perpendicular(this Vector2D vector) => Vector2D.Perpendicular(vector); + + /// + /// Rotates a by the specified angle (in radians). + /// + /// The to rotate. + /// The angle to rotate by, in radians. + /// The rotated . public static Vector2D Rotate(this Vector2D vector, float angleInRadian) => Vector2D.Rotate(vector, angleInRadian); + + /// + /// Returns the component-wise minimum of two s. + /// + /// The first . + /// The second . + /// The containing the minimum components from both input s. public static Vector2D Min(this Vector2D left, Vector2D right) => Vector2D.Min(left, right); + + /// + /// Returns the component-wise maximum of two s. + /// + /// The first . + /// The second . + /// The containing the maximum components from both input s. public static Vector2D Max(this Vector2D left, Vector2D right) => Vector2D.Max(left, right); + + /// + /// Clamps each component of a between the corresponding component of two other s. + /// + /// The to clamp. + /// The representing the minimum values for each component. + /// The representing the maximum values for each component. + /// The clamped . public static Vector2D Clamp(this Vector2D vector, Vector2D min, Vector2D max) => Vector2D.Clamp(vector, min, max); + + /// + /// Linearly interpolates between two s. + /// + /// The start . + /// The end . + /// The interpolation parameter (between 0 and 1). + /// The interpolated . public static Vector2D Lerp(this Vector2D from, Vector2D to, float t) => Vector2D.Lerp(from, to, t); + /// + /// Calculates the cross product of two s. + /// + /// The first . + /// The second . + /// The cross product of the two s. public static float Cross(this Vector2D left, Vector2D right) => Vector2D.Cross(left, right); + + /// + /// Calculates the angle in radians between two s. + /// + /// The first . + /// The second . + /// The angle between the two s in radians. public static float AngleBetween(this Vector2D left, Vector2D right) => Vector2D.Angle(left, right); + + /// + /// Calculates the dot product of two s. + /// + /// The first . + /// The second . + /// The dot product of the two s. public static float Dot(this Vector2D left, Vector2D right) => Vector2D.Dot(left, right); - + /// + /// Checks whether two s are approximately equal within a certain epsilon range. + /// + /// The first . + /// The second . + /// The maximum difference allowed between components. + /// True if the s are approximately equal, false otherwise. public static bool ApproximatelyEquals(this Vector2D left, Vector2D right, float epsilon = float.Epsilon) => Vector2D.ApproximatelyEquals(left, right, epsilon); } diff --git a/Engine.Core/Vector2D.cs b/Engine.Core/Vector2D.cs index bbf9399..29cc880 100644 --- a/Engine.Core/Vector2D.cs +++ b/Engine.Core/Vector2D.cs @@ -2,21 +2,65 @@ using System; namespace Syntriax.Engine.Core; +/// +/// Represents a two-dimensional vector. +/// [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; + /// + /// The X coordinate of the . + /// + public readonly float X = x; - public readonly float Magnitude => Length(this); - public readonly float MagnitudeSquared => LengthSquared(this); - public readonly Vector2D Normalized => Normalize(this); + /// + /// The Y coordinate of the . + /// + public readonly float Y = y; + /// + /// The magnitude (length) of the . + /// + public float Magnitude => Length(this); + + /// + /// The squared magnitude (length) of the . + /// + public float MagnitudeSquared => LengthSquared(this); + + /// + /// The normalized form of the (a with the same direction and a magnitude of 1). + /// + public Vector2D Normalized => Normalize(this); + + /// + /// Represents the unit pointing upwards. + /// public readonly static Vector2D Up = new(0f, 1f); + + /// + /// Represents the unit pointing downwards. + /// public readonly static Vector2D Down = new(0f, -1f); + + /// + /// Represents the unit pointing leftwards. + /// public readonly static Vector2D Left = new(-1f, 0f); + + /// + /// Represents the unit pointing rightwards. + /// public readonly static Vector2D Right = new(1f, 0f); + + /// + /// Represents the zero . + /// public readonly static Vector2D Zero = new(0f, 0f); + + /// + /// Represents the with both components equal to 1. + /// 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; + /// + /// Calculates the length of the . + /// + /// The . + /// The length of the . public static float Length(Vector2D vector) => MathF.Sqrt(LengthSquared(vector)); + + /// + /// Calculates the squared length of the . + /// + /// The . + /// The squared length of the . public static float LengthSquared(Vector2D vector) => vector.X * vector.X + vector.Y * vector.Y; + /// + /// Calculates the distance between two s. + /// + /// The start . + /// The end . + /// The distance between the two s. public static float Distance(Vector2D from, Vector2D to) => Length(FromTo(from, to)); + /// + /// Inverts the direction of the . + /// + /// The . + /// The inverted . public static Vector2D Invert(Vector2D vector) => -vector; + + /// + /// Adds two s. + /// + /// The first . + /// The second . + /// The sum of the two s. public static Vector2D Add(Vector2D left, Vector2D right) => left + right; + + /// + /// Subtracts one from another. + /// + /// The to subtract from. + /// The to subtract. + /// The result of subtracting the second from the first. public static Vector2D Subtract(Vector2D left, Vector2D right) => left - right; + + /// + /// Multiplies a by a scalar value. + /// + /// The . + /// The scalar value. + /// The result of multiplying the by the scalar value. public static Vector2D Multiply(Vector2D vector, float value) => vector * value; + + /// + /// Divides a by a scalar value. + /// + /// The . + /// The scalar value. + /// The result of dividing the by the scalar value. public static Vector2D Subdivide(Vector2D vector, float value) => vector / value; + /// + /// Calculates the absolute value of each component of the vector. + /// + /// The . + /// The with each component's absolute value. public static Vector2D Abs(Vector2D vector) => new(Math.Abs(vector.X), Math.Abs(vector.Y)); + + /// + /// Normalizes the (creates a unit with the same direction). + /// + /// The to normalize. + /// The normalized . public static Vector2D Normalize(Vector2D vector) => vector / Length(vector); + + /// + /// Reflects a off a surface with the specified normal. + /// + /// The incident . + /// The normal of the surface. + /// The reflected . public static Vector2D Reflect(Vector2D vector, Vector2D normal) => vector - 2f * Dot(vector, normal) * normal; + + /// + /// Calculates the from one point to another. + /// + /// The starting point. + /// The ending point. + /// The from the starting point to the ending point. public static Vector2D FromTo(Vector2D from, Vector2D to) => to - from; + + /// + /// Scales a by another component-wise. + /// + /// The to scale. + /// The containing the scaling factors for each component. + /// The scaled . public static Vector2D Scale(Vector2D vector, Vector2D scale) => new(vector.X * scale.X, vector.Y * scale.Y); + /// + /// Calculates a perpendicular to the given . + /// + /// The input . + /// A perpendicular to the input . public static Vector2D Perpendicular(Vector2D vector) => new(-vector.Y, vector.X); + + /// + /// Rotates a by the specified angle (in radians). + /// + /// The to rotate. + /// The angle to rotate by, in radians. + /// The rotated . 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); + + /// + /// Returns the component-wise minimum of two s. + /// + /// The first . + /// The second . + /// The containing the minimum components from both input s. 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); + + /// + /// Returns the component-wise maximum of two s. + /// + /// The first . + /// The second . + /// The containing the maximum components from both input s. 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); + + /// + /// Clamps each component of a between the corresponding component of two other s. + /// + /// The to clamp. + /// The representing the minimum values for each component. + /// The representing the maximum values for each component. + /// A with each component clamped between the corresponding components of the min and max s. 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)); + + /// + /// Performs linear interpolation between two s. + /// + /// The starting (t = 0). + /// The ending (t = 1). + /// The interpolation parameter. + /// The interpolated . public static Vector2D Lerp(Vector2D from, Vector2D to, float t) => from + FromTo(from, to) * t; + /// + /// Calculates the cross product of two s. + /// + /// The first . + /// The second . + /// The cross product of the two s. public static float Cross(Vector2D left, Vector2D right) => left.X * right.Y - left.Y * right.X; + + /// + /// Calculates the angle between two s. + /// + /// The first . + /// The second . + /// The angle between the two s in radians. public static float Angle(Vector2D left, Vector2D right) => MathF.Acos(Dot(left, right) / (Length(left) * Length(right))); + + /// + /// Calculates the dot product of two s. + /// + /// The first . + /// The second . + /// The dot product of the two s. public static float Dot(Vector2D left, Vector2D right) => left.X * right.X + left.Y * right.Y; /// - /// Finds the Orientation of 3 s + /// Determines the orientation of three points represented by s. /// - /// 0 -> Collinear, 1 -> Clockwise, 2 -> Counterclockwise + /// The first . + /// The second . + /// The third . + /// + /// 0 - Collinear. + /// 1 - Clockwise. + /// 2 - Counterclockwise. + /// 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; } + /// + /// Checks if two s are approximately equal within a specified epsilon range. + /// + /// The first . + /// The second . + /// The epsilon range. + /// if the s are approximately equal; otherwise, . public static bool ApproximatelyEquals(Vector2D left, Vector2D right, float epsilon = float.Epsilon) => left.X.ApproximatelyEquals(right.X, epsilon) && left.Y.ApproximatelyEquals(right.Y, epsilon); + /// + /// Converts the to its string representation. + /// + /// A string representation of the . public override string ToString() => $"{nameof(Vector2D)}({X}, {Y})"; + /// + /// Determines whether the specified object is equal to the current . + /// + /// The object to compare with the current . + /// if the specified object is equal to the current ; otherwise, . public override bool Equals(object? obj) => obj is Vector2D objVec && X.Equals(objVec.X) && Y.Equals(objVec.Y); + + /// + /// Generates a hash code for the . + /// + /// A hash code for the . public override int GetHashCode() => HashCode.Combine(X, Y); }