From c04d9c91d565b55539681593a1cb1201da40f065 Mon Sep 17 00:00:00 2001 From: Eb3yr Date: Fri, 8 Nov 2024 16:40:05 +0000 Subject: [PATCH 1/2] Fix Invert(ref Matrix3x2) * erroneous results were given by matrix fields being altered sequentially, some fields would use new state instead of the input * Check for matrix.Determinant() = 0, now returns the identity instead of det becoming infinite" --- source/MonoGame.Extended/Math/Matrix3x2.cs | 21 ++++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/source/MonoGame.Extended/Math/Matrix3x2.cs b/source/MonoGame.Extended/Math/Matrix3x2.cs index 94d997fde..c891ccbed 100644 --- a/source/MonoGame.Extended/Math/Matrix3x2.cs +++ b/source/MonoGame.Extended/Math/Matrix3x2.cs @@ -562,14 +562,21 @@ public static void Invert(ref Matrix3x2 matrix) { var det = 1.0f / matrix.Determinant(); - matrix.M11 = matrix.M22 * det; - matrix.M12 = -matrix.M12 * det; - - matrix.M21 = -matrix.M21 * det; - matrix.M22 = matrix.M11 * det; + if (float.IsInfinity(det)) // Det(M) = 0 + { + matrix = Identity; + return; + } - matrix.M31 = (matrix.M32 * matrix.M21 - matrix.M31 * matrix.M22) * det; - matrix.M32 = -(matrix.M32 * matrix.M11 - matrix.M31 * matrix.M12) * det; + // The new 3x2 matrix is the first and second column of the inverse of the 3x3 matrix given by adding the third column (0, 0, 1) to the input matrix + matrix = new( + matrix.M22 * det, + -matrix.M12 * det, + -matrix.M21 * det, + matrix.M11 * det, + (matrix.M32 * matrix.M21 - matrix.M31 * matrix.M22) * det, + (matrix.M31 * matrix.M12 - matrix.M32 * matrix.M11) * det + ); } /// From f91e141da1a4a76b0753ffbde11a3eee2e9c442a Mon Sep 17 00:00:00 2001 From: Eb3yr Date: Fri, 8 Nov 2024 18:52:38 +0000 Subject: [PATCH 2/2] Add unit test for Matrix3x2.Invert --- tests/MonoGame.Extended.Tests/Math/Matrix3x2.cs | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/tests/MonoGame.Extended.Tests/Math/Matrix3x2.cs b/tests/MonoGame.Extended.Tests/Math/Matrix3x2.cs index 56ab1e7b1..3a100ec6e 100644 --- a/tests/MonoGame.Extended.Tests/Math/Matrix3x2.cs +++ b/tests/MonoGame.Extended.Tests/Math/Matrix3x2.cs @@ -17,4 +17,20 @@ public void ConstructorTest() Assert.Equal(y, matrix.Y); Assert.Equal(z, matrix.Z); } + + [Fact] + public void InverseTest() + { + Matrix3x2 posDeterminant = new Matrix3x2(3, -7, 4, 2, 13, -2); + Matrix3x2 singular = new Matrix3x2(2, 1, 4, 2, 3, -4); + Matrix3x2 negDeterminant = new Matrix3x2(1, -5, 3, 2, 3, -4); + + Matrix3x2 posExpected = new Matrix3x2(1f/17, 7f/34, -2f/17, 3f/34, -1f, -5f/2); + Matrix3x2 singularExpected = Matrix3x2.Identity; + Matrix3x2 negExpected = new Matrix3x2(2f/17, 5f/17, -3f/17, 1f/17, -18f/17, -11f/17); + + Assert.Equal(Matrix3x2.Invert(posDeterminant), posExpected); + Assert.Equal(Matrix3x2.Invert(singular), singularExpected); + Assert.Equal(Matrix3x2.Invert(negDeterminant), negExpected); + } }