sách gpt4 ai đã đi

Triển khai C# phép quay tọa độ không gian không lặp lại góc lớn

In lại Tác giả: Tôi là một chú chim nhỏ Thời gian cập nhật: 2022-12-16 22:31:09 37 4
mua khóa gpt4 Nike

1. Giới thiệu

Trong bài viết trước, chúng tôi đã đề cập đến việc chuyển đổi giữa các hệ tọa độ hình chữ nhật không gian. Khi chuyển đổi tọa độ trắc địa và bản đồ, tình huống thường gặp là: chuyển đổi góc nhỏ giữa hai hệ tọa độ hình chữ nhật. Đây là phép chuyển đổi giữa hệ tọa độ WGS-84, hệ tọa độ Bắc Kinh 54, hệ tọa độ Tây An 80 và hệ tọa độ Quốc gia 2000, mà chúng ta thường sử dụng trong khảo sát và xử lý dữ liệu bản đồ.

Cái gọi là chuyển đổi góc nhỏ đề cập đến góc quay của trục tương ứng giữa hệ tọa độ hình chữ nhật \(XOY\) và hệ tọa độ hình chữ nhật \(X'O'Y'\) rất nhỏ, thỏa mãn mô hình tuyến tính sau khi khai triển chuỗi Taylor.

1671185879422

Các mô hình chuyển đổi tọa độ ba chiều phổ biến bao gồm [1]:

  • Mô hình Bursa
  • Mô hình Molochensky
  • Mô hình Paradigm

Tuy nhiên, khi góc quay của các trục tương ứng của hai hệ tọa độ vượt quá một độ nhất định thì không thể sử dụng phép khai triển chuỗi Taylor bậc thấp và độ phức tạp, độ chính xác và tốc độ tính toán lặp lại không thể cân bằng được [2]. Có những nhược điểm sau:

  1. Chỉ phù hợp với các chuyển đổi góc nhỏ đáp ứng các yêu cầu gần đúng
  2. Thiết kế các phép toán lượng giác phức tạp
  3. Tính toán lặp lại là cần thiết

Ma trận Rodriguez là một phương pháp phổ biến trong quang trắc, trong đó không yêu cầu tính toán lượng giác và các phép toán lặp lại. Quá trình tính toán đơn giản và rõ ràng, dễ dàng thực hiện thông qua lập trình. Nó không chỉ áp dụng cho phép biến đổi tọa độ góc nhỏ mà còn áp dụng cho phép biến đổi tọa độ không gian góc lớn.

Bài viết này sẽ giới thiệu các nguyên tắc cơ bản và cách triển khai ma trận Rodriguez bằng C#, đồng thời sử dụng các ví dụ để chứng minh tính hiệu quả của giải pháp.

2. Nguyên lý biến đổi tọa độ ma trận Rodriguez

2.1 Ma trận cơ bản của phép biến đổi tọa độ

Hai hệ tọa độ hình chữ nhật không gian là \(XOY\) và \(X'O'Y'\), gốc của các hệ tọa độ này không nhất quán và có ba tham số tịnh tiến \(\Delta X\), \(\Delta Y\), và \(\Delta Z\). Trục tọa độ của chúng cũng không song song với nhau và có ba tham số quay \(\epsilon x\), \(\epsilon y\), \(\epsilon z\). Tọa độ của cùng một điểm A trong hai hệ tọa độ lần lượt là \((X,Y,Z)\) và \((X',Y',Z')\).

Rõ ràng, hai hệ tọa độ này có thể thu được bằng phép biến đổi tịnh tiến và quay của các trục tọa độ. Mối quan hệ chuyển đổi giữa các tọa độ như sau

\[\left[\begin{mảng}{l} X \\ Y \\ Z \end{mảng}\right]=\lambda R\left[\begin{mảng}{l} X^{\prime} \\ Y^{\prime} \\ Z^{\prime} \end{mảng}\right]+\left[\begin{mảng}{l} \Delta X \\ \Delta Y \\ \Delta Z \end{mảng}\right] \tag{1} \]

Trong đó, \(\lambda\) là hệ số tỷ lệ, \(R\left(\varepsilon_Y\right) R\left(\varepsilon_X\right) R\left(\varepsilon_Z\right)\) là các ma trận quay quanh trục Y, trục X và trục Z. Lưu ý rằng thứ tự quay là khác nhau và dạng của \(R\) cũng khác nhau.

\[\begin{aligned} R & =R\left(\varepsilon_Y\right) R\left(\varepsilon_X\right) R\left(\varepsilon_Z\right) \\ & =\left[\begin{array}{ccc} \cos \varepsilon_Y \cos \varepsilon_Z-\sin \varepsilon_Y \sin \varepsilon_X \sin \varepsilon_Z & -\cos \varepsilon_Y \sin \varepsilon_Z-\sin \varepsilon_Y \sin \varepsilon_X \cos \varepsilon_Z & -\sin \varepsilon_Y \cos \varepsilon_X \\ \cos \varepsilon_X \sin \varepsilon_Z & \cos \varepsilon_X \cos \varepsilon_Z & -\sin \varepsilon_X \\ \sin \varepsilon_Y \cos \varepsilon_Z+\cos \varepsilon_Y \sin \varepsilon_X \sin \varepsilon_Z & -\sin \varepsilon_Y \sin \varepsilon_Z+\cos \varepsilon_Y \sin \varepsilon_X \cos \varepsilon_Z & \cos \varepsilon_Y \cos \varepsilon_X \end{mảng}\right] \end{căn chỉnh} \]

Người ta thường gọi \(R\) là ma trận quay và \([\Delta X,\Delta Y,\Delta Z]^T\) là ma trận tịnh tiến. Việc chuyển đổi giữa hai hệ tọa độ có thể thực hiện được chỉ bằng cách tìm bảy tham số chuyển đổi \(\Delta X\), \(\Delta Y\), \(\Delta Z\), \(\varepsilon_X\), \(\varepsilon_Y\), \(\varepsilon_Z\), hoặc trực tiếp tìm ma trận quay và ma trận tịnh tiến.

2.2 Kỹ thuật tính toán - Ma trận Barycentric

Để thuận tiện cho việc tính toán, tọa độ được sử dụng là tọa độ tâm. Tọa độ các điểm chung của hai hệ tọa độ được tính trung bình thành tọa độ khối tâm với trọng tâm là gốc. Chúng được ký hiệu lần lượt là \((\bar{X}, \bar{Y}, \bar{Z})\) và \(\left(\bar{X}^{\prime}, \bar{Y}^{\prime}, \bar{Z}^{\prime}\right)\). Tọa độ của trọng tâm của hai hệ tọa độ lần lượt là \((X_g, Y_g, Z_g)\) và \((X'_g, Y'_g, Z'_g)\).

\[\left\{\begin{array}{l} X_k=\frac{\sum_{i=1}^n X_i}{n}, Y_k=\frac{\sum_{i=1}^n Y_i}{n}, Z_k=\frac{\sum_{i=1}^n Z_i}{n} \\ X_k^{\prime}=\frac{\sum_{i=1}^n X_i^{\prime}}{n}, Y_k^{\prime}=\frac{\sum_{i=1}^n Y_i^{\prime}}{n}, Z_k^{\prime}=\frac{\sum_{i=1}^n Z_i^{\prime}}{n} \\ \bar{X}_i=X_i-X_k, \bar{Y}_i=Y_i-Y_k, \bar{Z}_i=Z_i-Z_k \\ \bar{X}_i^{\prime}=X_i^{\prime}-X_k^{\prime}, \bar{Y}_i^{\prime}=Y_i^{\prime}-Y_k^{\prime}, \bar{Z}_i^{\prime}=Z_i^{\prime}-Z_k^{\prime} \end{mảng}\right. \]

Do đó, công thức (1) có thể được chuyển đổi thành:

\[\left[\begin{mảng}{l} \bar{X} \\ \bar{Y} \\ \bar{Z} \end{mảng}\right]=\lambda R\left[\begin{mảng}{l} \bar{X}^{\prime} \\ \bar{Y}^{\prime} \\ \bar{Z}^{\prime} \end{mảng}\right] \tag{2} \]

\[\left[\begin{mảng}{l} \Delta X \\ \Delta Y \\ \Delta Z \end{mảng}\right]=\left[\begin{mảng}{l} X_g \\ Y_g \\ Z_g \end{mảng}\right]-\lambda R\left[\begin{mảng}{l} X_g^{\prime} \\ Y_g^{\prime} \\ Z_g^{\prime} \end{mảng}\right] \tag{3} \]

Do đó, các tham số chuyển đổi có thể được giải quyết theo hai bước. Đầu tiên, sử dụng công thức (2) để tìm các tham số quay và hệ số tỷ lệ, sau đó sử dụng công thức (3) để tìm các tham số tịnh tiến.

2.3 Phương pháp biến đổi dựa trên ma trận Rodriguez

Lấy chuẩn 2 ở cả hai vế của phương trình (2), do \(\lambda > 0\), ma trận quay là ma trận trực giao, ta có thể thu được

\[\Vert [\bar{X}, \bar{Y}, \bar{Z}]^T \Vert = \lambda \Vert [\bar{X'}, \bar{Y'}, \bar{Z'}]^T \Vert \tag{4} \]

Đối với n điểm chung, ước lượng bình phương trung bình tối thiểu của \(\lambda\) có thể thu được

\[\lambda=\frac{\sum_{i=1}^n\left(\left\|\left[\bar{X}_i \bar{Y}_i \bar{Z}_i\right]^{\mathrm{T}}\right\| \cdot\left\|\left[\bar{X}_i^{\prime} \bar{Y}_i^{\prime} \bar{Z}_i^{\prime}\right]^{\mathrm{T}}\right\|\right)}{\sum_i^n\left(\left\|\left[\bar{X}_{\prime}^{\prime} \bar{Y}_i^{\prime} \bar{Z}_i^{\prime}\right]^{\mathrm{T}}\right\|\right)^2} \]

Sau khi có được ước lượng bình phương trung bình tối thiểu của hệ số tỷ lệ, ma trận quay \(R\) có thể được biểu thị như sau

\[R=(IS)^{-1} (I+S) \thẻ{5} \]

Trong đó, \(I\) là ma trận đơn vị và \(S\) là ma trận phản đối xứng. Thay công thức (5) vào công thức (3), ta được:

\[\left[\begin{mảng}{c} \bar{X}-\lambda \bar{X}^{\prime} \\ \bar{Y}-\lambda \bar{Y}^{\prime} \\ \bar{Z}-\lambda \bar{Z}^{\prime} \end{mảng}\right]=\left[\begin{mảng}{ccc} 0 & -\left(\bar{Z}+\lambda \bar{Z}^{\prime}\right) & -\left(\bar{Y}+\lambda \bar{Y}^{\prime}\right) \\ -\left(\bar{Z}+\lambda \bar{Z}^{\prime}\right) & 0 & \bar{X}+\lambda \bar{X}^{\prime} \\ \bar{Y}+\lambda \bar{Y}^{\prime} & \bar{X}+\lambda \bar{X}^{\prime} & 0 \end{mảng}\right]\left[\begin{mảng}{l} a \\ b \\ c \end{mảng}\right] \tag{6} \]

3. Triển khai mã C#

Các phép toán ma trận sử dụng thư viện MathNet.Numerics, khởi tạo các trường MatrixBuilder mb = Matrix.Build và VectorBuilder vb = Vector.Build.

3.1 Tính toán tọa độ trọng tâm của ma trận

                        
                          Vector BarycentricCoord(Ma trận tọa độ) { Vector barycentric = vb.Dense(3, 1); int lenCoord = tọa độ.ColumnCount; nếu (lenCoord > 2) barycentric = tọa độ.RowSums(); barycentric /= lenCoord; trả về barycentric; }


                        
                      

3.2 Tính hệ số tỷ lệ

Lấy chuẩn 2 và sử dụng hàm lũy thừa từng điểm (2.0):

                        
                          double ScaleFactor(Matrix sourceCoord, Matrix targetCoord) { double k = 0; double s1 = 0; double s2 = 0; Vector sourceColL2Norm = sourceCoord.PointwisePower(2.0).ColumnSums(); Vector targetColL2Norm = targetCoord.PointwisePower(2.0).ColumnSums(); int lenSourceCoord = sourceCoord.ColumnCount; int lenTargetCoord = targetCoord.ColumnCount; // Chỉ khi ma trận đích và ma trận nguồn có cùng kích thước thì mới có thể tính được if (lenSourceCoord == lenTargetCoord) { s1 = sourceColL2Norm.PointwiseSqrt().PointwiseMultiply(targetColL2Norm.PointwiseSqrt()).Sum(); s2 = sourceColL2Norm.Sum(); } k = s1 / s2; return k; }


                        
                      

3.3 Tính toán các tham số Rodriguez

Tham số Rodrigues ở đây là \([a, b, c]^T\) trong phương trình (6).

                        
                          Vector RoderickParas(double scalceFactor, Matrix sourceCoord, Matrix targetCoord) { Vector roderick = vb.Dense(new double[] { 0, 0, 0 }); int lenData = sourceCoord.ColumnCount; //Ma trận hệ số hằng số var lConstant = vb.Dense(new double[3 * lenData]); //Ma trận hệ số var coefficient = mb.DenseOfArray(new double[3 * lenData, 3]); //Xây dựng ma trận tương ứng cho (int i = 0; i < lenData; i++) { lConstant[3 * i] = targetCoord[0, i] - scalceFactor * sourceCoord[0, i]; lConstant[3 * i + 1] = targetCoord[1, i] - scalceFactor * sourceCoord[1, i]; lConstant[3 * i + , i]); hệ số[3 * i + 1, 0] = targetCoord[0, i] + scalceFactor * sourceCoord[0, i]; hệ số[3 * i + 2, 0] = targetCoord[1, i] + scalceFactor * sourceCoord[2, i]; hệ số[3 * i + 1, 1] = 0; hệ số[3 * i + 2, 0] = targetCoord[0, i] + scalceFactor * sourceCoord[0, i]; hệ số[3 * i + 2, 0] = targetCoord[1, i] + scalceFactor * sourceCoord[1, i]; scalceFactor * sourceCoord[1, i]; hệ số[3 * i + 2, 1] = targetCoord[0, i] + scalceFactor * sourceCoord[0, i]; hệ số[3 * i + 2, 2] = 0; } roderick = hệ số.TransposeThisAndMultiply(hệ số).Inverse() * hệ số.Transpose() * lConstant; trả về roderick; }



                        
                      

3.4 Phân tích Ma trận Rodriguez

Ở đây, nó là sự hiện thực hóa công thức (5).

                        
                          ///  /// phân tích ma trận Roderick vào ma trận xoay và ma trận dịch ///  ///  tọa độ tọa độ Tọa độ {0,0,0}, {0,0,0}}); 0, -roderick[2], -roderick[1] }, {roderick[2], 0, -roderick[0] }, {roderick[1], roderick[0], 0 } }); // Tạo ma trận đơn vị // Sau đó thực hiện các phép toán + và - với S từ (5) rotation = (DenseMatrix.CreateIdentity(3) - antisymmetric).Inverse() * (DenseMatrix.CreateIdentity(3) + antisymmetric); translation = coreTargetCoord - scaleFactor * rotation * coreSourceCoord; return (rotation, translation); }


                        
                      

3.5 Logic gọi

                        
                          // 1. Chuẩn bị giá trị trường MatrixBuilder mb = Matrix.Build; VectorBuilder vb = Vector.Build; // 2. Viết tọa độ của hệ tọa độ nguồn. Lưu ý thứ tự đầu vào của x, y và z tại đây Matrix source = mb.DenseOfArray(new double[,] { {-17.968, -12.829, 11.058 }, {-0.019 , 7.117, 11.001 }, {0.019 , -7.117, 10.981 } }).Transpose(); // 3. Viết tọa độ của hệ tọa độ đích Matrix target = mb.DenseOfArray(new double[,] { { 3392088.646,504140.985,17.958 }, { 3392089.517,504167.820,17.775 }, { 3392098.729,504156.945,17.751 } }).Transpose(); // 4. Barycentricization var coreSource = BarycentricCoord(source); var coreTarget = BarycentricCoord(target); var sourceCoords = source - mb.DenseOfColumnVectors(coreSource, coreSource, coreSource); var targetCoords = target - mb.DenseOfColumnVectors(coreTarget, coreTarget, coreTarget); // 5. Hệ số tỷ lệ double k = ScaleFactor(sourceCoords, targetCoords); // 6. Giải quyết các tham số Roderick var roderick = RoderickParas(k, sourceCoords, targetCoords); // 7. Rotate(Ma trận ro, Vector tran) = RotationMatrix(k, roderick, coreSource, coreTarget); Console.WriteLine("Hệ số tỷ lệ là: "); Console.WriteLine(k); Console.WriteLine("Ma trận quay là: "); Console.WriteLine(ro.ToString()); Console.WriteLine("Tham số dịch là: "); Console.WriteLine(tran.ToString()); Console.WriteLine("Kết quả tính toán là: "); Console.WriteLine(source2.ToString());


                        
                      

4. Kết luận

Phương pháp biến đổi dựa trên ma trận Rodrigues đơn giản và nhanh chóng trong việc giải các tham số biến đổi giữa hai hệ tọa độ, đặc biệt khi góc quay lớn.

1671195869776


  1. Chu Hoa Đồng, Dương Nguyên Hy, Lữ Chí Bình. Biến đổi hệ tọa độ GPS[M]. Bắc Kinh: Nhà xuất bản Khảo sát và Bản đồ Trung Quốc, 1994. ↩︎ .

  2. Zhan Yinhu, Zheng Yong, Luo Yabo, et al. Một thuật toán dẫn đường thiên thể mới không cần khởi tạo và lặp lại. Tạp chí Khoa học Công nghệ Đo đạc và Bản đồ, 2015, 32(5): 445-449. ↩︎ .

Cuối cùng, bài viết này về việc triển khai C# của phép quay tọa độ không gian góc lớn không lặp lại đã kết thúc. Nếu bạn muốn biết thêm về việc triển khai C# của phép quay tọa độ không gian góc lớn không lặp lại, vui lòng tìm kiếm các bài viết trên CFSDN hoặc tiếp tục duyệt các bài viết liên quan. Tôi hy vọng bạn sẽ ủng hộ blog của tôi trong tương lai! .

37 4 0
Tôi là một chú chim nhỏ
Hồ sơ cá nhân

Tôi là một lập trình viên xuất sắc, rất giỏi!

Nhận phiếu giảm giá Didi Taxi miễn phí
Mã giảm giá Didi Taxi
Giấy chứng nhận ICP Bắc Kinh số 000000
Hợp tác quảng cáo: 1813099741@qq.com 6ren.com