坐标转换程序:(1)四参数和七参数的计算

                                                                                                      

 

       个人想分享一些在大学中编写的一些程序,在进行坐标转换的时候,我们经常涉及到四参数与七参数的计算,在文章中,采用C#语言来进行编程,方便计算。

(1)四参数的计算:

在转换范围较小内不同的平面坐标转换通常采用二维四参数模型转换,二维四参数的转换模型的公式如下:

    

式中的x1,y1x2y2是两个坐标系下的坐标点;

是平移参数,单位为米;

α是旋转参数,单位为弧度;

m是尺度参数,无单位。

(2)七参数的计算:

两个空间直角坐标系进行转换计算就需要用到七个参数,其中包括:三个平移参数,(ΔX, ΔY ,ΔZ),三个旋转角度参数(εX,εY,εZ)以及一个尺度参数dK

公式如下:

 

式中的XT与X是用来表示P点在图中的两个坐标系O-XYZ与OT-XTYTZT的坐标向量


∆X0是原点的平移向量,

    

R(ε)是一个旋转参数矩阵

        

为了便于计算,我们需要简化公式,因此假设当旋转角的值很小时,可以得到与得到公式的最终形式:


(3)四参数转换主要代码:

publicstaticvoid Canshu4(Point2d[] p1, Point2d[] p2, int PointCount, refdouble rota, refdouble scale, refdouble dx, refdouble dy)

        {

            double u = 1.0, v = 0, Dx = 0.0, Dy = 0.0;

 

            int intCount = PointCount;

            //Matrix dx1 ;//误差方程改正数

            Matrix B;//误差方程系数矩阵

                     // Matrix W ;//误差方程常数项

            double[,] dx1 = newdouble[4, 1];

            double[,] B1 = newdouble[2 * intCount, 4];

            double[,] W1 = newdouble[2 * intCount, 1];

            // Matrix BT, N, InvN, BTW;

            double[,] BT = newdouble[4, 2 * intCount];

            double[,] N = newdouble[4, 4];

            double[,] InvN = newdouble[4, 4];

            double[,] BTW = newdouble[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 = newMatrix(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)七参数转换主要代码:

publicstaticvoid Canshu7(Point3d[] p1, Point3d[] p2, int PointCount, refdouble rotax, refdouble rotay, refdouble rotaz, refdouble scale, refdouble dx, refdouble dy, refdouble dz)

        {

            double[,] B1 = newdouble[PointCount * 3, 7];

            Matrix B = newMatrix(B1);

            double[,] dx1 = newdouble[7, 1];//V=B*X-L

            double[,] L = newdouble[PointCount * 3, 1];

            double[,] BT = newdouble[7, PointCount * 3];

            double[,] N = newdouble[7, 7];

            double[,] InvN = newdouble[7, 7];

            double[,] BTL = newdouble[7, 1];

            //初始化L矩阵

            for(int i=0;i<PointCount*3;i++)

            {

                if(i%3==0)

                {

                    L[i, 0] = p2[i / 3].X;

                }

                elseif(i%3==1)

                {

                    L[i, 0] = p2[i / 3].Y;

                }

                elseif (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;

 

                }

                elseif(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;

                }

                elseif (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里面和csdn资源页里面

CSDN:https://download.csdn.net/download/yeahzhou/10467824

Github:https://github.com/Ahmiao/C-coordinate-conversion.git

  • 13
    点赞
  • 194
    收藏
    觉得还不错? 一键收藏
  • 12
    评论
下面是一个使用C++语言进行参数Logistic曲线拟合的示例代码: ```c++ #include <iostream> #include <cmath> using namespace std; double x[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }; double y[] = { 1, 3, 4, 7, 10, 15, 20, 26, 32, 38 }; int n = 10; double logistic(double x, double A, double B, double C, double D) { return A + (B - A) / pow(1 + pow(C / x, D), D); } void four_param_fit(double *x, double *y, int n, double &A, double &B, double &C, double &D) { double ym = y[0]; double xm = x[0]; for (int i = 1; i < n; i++) { if (y[i] > ym) { ym = y[i]; xm = x[i]; } } A = y[0]; B = ym; C = xm; D = 1; double eps = 1e-8; double err = 1; while (err > eps) { double A1 = A; double B1 = B; double C1 = C; double D1 = D; for (int i = 0; i < n; i++) { double f = logistic(x[i], A, B, C, D); double dfdA = 1; double dfdB = 1; double dfdC = (B - A) * D * pow(C, D) / pow(x[i] * C + pow(C, D), D + 1); double dfdD = (B - A) * pow(x[i] * C, D) * log(x[i] * C) * pow(C, D) / pow(x[i] * C + pow(C, D), D + 1); A1 += (y[i] - f) * dfdA; B1 += (y[i] - f) * dfdB; C1 += (y[i] - f) * dfdC; D1 += (y[i] - f) * dfdD; } err = sqrt(pow(A1 - A, 2) + pow(B1 - B, 2) + pow(C1 - C, 2) + pow(D1 - D, 2)); A = A1; B = B1; C = C1; D = D1; } } int main() { double A, B, C, D; four_param_fit(x, y, n, A, B, C, D); cout << "A = " << A << ", B = " << B << ", C = " << C << ", D = " << D << endl; return 0; } ``` 该代码使用了最小二乘法进行参数Logistic曲线拟合的计算,其中`four_param_fit`函数用于计算参数的值,`logistic`函数用于计算Logistic函数的值。在该示例代码中,输入数据为10个点的x和y值,输出为拟合得到的参数的值。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 12
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值