/// <summary>Attempts to invert the given matrix. If the operation succeeds, the inverted matrix is stored in the result parameter.</summary> /// <param name="matrix">The source matrix.</param> /// <param name="result">The output matrix.</param> /// <returns>True if the operation succeeded, False otherwise.</returns> public static bool Invert <T>(Matrix3X2 <T> matrix, out Matrix3X2 <T> result) where T : unmanaged, IFormattable, IEquatable <T>, IComparable <T> { T det = Scalar.Subtract(Scalar.Multiply(matrix.M11, matrix.M22), Scalar.Multiply(matrix.M21, matrix.M12)); if (!Scalar.GreaterThanOrEqual(Scalar.Abs(det), Scalar <T> .Epsilon)) { result = new(Scalar <T> .NaN, Scalar <T> .NaN, Scalar <T> .NaN, Scalar <T> .NaN, Scalar <T> .NaN, Scalar <T> .NaN); return(false); } T invDet = Scalar.Reciprocal(det); result = default; result.M11 = Scalar.Multiply(matrix.M22, invDet); result.M12 = Scalar.Negate(Scalar.Multiply(matrix.M12, invDet)); result.M21 = Scalar.Negate(Scalar.Multiply(matrix.M21, invDet)); result.M22 = Scalar.Multiply(matrix.M11, invDet); result.M31 = Scalar.Multiply(Scalar.Subtract(Scalar.Multiply(matrix.M21, matrix.M32), Scalar.Multiply(matrix.M31, matrix.M22)), invDet); result.M32 = Scalar.Multiply(Scalar.Subtract(Scalar.Multiply(matrix.M31, matrix.M12), Scalar.Multiply(matrix.M11, matrix.M32)), invDet); return(true); }
/// <summary>Linearly interpolates from matrix1 to matrix2, based on the third parameter.</summary> /// <param name="matrix1">The first source matrix.</param> /// <param name="matrix2">The second source matrix.</param> /// <param name="amount">The relative weighting of matrix2.</param> /// <returns>The interpolated matrix.</returns> public static Matrix3X2 <T> Lerp <T>(Matrix3X2 <T> matrix1, Matrix3X2 <T> matrix2, T amount) where T : unmanaged, IFormattable, IEquatable <T>, IComparable <T> { return(new(Vector2D.Lerp(matrix1.Row1, matrix2.Row1, amount), Vector2D.Lerp(matrix1.Row2, matrix2.Row2, amount), Vector2D.Lerp(matrix1.Row3, matrix2.Row3, amount))); }
/// <summary>Creates a translation matrix from the given vector.</summary> /// <param name="position">The translation position.</param> ` /// <returns>A translation matrix.</returns> public static Matrix3X2 <T> CreateTranslation <T>(Vector2D <T> position) where T : unmanaged, IFormattable, IEquatable <T>, IComparable <T> { Matrix3X2 <T> result = Matrix3X2 <T> .Identity; result.M31 = position.X; result.M32 = position.Y; return(result); }
/// <summary>Creates a translation matrix from the given X and Y components.</summary> /// <param name="xPosition">The X position.</param> /// <param name="yPosition">The Y position.</param> /// <returns>A translation matrix.</returns> public static Matrix3X2 <T> CreateTranslation <T>(T xPosition, T yPosition) where T : unmanaged, IFormattable, IEquatable <T>, IComparable <T> { Matrix3X2 <T> result = Matrix3X2 <T> .Identity; result.M31 = xPosition; result.M32 = yPosition; return(result); }
/// <summary>Creates a scale matrix that scales uniformly with the given scale.</summary> /// <param name="scale">The uniform scale to use.</param> /// <returns>A scaling matrix.</returns> public static Matrix3X2 <T> CreateScale <T>(T scale) where T : unmanaged, IFormattable, IEquatable <T>, IComparable <T> { Matrix3X2 <T> result = Matrix3X2 <T> .Identity; result.M11 = scale; result.M22 = scale; return(result); }
/// <summary>Creates a skew matrix from the given angles in radians.</summary> /// <param name="radiansX">The X angle, in radians.</param> /// <param name="radiansY">The Y angle, in radians.</param> /// <returns>A skew matrix.</returns> public static Matrix3X2 <T> CreateSkew <T>(T radiansX, T radiansY) where T : unmanaged, IFormattable, IEquatable <T>, IComparable <T> { Matrix3X2 <T> result = Matrix3X2 <T> .Identity; T xTan = Scalar.Tan(radiansX); T yTan = Scalar.Tan(radiansY); result.M12 = yTan; result.M21 = xTan; return(result); }
/// <summary>Creates a scale matrix that scales uniformly with the given scale with an offset from the given center.</summary> /// <param name="scale">The uniform scale to use.</param> /// <param name="centerPoint">The center offset.</param> /// <returns>A scaling matrix.</returns> public static Matrix3X2 <T> CreateScale <T>(T scale, Vector2D <T> centerPoint) where T : unmanaged, IFormattable, IEquatable <T>, IComparable <T> { Matrix3X2 <T> result = Matrix3X2 <T> .Identity; T tx = Scalar.Multiply(centerPoint.X, Scalar.Subtract(Scalar <T> .One, scale)); T ty = Scalar.Multiply(centerPoint.Y, Scalar.Subtract(Scalar <T> .One, scale)); result.M11 = scale; result.M22 = scale; result.M31 = tx; result.M32 = ty; return(result); }
/// <summary>Creates a skew matrix from the given angles in radians and a center point.</summary> /// <param name="radiansX">The X angle, in radians.</param> /// <param name="radiansY">The Y angle, in radians.</param> /// <param name="centerPoint">The center point.</param> /// <returns>A skew matrix.</returns> public static Matrix3X2 <T> CreateSkew <T>(T radiansX, T radiansY, Vector2D <T> centerPoint) where T : unmanaged, IFormattable, IEquatable <T>, IComparable <T> { Matrix3X2 <T> result = Matrix3X2 <T> .Identity; T xTan = Scalar.Tan(radiansX); T yTan = Scalar.Tan(radiansY); T tx = Scalar.Negate(Scalar.Multiply(centerPoint.Y, xTan)); T ty = Scalar.Negate(Scalar.Multiply(centerPoint.X, yTan)); result.M12 = yTan; result.M21 = xTan; result.M31 = tx; result.M32 = ty; return(result); }
public static Matrix3X2 <T> Subtract <T>(Matrix3X2 <T> value1, Matrix3X2 <T> value2) where T : unmanaged, IFormattable, IEquatable <T>, IComparable <T> => value1 - value2;
public static Matrix3X2 <T> Negate <T>(Matrix3X2 <T> value) where T : unmanaged, IFormattable, IEquatable <T>, IComparable <T> => - value;
public static Matrix3X2 <T> Multiply <T>(Matrix3X2 <T> value1, T value2) where T : unmanaged, IFormattable, IEquatable <T>, IComparable <T> => value1 * value2;
/// <summary>Creates a rotation matrix using the given rotation in radians.</summary> /// <param name="radians">The amount of rotation, in radians.</param> /// <returns>A rotation matrix.</returns> public static Matrix3X2 <T> CreateRotation <T>(T radians) where T : unmanaged, IFormattable, IEquatable <T>, IComparable <T> { radians = Scalar.IEEERemainder(radians, Scalar <T> .Tau); T c, s; if (Scalar.GreaterThan(radians, Scalar.As <float, T>(-RotationEpsilon)) && !Scalar.GreaterThanOrEqual(radians, Scalar.As <float, T>(RotationEpsilon))) { // Exact case for zero rotation. c = Scalar <T> .One; s = Scalar <T> .Zero; } else if (Scalar.GreaterThan(radians, Scalar.As <float, T>( #if MATHF MathF.PI #else ((float)Math.PI) #endif / 2 - RotationEpsilon)) && !Scalar.GreaterThanOrEqual(radians, Scalar.As <float, T>( #if MATHF MathF.PI #else ((float)Math.PI) #endif / 2 + RotationEpsilon))) { // Exact case for 90 degree rotation. c = Scalar <T> .Zero; s = Scalar <T> .One; } else if (!Scalar.GreaterThanOrEqual(radians, Scalar.As <float, T>(- #if MATHF MathF.PI #else ((float)Math.PI) #endif + RotationEpsilon)) || Scalar.GreaterThan(radians, Scalar.As <float, T>( #if MATHF MathF.PI #else ((float)Math.PI) #endif - RotationEpsilon))) { // Exact case for 180 degree rotation. c = Scalar <T> .MinusOne; s = Scalar <T> .Zero; } else if (Scalar.GreaterThan(radians, Scalar.As <float, T>(- #if MATHF MathF.PI #else ((float)Math.PI) #endif / 2 - RotationEpsilon)) && !Scalar.GreaterThanOrEqual(radians, Scalar.As <float, T>(- #if MATHF MathF.PI #else ((float)Math.PI) #endif / 2 + RotationEpsilon))) { // Exact case for 270 degree rotation. c = Scalar <T> .Zero; s = Scalar <T> .MinusOne; } else { // Arbitrary rotation. c = Scalar.Cos(radians); s = Scalar.Sin(radians); } // [ c s ] // [ -s c ] // [ 0 0 ] Matrix3X2 <T> result = Matrix3X2 <T> .Identity; result.M11 = c; result.M12 = s; result.M21 = Scalar.Negate(s); result.M22 = c; return(result); }