| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275 | 
							- using System;
 
- using System.Diagnostics;
 
- using o0.Geometry2D.Float;
 
- // 其实这个类内部是用Double计算的
 
- namespace ZIM
 
- {
 
-     // 来源 https://web.archive.org/web/20150222120106/xenia.media.mit.edu/~cwren/interpolator/
 
-     public class ZIMPerspectiveTransform
 
-     {
 
-         // 变换矩阵
 
-         double[,] H;
 
-         double[,] InverseH;
 
-         public ZIMPerspectiveTransform(OrdinalQuadrilateral src, OrdinalQuadrilateral dst)
 
-         {
 
-             // 该算法点序为 左下角开始 顺时针
 
-             double[] X = new double[4] { src.A.x, src.C.x, src.D.x, src.B.x };
 
-             double[] Y = new double[4] { src.A.y, src.C.y, src.D.y, src.B.y };
 
-             double[] Xp = new double[4] { dst.A.x, dst.C.x, dst.D.x, dst.B.x };
 
-             double[] Yp = new double[4] { dst.A.y, dst.C.y, dst.D.y, dst.B.y };
 
-             TransformEstimate(X, Y, Xp, Yp);
 
-             //UnityEngine.Debug.Log(H.ToJson(true));
 
-             //UnityEngine.Debug.Log(H[0, 0]);
 
-             //UnityEngine.Debug.Log(H[0, 1]);
 
-             //UnityEngine.Debug.Log(H[0, 2]);
 
-         }
 
-         //public Vector Transform(Vector v)
 
-         //{
 
-         //    var result = Transform(v.x, v.y);
 
-         //    return new Vector((float)result.x, (float)result.y);
 
-         //}
 
-         public (int x, int y) TransformRound(int x, int y)
 
-         {
 
-             var result = Transform((double)x, (double)y);
 
-             return ((int)Math.Round(result.x), (int)Math.Round(result.y));
 
-         }
 
-         public (float x, float y) Transform(float x, float y)
 
-         {
 
-             var result = Transform((double)x, (double)y);
 
-             return ((float)result.x, (float)result.y);
 
-         }
 
-         public (double x, double y) Transform(double x, double y)
 
-         {
 
-             double t1 = H[0, 0] * x + H[0, 1] * y + H[0, 2];
 
-             double t2 = H[1, 0] * x + H[1, 1] * y + H[1, 2];
 
-             double t3 = H[2, 0] * x + H[2, 1] * y + H[2, 2];
 
-             return (t1 / t3, t2 / t3);
 
-         }
 
-         public (float x, float y) TransformInverse(float x, float y)
 
-         {
 
-             var result = TransformInverse((double)x, (double)y);
 
-             return ((float)result.x, (float)result.y);
 
-         }
 
-         public (double x, double y) TransformInverse(double x, double y)
 
-         {
 
-             double t1 = InverseH[0, 0] * x + InverseH[0, 1] * y + InverseH[0, 2];
 
-             double t2 = InverseH[1, 0] * x + InverseH[1, 1] * y + InverseH[1, 2];
 
-             double t3 = InverseH[2, 0] * x + InverseH[2, 1] * y + InverseH[2, 2];
 
-             return (t1 / t3, t2 / t3);
 
-         }
 
-         // Calculate matrix transform
 
-         void TransformEstimate(double[] X, double[] Y, double[] Xp, double[] Yp)
 
-         {
 
-             //double[] Xp = { 0, 0, 1280, 1280 };
 
-             //double[] Yp = { 0, 720, 720, 0 };
 
-             double[,] B = new double[8, 8];
 
-             double[,] D = new double[8, 1];
 
-             for (int i = 0; i < 4; i++)
 
-             {
 
-                 B[i, 0] = X[i];
 
-                 B[i, 1] = Y[i];
 
-                 B[i, 2] = 1;
 
-                 B[i, 6] = -X[i] * Xp[i];
 
-                 B[i, 7] = -Y[i] * Xp[i];
 
-                 B[i + 4, 3] = X[i];
 
-                 B[i + 4, 4] = Y[i];
 
-                 B[i + 4, 5] = 1;
 
-                 B[i + 4, 6] = -X[i] * Yp[i];
 
-                 B[i + 4, 7] = -Y[i] * Yp[i];
 
-             }
 
-             for (int i = 0; i < 4; i++)
 
-             {
 
-                 D[i, 0] = Xp[i];
 
-                 D[i + 4, 0] = Yp[i];
 
-             }
 
-             double[,] BTranspose = TransposeMatrix(B);
 
-             double[,] l = MatrixMultiply(MatrixMultiply(MatrixInverse(MatrixMultiply(BTranspose, B)), BTranspose), D);      // l 是8行1列的矩阵
 
-             H = new double[3, 3] { { l[0, 0], l[1, 0], l[2, 0] }, { l[3, 0], l[4, 0], l[5, 0] }, { l[6, 0], l[7, 0], 1 } };
 
-             InverseH = MatrixInverse(H);
 
-             // 测试代码
 
-             //var x1 = X[2];
 
-             //var y1 = Y[2];
 
-             //var x2 = X[0];
 
-             //var y2 = Y[0];
 
-             //// Plot the points and their transformed coordinates
 
-             //UnityEngine.Debug.Log("Plotting the points and their transformed coordinates...");
 
-             //for (double u = 0; u <= 1; u += 0.1)
 
-             //{
 
-             //    double x = u * x1 + (1 - u) * x2;
 
-             //    double y = u * y1 + (1 - u) * y2;
 
-             //    UnityEngine.Debug.Log($"Point ({x}, {y})");
 
-             //    double t1 = H[0, 0] * x + H[0, 1] * y + H[0, 2];
 
-             //    double t2 = H[1, 0] * x + H[1, 1] * y + H[1, 2];
 
-             //    double t3 = H[2, 0] * x + H[2, 1] * y + H[2, 2];
 
-             //    double tX = t1 / t3;
 
-             //    double tY = t2 / t3;
 
-             //    UnityEngine.Debug.Log($"Transformed point ({tX}, {tY})");
 
-             //}
 
-         }
 
-         static double[,] TransposeMatrix(double[,] matrix)
 
-         {
 
-             int rows = matrix.GetLength(0);
 
-             int cols = matrix.GetLength(1);
 
-             double[,] result = new double[cols, rows];
 
-             for (int i = 0; i < rows; i++)
 
-             {
 
-                 for (int j = 0; j < cols; j++)
 
-                 {
 
-                     result[j, i] = matrix[i, j];
 
-                 }
 
-             }
 
-             return result;
 
-         }
 
-         static double[,] ReshapeMatrix(double[,] matrix, int rows, int cols)
 
-         {
 
-             int originalRows = matrix.GetLength(0);
 
-             int originalCols = matrix.GetLength(1);
 
-             if (originalRows * originalCols != rows * cols)
 
-             {
 
-                 throw new Exception("Invalid reshape dimensions");
 
-             }
 
-             double[,] result = new double[rows, cols];
 
-             int rowIndex = 0;
 
-             int colIndex = 0;
 
-             for (int i = 0; i < originalRows; i++)
 
-             {
 
-                 for (int j = 0; j < originalCols; j++)
 
-                 {
 
-                     result[rowIndex, colIndex] = matrix[i, j];
 
-                     colIndex++;
 
-                     if (colIndex == cols)
 
-                     {
 
-                         colIndex = 0;
 
-                         rowIndex++;
 
-                     }
 
-                 }
 
-             }
 
-             return result;
 
-         }
 
-         static double[,] ReshapeMatrix(double[] array, int rows, int cols)
 
-         {
 
-             double[,] result = new double[rows, cols];
 
-             int index = 0;
 
-             for (int j = 0; j < cols; j++)
 
-             {
 
-                 for (int i = 0; i < rows; i++)
 
-                 {
 
-                     result[i, j] = array[index];
 
-                     index++;
 
-                 }
 
-             }
 
-             return result;
 
-         }
 
-         static double[,] MatrixMultiply(double[,] matrix1, double[,] matrix2)
 
-         {
 
-             int rows1 = matrix1.GetLength(0);
 
-             int cols1 = matrix1.GetLength(1);
 
-             int rows2 = matrix2.GetLength(0);
 
-             int cols2 = matrix2.GetLength(1);
 
-             if (cols1 != rows2)
 
-             {
 
-                 throw new Exception("Invalid matrix dimensions");
 
-             }
 
-             double[,] result = new double[rows1, cols2];
 
-             for (int i = 0; i < rows1; i++)
 
-             {
 
-                 for (int j = 0; j < cols2; j++)
 
-                 {
 
-                     for (int k = 0; k < cols1; k++)
 
-                     {
 
-                         result[i, j] += matrix1[i, k] * matrix2[k, j];
 
-                     }
 
-                 }
 
-             }
 
-             return result;
 
-         }
 
-         static double[,] MatrixInverse(double[,] matrix)
 
-         {
 
-             int n = matrix.GetLength(0);
 
-             double[,] augmentedMatrix = new double[n, 2 * n];
 
-             for (int i = 0; i < n; i++)
 
-             {
 
-                 for (int j = 0; j < n; j++)
 
-                 {
 
-                     augmentedMatrix[i, j] = matrix[i, j];
 
-                 }
 
-                 augmentedMatrix[i, i + n] = 1;
 
-             }
 
-             for (int i = 0; i < n; i++)
 
-             {
 
-                 double pivot = augmentedMatrix[i, i];
 
-                 for (int j = 0; j < 2 * n; j++)
 
-                 {
 
-                     augmentedMatrix[i, j] /= pivot;
 
-                 }
 
-                 for (int k = 0; k < n; k++)
 
-                 {
 
-                     if (k != i)
 
-                     {
 
-                         double factor = augmentedMatrix[k, i];
 
-                         for (int j = 0; j < 2 * n; j++)
 
-                         {
 
-                             augmentedMatrix[k, j] -= factor * augmentedMatrix[i, j];
 
-                         }
 
-                     }
 
-                 }
 
-             }
 
-             double[,] inverseMatrix = new double[n, n];
 
-             for (int i = 0; i < n; i++)
 
-             {
 
-                 for (int j = 0; j < n; j++)
 
-                 {
 
-                     inverseMatrix[i, j] = augmentedMatrix[i, j + n];
 
-                 }
 
-             }
 
-             return inverseMatrix;
 
-         }
 
-     }
 
- }
 
 
  |