大地测量——计算七参数(编程作业)

2018.12.30 很多人私信问我要矩阵类,推荐一个,很适合测绘的学生,基本上矩阵有了之后,程序就很好编写了: C#矩阵类 http://www.zhangjiacheng.xyz/Index.html 

 

需求:通过A,B坐标系中提供的六个已知同名点,获得由A转换到B坐标系的七个参数。

逻辑框图:                                                            界面如下:

 

                                         

 

代码:

1.文件读取部分

//存储读入数据的数组
        double[,] _f1 = new double[6, 3];
        double[,] _f2 = new double[6, 3];
       
        /***************文件读取开始************************/
        private void button1_Click(object sender, EventArgs e)
        {
            openFileDialog1.Filter = "文本文件(*.txt)|*.txt";//文件过滤器
            if (DialogResult.OK == openFileDialog1.ShowDialog())
                textBox1.Text = openFileDialog1.FileName;
            StreamReader reader = new StreamReader(openFileDialog1.FileName);
            for (int i = 0; i < 6; i++)
            {
                string str = reader.ReadLine();
                string[] arr = new string[3];
                arr = str.Split(',');
                for (int j = 0; j < 3; j++)
                {
                    _f1[i, j] = double.Parse(arr[j]);
                }
            }
           
        }
        private void button2_Click(object sender, EventArgs e)
        {
            openFileDialog2.Filter = "文本文件(*.txt)|*.txt";//文件过滤器
            if (DialogResult.OK == openFileDialog2.ShowDialog())
                textBox2.Text = openFileDialog2.FileName;
            StreamReader reader = new StreamReader(openFileDialog2.FileName);          
            for (int i = 0; i < 6; i++)
            {
                string str = reader.ReadLine();
                string[] arr = new string[3];
                arr = str.Split(',');
                for (int j = 0; j < 3; j++)
                {
                    _f2[i, j] = double.Parse(arr[j]);
                }
            }
        }
        /***************文件读取结束************************/

2.数据导入矩阵+计算+输出

private void button3_Click(object sender, EventArgs e)
        {
               /*******************数据录入对应矩阵开始**************/
            //计算第一点的B,L
                Matrix sumB = GetItsB(_f1[0, 0], _f1[0, 1], _f1[0, 2]);               
                Matrix sumL = new Matrix(3,1, new double[3] { _f2[0, 0], _f2[0, 1], _f2[0, 2] });
            //计算后续点的B,L 并将之按行添加到第一点末尾   
                for (int i = 1; i < 6; i++)
                { 
                    Matrix _B = GetItsB(_f1[i, 0], _f1[i, 1], _f1[i, 2]);
                   sumB=sumB.Addinend(_B); 
                   Matrix _L = new Matrix(3,1, new double[3] { _f2[i, 0], _f2[i, 1], _f2[i, 2] });
                   sumL=sumL.Addinend(_L);                    
                }
                /*******************数据录入对应矩阵结束**************/

                /*******************计算开始*****************/
            //X阵求解,V阵求解
                Matrix N = new Matrix(sumB.Transpose() * sumB);
                N.InvertGaussJordan();
                Matrix X = new Matrix(N.Multiply(-1)*sumB.Transpose()*sumL);
                Matrix V = new Matrix(sumB * X + sumL);
                 /*******************计算结束*****************/


                /*******************结果输出开始*****************/            
            double m0 = Math.Sqrt((V.Transpose()*V).elements[0] / 11);
            textBox3.Text = "平移X0:" + X.elements[0] + "m" +"\r\n"+
                          "平移Y0:" + X.elements[1] + "m   " + "\r\n" +
                          "平移Z0:" + X.elements[2] + "m  " + "\r\n" +
                          "尺度 K:" + Math.Pow(10, 6) * (X.elements[3] - 1) + "ppm   " + "\r\n" +
                          "旋转 X:" + 180 * 60 * 60 * (X.elements[4] / X.elements[3]) / Math.PI + "s   " + "\r\n" +
                          "旋转 Y:" + 180 * 60 * 60 * (X.elements[5] / X.elements[3]) / Math.PI + "s   " + "\r\n" +
                          "旋转 Z:" + 180 * 60 * 60 * (X.elements[6] / X.elements[3]) / Math.PI + "s   " + "\r\n" +
                          "单位权中误差m0:" + m0*Math.Pow(10,2) + "cm   ";
            /*******************结果输出结束*****************/
            
                               
        }

        /**
         * 输入一个点的z,y,z输出其B矩阵
         */
        Matrix GetItsB(double X, double Y, double Z)
        {
            double[] toB = new double[21]{1,0,0,X,0,-Z,Y,
                                          0,1,0,Y,Z,0,-X,
                                          0,0,1,Z,-Y,X,0};
            Matrix B = new Matrix(3, 7, toB);
            return B.Multiply(-1);

        }

运行结果:

 

 

体悟与收获:

本次的程序设计逻辑相对简单。但对于编程思维掌握不是很熟练的我来说,算是一次非常合适的训练。

1.这是我第一次写程序处处用注释,也是第一次先构思好程序的大部分再开始动手写的程序。换言之,这是我第一次时刻自己明白自己要做什么的编程。

2.以及,本次调试我已经能熟练的时候断点,监测和单步运行。这使得我差错并没有花上太多时间。以及,随着不断深入编程学习,我开始能触类旁通。

3.本次完成程序总共耗时:  6h  

编写读入文件:3h|一个晚上

这是最简单的,但我在这犯错最多。主要是因为:一开始时我是直接用split分隔数据。但split分隔空格使得连续空格处产生了空位“”。我试图用数组传递来解决这个问题,但后来程序运行效率低下,打开文件并读取到数组的时间延搁非常长。(约一分钟左右)于是我反复纠结我写的代码,运行效率为何如此低下,结果耗时极长。)后来稍微修改了一下读入txt,改成了txt中也以英文逗号分隔,运行效率低下问题才解决。

录入矩阵并计算并输出结果:1|早起到上课前一小时+2h|晚上

此处我花费时间主要还是因为,虽然这次我用了逻辑框架指导我的编程,但我编程的思路仍旧稍有混乱。外加必要的调试时间。以及使用他人的矩阵类,并为之新写addinend的时间,所以用了三个小时。

 

总之来说,本次编程我熟练不少;而且我的编程越来越熟练,这也使我振奋不已。总之,我应该继续好好学习并时刻学习编程,并继续培养良好的编程思想和习惯。

©️2020 CSDN 皮肤主题: 大白 设计师: CSDN官方博客 返回首页
实付0元
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值