mirror of
https://github.com/AlexMacocian/MonoGame.Extended.git
synced 2026-07-15 15:09:29 +00:00
Fix Invert(ref Matrix3x2) (#962)
* 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
This commit is contained in:
@@ -562,14 +562,21 @@ public struct Matrix3x2 : IEquatable<Matrix3x2>
|
||||
{
|
||||
var det = 1.0f / matrix.Determinant();
|
||||
|
||||
matrix.M11 = matrix.M22 * det;
|
||||
matrix.M12 = -matrix.M12 * det;
|
||||
if (float.IsInfinity(det)) // Det(M) = 0
|
||||
{
|
||||
matrix = Identity;
|
||||
return;
|
||||
}
|
||||
|
||||
matrix.M21 = -matrix.M21 * det;
|
||||
matrix.M22 = matrix.M11 * det;
|
||||
|
||||
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>
|
||||
|
||||
@@ -17,4 +17,20 @@ public sealed class Matrix3x2Tests
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user