Skip to content

Commit

Permalink
Fix Invert(ref Matrix3x2) (#962)
Browse files Browse the repository at this point in the history
* 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"

* Add unit test for Matrix3x2.Invert
  • Loading branch information
Eb3yr authored Nov 8, 2024
1 parent d3b4482 commit 8b02498
Show file tree
Hide file tree
Showing 2 changed files with 30 additions and 7 deletions.
21 changes: 14 additions & 7 deletions source/MonoGame.Extended/Math/Matrix3x2.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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
);
}

/// <summary>
Expand Down
16 changes: 16 additions & 0 deletions tests/MonoGame.Extended.Tests/Math/Matrix3x2.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
}

0 comments on commit 8b02498

Please sign in to comment.