個人想分享一些在大學中編寫的一些程序,在進行坐標轉換的時候,我們經常涉及到四參數與七參數的計算,在文章中,采用C#語言來進行編程,方便計算。
(1)四參數的計算:
在轉換范圍較小內不同的平面坐標轉換通常采用二維四參數模型轉換,二維四參數的轉換模型的公式如下:

式中的x1,y1與x2,y2是兩個坐標系下的坐標點;
是平移參數,單位為米;
α是旋轉參數,單位為弧度;
m是尺度參數,無單位。
(2)七參數的計算:
兩個空間直角坐標系進行轉換計算就需要用到七個參數,其中包括:三個平移參數,(ΔX, ΔY ,ΔZ),三個旋轉角度參數(εX,εY,εZ)以及一個尺度參數dK
公式如下:
式中的XT與X是用來表示P點在圖中的兩個坐標系O-XYZ與OT-XTYTZT的坐標向量

∆X0是原點的平移向量,
R(ε)是一個旋轉參數矩陣
為了便於計算,我們需要簡化公式,因此假設當旋轉角的值很小時,可以得到
與
得到公式的最終形式:

(3)四參數轉換主要代碼:
| public static void Canshu4(Point2d[] p1, Point2d[] p2, int PointCount, ref double rota, ref double scale, ref double dx, ref double dy) { double u = 1.0, v = 0, Dx = 0.0, Dy = 0.0;
int intCount = PointCount; //Matrix dx1 ;//誤差方程改正數 Matrix B;//誤差方程系數矩陣 // Matrix W ;//誤差方程常數項 double[,] dx1 = new double[4, 1]; double[,] B1 = new double[2 * intCount, 4]; double[,] W1 = new double[2 * intCount, 1]; // Matrix BT, N, InvN, BTW; double[,] BT = new double[4, 2 * intCount]; double[,] N = new double[4, 4]; double[,] InvN = new double[4, 4]; double[,] BTW = new double[4, 1]; for (int i = 0; i < intCount; i++) { //計算誤差方程系數 B1[2 * i, 0] = 1; B1[2 * i, 1] = 0; B1[2 * i, 2] = p1[i].X; B1[2 * i, 3] = -p1[i].Y;
B1[2 * i + 1, 0] = 0; B1[2 * i + 1, 1] = 1; B1[2 * i + 1, 2] = p1[i].Y; B1[2 * i + 1, 3] = p1[i].X; } B = new Matrix(B1); for (int i = 0; i < intCount; i++) { //計算誤差方程系常數 W1[2 * i, 0] = p2[i].X - u * p1[i].X + v * p1[i].Y - Dx; W1[2 * i + 1, 0] = p2[i].Y - u * p1[i].Y - v * p1[i].X - Dy;
} //最小二乘求解 B.MatrixInver(B1, ref BT);//轉置 B.MatrixMultiply(BT, B1, ref N); InvN = B.MatrixOpp(N); B.MatrixMultiply(BT, W1, ref BTW); B.MatrixMultiply(InvN, BTW, ref dx1); Dx = Dx + dx1[0, 0]; Dy = Dy + dx1[1, 0]; u = u + dx1[2, 0]; v = v + dx1[3, 0]; dx = Dx; dy = Dy; rota = Math.Atan(v / u); scale = u / Math.Cos(rota); dx = Math.Round(dx, 6); dy = Math.Round(dy, 6); rota = Math.Round(rota, 6); scale = Math.Round(scale, 6); } |
(4)七參數轉換主要代碼:
| public static void Canshu7(Point3d[] p1, Point3d[] p2, int PointCount, ref double rotax, ref double rotay, ref double rotaz, ref double scale, ref double dx, ref double dy, ref double dz) { double[,] B1 = new double[PointCount * 3, 7]; Matrix B = new Matrix(B1); double[,] dx1 = new double[7, 1];//V=B*X-L double[,] L = new double[PointCount * 3, 1]; double[,] BT = new double[7, PointCount * 3]; double[,] N = new double[7, 7]; double[,] InvN = new double[7, 7]; double[,] BTL = new double[7, 1]; //初始化L矩陣 for(int i=0;i<PointCount*3;i++) { if(i%3==0) { L[i, 0] = p2[i / 3].X; } else if(i%3==1) { L[i, 0] = p2[i / 3].Y; } else if (i % 3 == 2) { L[i, 0] = p2[i / 3].Z; } } //初始化B矩陣 for (int i = 0; i < PointCount * 3; i++) { if(i%3==0) { B1[i, 0] = 1; B1[i, 1] = 0; B1[i, 2] = 0; B1[i, 3] = p1[i/3].X; B1[i, 4] = 0; B1[i, 5] = -p1[i/3].Z; B1[i, 6] = p1[i/3].Y;
} else if(i%3==1) { B1[i, 0] = 0; B1[i, 1] = 1; B1[i, 2] = 0; B1[i, 3] = p1[i / 3].Y; B1[i, 4] = p1[i/3].Z; B1[i, 5] = 0; B1[i, 6] = -p1[i / 3].X; } else if (i % 3 == 2) { B1[i, 0] = 0; B1[i, 1] = 0; B1[i, 2] = 1; B1[i, 3] = p1[i / 3].Z; B1[i, 4] = -p1[i / 3].Y; B1[i, 5] = p1[i/3].X; B1[i, 6] = 0; }
} //轉置 B.MatrixInver(B1,ref BT); //法方程矩陣 //N=BT*B B.MatrixMultiply(BT,B1,ref N); //求逆 InvN=B.MatrixOpp(N); //BTL=BT*L B.MatrixMultiply(BT,L,ref BTL); //dx1=invN*BTL; B.MatrixMultiply(InvN,BTL,ref dx1); // dx = Math.Round(dx1[0, 0], 6); dy = Math.Round(dx1[1, 0], 6); dz = Math.Round(dx1[2, 0], 6); scale = Math.Round(dx1[3, 0], 6); rotax = Math.Round(dx1[4, 0] / dx1[3, 0], 6); rotay = Math.Round(dx1[5, 0] / dx1[3, 0], 6); rotaz = Math.Round(dx1[6, 0] / dx1[3, 0], 6); } |
(5)程序效果圖

圖一:界面操作

圖二:計算結果
(6)源代碼下載
本程序的源代碼在我的github里面
Github:https://github.com/Ahmiao/C-coordinate-conversion.git
