Search code examples
c#mathnet-numerics

How to get translation matrix 2D for coordinates transformation


I have two 2D coordinate systems A and B. I know how 3 points from the coordinate system A are translated into the coordinate system B.

A1[x, y] => B1[x, y]
A2[x, y] => B2[x, y]
A3[x, y] => B3[x, y]

Now, I have a point A4 from the coordinate system A and I need to calculate a point B4 it's position in the coordinate system B.

I don't know how to calculate a translation matrix from points A1, A2, A3, B1, B2, B3 and how to use this matrix to calculate the point B4 from A4 using C#.

I didn't find any useful classes or methods in .NET framework documentation.

I've checked the MathNet library but this library is so huge that it makes the MathNet library unreadable for a newbie.


Solution

  • Given the list of point-pairs

    IReadOnlyList<(Vector2 A, Vector2 B)> list
    

    you can find the transform between points A and B with:

        var nRows = list.Count* 2;
        const int nCols = 6;
        var A = new DenseMatrix(nRows, nCols);
        var b = new DenseMatrix(nRows, 1);
    
        for (var p = 0; p < list.Count; p++)
        {
            var row = p * 2;
            A[row, 0] = list[p].A.X;
            A[row, 1] = list[p].A.Y;
            A[row, 2] = 1;
            b[row, 0] = list[p].B.X;
            row++;
            A[row, 3] = list[p].A.X;
            A[row, 4] = list[p].A.Y;
            A[row, 5] = 1;
            b[row, 0] = list[p].B.Y;
        }
        var x = A.Solve(b);
        var affine = new Matrix3x2(
            (float)x[0, 0], 
            (float)x[3, 0], 
            (float)x[1, 0], 
            (float)x[4, 0], 
            (float)x[2, 0], 
            (float)x[5, 0]) ;
    

    This uses Math.net.Numerics as the matrix solver, and System.Numerics.Matrix3x2 for the result. This is for affine transforms using 3+ point pairs. You can also calculate the homography in a similar way, but the math is a bit different.

    use Vector2.Transform to apply the transformation