Consider the following test code:
using System;
using System.Drawing;
using System.Drawing.Drawing2D;
public class Program
{
public static void Main()
{
var matrix = new Matrix(123, 24, 82, 16, 47, 30);
Console.WriteLine(matrix.IsInvertible);
Console.WriteLine(matrix.Elements[0] + ", " + matrix.Elements[1] + ", " + matrix.Elements[2] + ", " + matrix.Elements[3]+ ", " + matrix.Elements[4]+ ", " + matrix.Elements[5]);
matrix.Rotate(90);
Console.WriteLine(matrix.IsInvertible);
Console.WriteLine(matrix.Elements[0] + ", " + matrix.Elements[1] + ", " + matrix.Elements[2] + ", " + matrix.Elements[3]+ ", " + matrix.Elements[4]+ ", " + matrix.Elements[5]);
matrix.Rotate(-90);
Console.WriteLine(matrix.IsInvertible);
Console.WriteLine(matrix.Elements[0] + ", " + matrix.Elements[1] + ", " + matrix.Elements[2] + ", " + matrix.Elements[3]+ ", " + matrix.Elements[4]+ ", " + matrix.Elements[5]);
}
}
On my machine it output
IsInvertible: False
Elements: 123, 24, 82, 16, 47, 30
IsInvertible: True
Elements: 82, 16, -123, -24, 47, 30
IsInvertible: True
Elements: 123, 24, 82, 16, 47, 30
This result surprises me - I rotated a non-invertible matrix then reversed the rotate giving me exactly the same elements. But then how come the matrix is no longer non invertible? What is the cause of this quirk?
The answer to this is "loss of precision".
The array that you supply is indeed not invertable.
However, when you rotate it by 90 degrees and back again, rounding errors have caused the original numbers to become different by a small amount - enough that the matrix is now invertable.
If you add .ToString("r")
to each of the WriteLines to print the full number, you'll see this:
122.999985, 23.9999962, 82, 16, 47, 30
Note how the first two numbers have changed.
Also note that you can print the result out a bit more succinctly like so:
Console.WriteLine(string.Join(", ", matrix.Elements.Select(n => n.ToString("r"))));