解析空中三角测量程序代码
- 格式:doc
- 大小:167.00 KB
- 文档页数:24
解析空三航带法区域网平差程序设计随着新一代GPS系统在各个方面的高速发展,摄影测量技术已经被运用于国土资源监测、气象监测和天体科学等多个领域之中。
摄影测量技术也被逐渐运用到测绘科学中,丰富测绘学科测量技术手段的同时,摄影测量促进测量学的发展。
从摄影测量应用到生产的各个环节,人们对摄影测量的精度要求从未停止过,工程项目对摄影测量的测量精度也提出更高的要求。
本文通过摄影测量的解析空中三角测量方法,在整个目标范围内,将航测线路的模型点作为摄影测量辅助位置观测值,在一个区域范围内,利用多条航带构建一个模型网,再进行整体平差计算出区域网内各航带位置的改正系数,从而解算出航带中各个加密点的三维地表位置数据。
以这种数学模型和平差方法為基础,研究相应的算法,编写出相应的程序进行测试,通过实例计算并对最终结果进行精度评定。
1 Visual Studio简介1.1 什么是Visual StudioC# 编程语言作为美国Microsoft Corporation为Visual Studio (以下简称VS)开发环境下推出的一种简洁、类型安全的面向对象的计算机编程语言,软件程序开发的相关工作人员可以通过它编写在.NET Framework上运行的各种安全、可靠的应用程序。
1.2 C#所具有的特点C#具有以下突出特点:(1)C#的语法结构简单明了。
其最大的特点就是不允许对计算机系统的内存进行控制,去掉了复杂的指针操作。
(2)彻底的面向对象设计。
C#编程语言拥有面向对象的计算机语言的全部特征:封装、继承和多态。
(3)与Web紧密结合。
C#编程语言支持绝大多数的Web标准,例如HTML、XML、SOAP等语言。
(4)强大的安全机制。
能够自动处理在程序设计中常见的问题,较为高级的垃圾回收机制让普通编码基本忽略内存释放问题。
(5)兼容性好。
由于C#编程语言应用着.NET的编程语言规范设计(CLS),因此可以与其他的编程语言进行开发的组件相互兼容。
PBBA自动空中三角测量系统使用方法与技巧摘要自动空中三角测量,是航空摄影测量的组成部分,本课题主要介绍了PBBA系统和操作过程,以及在学生的使用系统的过程中遇到的问题与解决方法。
关键词自动空中三角测量;PBBA;使用技巧1 PBBA系统简介自动空中三角测量软件(PBBA,即Program of Block Bundle Adjustment的缩写),是国家863项目数字摄影测量工作站JX4A DPS的子项目,于1997年通过国家863项目专家组验收,于2001年通过日本测量界权威机构——日本测量协会的检定。
数字摄影测量工作站JX4A DPS项目于1999年获国家测绘局科技进步一等奖,于2001年获国家科技进步一等奖。
自动空中三角测量软件PBBA 是国内测绘行业同类产品中唯一的一套纯国产软件,在技术水平上,在国内、国际都占领先水平。
PBBA的作用是利用模式识别技术和多像影像匹配等方法代替人工在影像上自动选点与转点,同时自动获取像点坐标,提供给区域网平差程序解算,以确定加密点在选定坐标系中的空间位置和影像的定向参数。
PBBA自动空中三角测量软件由数字影像处理、框标量测内定向、加密点自动匹配、加密点人工修测、相对定向模型连接、旁向连接点自动转点、旁向连接点人工修测、多项式区域网整体平差、光束法区域网整体平差、测区接边、加密成果最终检定等十几个模块组成,该软件采用数字影象相关技术,自动化程度高、观测精度高、作业效率高。
该软件采用全片密集布点、点位均匀分布方式,因而连接点多,构网力度强,有效地降低了构网的系统误差,提高了加密精度和可靠性。
2 PBBA软件的使用及常见问题的处理通过近几年对我校航测专业学生的教学实践指导,我对PBBA软件的使用有了较深的体会,在此做一总结,以求得与同行进行交流的机会。
2.1 PBBA软件操作步骤1)建立目标文件夹。
2)复制影像文件夹“image”至自己的目标文件夹。
3)打开软件,进入自己的测区。
poss辅助空中三角测量的作业流程及步骤下载温馨提示:该文档是我店铺精心编制而成,希望大家下载以后,能够帮助大家解决实际的问题。
文档下载后可定制随意修改,请根据实际需要进行相应的调整和使用,谢谢!并且,本店铺为大家提供各种各样类型的实用资料,如教育随笔、日记赏析、句子摘抄、古诗大全、经典美文、话题作文、工作总结、词语解析、文案摘录、其他资料等等,如想了解不同资料格式和写法,敬请关注!Download tips: This document is carefully compiled by theeditor.I hope that after you download them,they can help yousolve practical problems. The document can be customized andmodified after downloading,please adjust and use it according toactual needs, thank you!In addition, our shop provides you with various types ofpractical materials,such as educational essays, diaryappreciation,sentence excerpts,ancient poems,classic articles,topic composition,work summary,word parsing,copy excerpts,other materials and so on,want to know different data formats andwriting methods,please pay attention!Poss辅助空中三角测量的作业流程与步骤解析Poss(Photogrammetric Oriented Points System)辅助空中三角测量是一种广泛应用在地理信息系统、遥感和测绘领域的技术。
基于C#的航带法空中三角测量程序设计与实现本文以Visual Studio 2010为平台。
使用C#语言,设计并实施了航带法空中三角测量程序。
本文叙述了航带法空中三角测量的原理以及程序设计与实验结果,将三个像对的数据使用编译的程序来进行实验。
实验主要进行了像对的相对定向、绝对定向、模型连接和模型的非线性改正等步骤,并剖析了程序结果的可靠性。
标签:C#;航带法;空中三角测量1 引言航空摄影测量的原理主要是利用二维地球图像提取三维表面空间信息[1],在航空摄影测量中,最常使用的方法就是利用合适的软件或者编写相应的程序来进行数据处理,在编写程序中使用最多的语言有VB、JA V A、C++、C#等,其中C#以其简单的界面、方便的语法、能够快速实现开发的特点得到了业界广泛的应用。
本文基于C#语言开展航带法空中三角测量程序的开发,并给予空中三角测量法建立单一导航区,其处理的本质是创建一个具有相对定向元素和模型点的单一模型,其次,基于连接点连接模型,为了建立统一的三维导航模型[2]。
2 航带法空中三角测量2.1 像素坐标测量与系统误差预校正照相材料的变形、摄影镜头的变形、大气折射和地球曲率造成二维图像点坐标的坐标误差,这些误差在每幅图像的影响是统一的,并且是系统性误差。
这些误差经过改正后的像点坐标公式为[1]:(1)上式中:()为各种系统误差的校正图像点的坐标;是照相材料校正后引起的点的坐标;为物镜畸变引起的像点坐标改正数;是大气折射影响引起的像点坐标的改正数;,为地球曲率引起的图像坐标改正数[1]。
2.2 像对的相对定向为航带内的每个单独模型建立图像空间辅助坐标系的像对定向的特征在于每个模型的图像空间辅助坐标系的轴是平行的,但是模型的比例尺是不同的,坐标原点也是不一致的[3]。
连续像对相对定向的解算公式为[1]:(2)q的含义表示为由相对定向建立的模型的上下差异,如果q=0,则表示已完成了像对的相对定向;相反,相对定向尚未完成,建立的模型仍然具有上下视差[1]。
using System;using System.Collections.Generic;using ponentModel;using System.Data;using System.Drawing;using System.Text;using System.Windows.Forms;using System.IO;using System.Data.OleDb;namespace 解析空中三角测量{public partial class Form1 : Form{public Form1(){InitializeComponent();}#region/////////////////////////////////////////////////////////////定义静态变量///////////////////////////////////////////////////////////////const int N = 150;int[] C = new int[3] { 15, 8, 11 };//各像对像点个数int[][] LDot = new int[3][];//像点点号int[] Control_Points = new int[4];//控制点点号int[] CheckPoint = new int[5];//检查点点号. double f = 153.033 / 1000.0;//主距double m;//比例尺//像对像点坐标double[][] x1 = new double[3][];double[][] y1 = new double[3][];double[][] x2 = new double[3][];double[][] y2 = new double[3][];//像点的像空间辅助坐标double[][] X1 = new double[3][];double[][] Y1 = new double[3][];double[][] Z1 = new double[3][];double[][] X2 = new double[3][];double[][] Y2 = new double[3][];double[][] Z2 = new double[3][];//相对定向元素double[] φ1 = new do uble[3];double[] ω1 = new double[3];double[] κ1 = new double[3];double[] φ2 = new double[3];double[] ω2 = new double[3];double[] κ2 = new double[3];double[] u = new double[3];double[] v = new double[3];//摄影基线分量double[] bx = new double[3];double[] by = new double[3];double[] bz = new double[3];//左、右像片投影系数N1,N2double[][] N1 = new double[3][];double[][] N2 = new double[3][];//上下视差Qdouble[][] Q = new double[3][];//模型点像空间辅助坐标double[][] Xm = new double[3][];double[][] Ym = new double[3][];double[][] Zm = new double[3][];//三个直线元素double[] Xs = new double[4];double[] Ys = new double[4];double[] Zs = new double[4];//模型点摄影测量坐标double[][] Xp = new double[3][];double[][] Yp = new double[3][];double[][] Zp = new double[3][];//绝对定向元素double ΔX, ΔY, ΔZ, λ, Φ, Ω,Κ;//控制点大地坐标double[] Xta = new double[4];double[] Yta = new double[4];double[] Zta = new double[4];//控制点地面摄影测量坐标double[] Xtpa = new double[4];double[] Ytpa = new double[4];double[] Ztpa = new double[4];//控制点摄影测量坐标double[] Xpa = new double[4];double[] Ypa = new double[4];double[] Zpa = new double[4];//模型点地面摄影测量坐标double[][] Xtp = new double[3][];double[][] Ytp = new double[3][];double[][] Ztp = new double[3][];//模型点大地坐标double[][] Xt = new double[3][];double[][] Yt = new double[3][];double[][] Zt = new double[3][];//检查点大地坐标double[] oXt = new double[5];double[] oYt = new double[5];double[] oZt = new double[5];//检查点的误差double[] oX = new double[5];double[] oY = new double[5];double[] oZ = new double[5];#endregion#region/////////////////////////////////////////////////////////////导入数据///////////////////////////////////////////////////////////////////private void 导入像点坐标数据ToolStripMenuItem_Click(object sender, EventArgs e){OpenFileDialog FILE = new OpenFileDialog();FILE.Filter = "文本文件(*.txt)|*.txt| 所有文件(*.*)|*.*";FILE.FilterIndex = 1;if (FILE.ShowDialog() == DialogResult.OK){StreamReader MSR = new StreamReader(FILE.FileName);string Line;//读取每行信息放在该字符串中double[,] Temp = new double[34, 5];//每行信息存放在该二维数组中int temp = 0;//将*.txt文件信息读到Temp[,]二维数组中while ((Line = MSR.ReadLine()) != null){char[] tt = new char[] { '\r', '\n' };string[] split = Line.Split(tt); //字符串转换为字符串数组string[] numbers;//读取的每行信息记录在数组中for (int i = 0; i < split.Length; i++){numbers = split[i].Split(' ');for (int j = 0, k = 0; j < numbers.Length && numbers[j] != ""; j++) Temp[temp, k++] = double.Parse(numbers[j]);}temp++;}MSR.Close();//用Temp中的数据赋值,并将单位换成米,并实例化像点坐标for (int i = 0; i < 3; i++){LDot[i] = new int[C[i]];x1[i] = new double[C[i]];y1[i] = new double[C[i]];x2[i] = new double[C[i]];y2[i] = new double[C[i]];}//像对1的坐标for (int i = 0; i < 15; i++){LDot[0][i] = (int)Temp[i, 0];x1[0][i] = Temp[i, 1] / 1000000.0;y1[0][i] = Temp[i, 2] / 1000000.0;x2[0][i] = Temp[i, 3] / 1000000.0;y2[0][i] = Temp[i, 4] / 1000000.0;}//像对2的坐标for (int i = 0; i < 8; i++){LDot[1][i] = (int)Temp[i + 15, 0];x1[1][i] = Temp[i + 15, 1] / 1000000.0;y1[1][i] = Temp[i + 15, 2] / 1000000.0;x2[1][i] = Temp[i + 15, 3] / 1000000.0;y2[1][i] = Temp[i + 15, 4] / 1000000.0;}//像对3的坐标for (int i = 0; i < 11; i++){LDot[2][i] = (int)Temp[i + 23, 0];x1[2][i] = Temp[i + 23, 1] / 1000000.0;y1[2][i] = Temp[i + 23, 2] / 1000000.0;x2[2][i] = Temp[i + 23, 3] / 1000000.0;y2[2][i] = Temp[i + 23, 4] / 1000000.0;}//显示像对坐标数据for (int i = 0; i < 34; i++){ListViewItem a;a = lst像对坐标数据.Items.Add(Temp[i, 0].ToString());a.SubItems.Add(Temp[i, 1].ToString());a.SubItems.Add(Temp[i, 2].ToString());a.SubItems.Add(Temp[i, 3].ToString());a.SubItems.Add(Temp[i, 4].ToString());}}}private void 导入控制点坐标数据ToolStripMenuItem_Click_1(object sender, EventArgs e){OpenFileDialog FILE = new OpenFileDialog();FILE.Filter = "文本文件(*.txt)|*.txt| 所有文件(*.*)|*.*";FILE.FilterIndex = 1;if (FILE.ShowDialog() == DialogResult.OK){StreamReader MSR = new StreamReader(FILE.FileName);string Line;//读取每行信息放在该字符串中double[,] Temp = new double[34, 5];//每行信息存放在该二维数组中int temp = 0;//将*.txt文件信息读到Temp[,]二维数组中while ((Line = MSR.ReadLine()) != null){char[] tt = new char[] { '\r', '\n' };string[] split = Line.Split(tt); //字符串转换为字符串数组string[] numbers;//读取的每行信息记录在数组中for (int i = 0; i < split.Length; i++){numbers = split[i].Split(' ');for (int j = 0, k = 0; j < numbers.Length && numbers[j] != ""; j++)Temp[temp, k++] = double.Parse(numbers[j]);}temp++;}MSR.Close();//用Temp中的数据赋值for (int i = 0; i < 4; i++){Control_Points[i] = (int)Temp[i, 0];Xta[i] = Temp[i, 1];Yta[i] = Temp[i, 2];Zta[i] = Temp[i, 3];}//显示控制点坐标数据for (int i = 0; i < 4; i++){ListViewItem a;a = lst控制点数据.Items.Add(Temp[i, 0].ToString());a.SubItems.Add(Temp[i, 1].ToString());a.SubItems.Add(Temp[i, 2].ToString());a.SubItems.Add(Temp[i, 3].ToString());}tab数据.SelectedTab = tab控制点数据;}}private void 导入检查点坐标数据ToolStripMenuItem_Click(object sender, EventArgs e){OpenFileDialog FILE = new OpenFileDialog();FILE.Filter = "文本文件(*.txt)|*.txt| 所有文件(*.*)|*.*";FILE.FilterIndex = 1;if (FILE.ShowDialog() == DialogResult.OK){StreamReader MSR = new StreamReader(FILE.FileName);string Line;//读取每行信息放在该字符串中double[,] Temp = new double[34, 5];//每行信息存放在该二维数组中int temp = 0;//将*.txt文件信息读到Temp[,]二维数组中while ((Line = MSR.ReadLine()) != null){char[] tt = new char[] { '\r', '\n' };string[] split = Line.Split(tt); //字符串转换为字符串数组string[] numbers;//读取的每行信息记录在数组中for (int i = 0; i < split.Length; i++){numbers = split[i].Split(' ');for (int j = 0, k = 0; j < numbers.Length && numbers[j] != ""; j++)Temp[temp, k++] = double.Parse(numbers[j]);}temp++;}MSR.Close();//用Temp中的数据赋值for (int i = 0; i < 5; i++){CheckPoint[i] = (int)Temp[i, 0];oXt[i] = Temp[i, 1];oYt[i] = Temp[i, 2];oZt[i] = Temp[i, 3];}//显示控制点坐标数据for (int i = 0; i < 5; i++){ListViewItem a;a = lst检查点数据.Items.Add(Temp[i, 0].ToString());a.SubItems.Add(Temp[i, 1].ToString());a.SubItems.Add(Temp[i, 2].ToString());a.SubItems.Add(Temp[i, 3].ToString());}}tab数据.SelectedTab = tab检查点坐标数据;}#endregion#region/////////////////////////////////////////////////////////////矩阵运算/////////////////////////////////////////////////////////////////////矩阵的转置运算private void Transpose(double[,] A, double[,] A T){int i, j;for (i = 0; i < A.GetLength(1); i++){for (j = 0; j < A.GetLength(0); j++){A T[i, j] = A[j, i];}}}//矩阵的乘法运算private void Matrix(double[,] AT, double[,] A, double[,] ATA){int i, j, k;for (i = 0; i < ATA.GetLength(0); i++){for (j = 0; j < ATA.GetLength(1); j++){A TA[i, j] = 0;for (k = 0; k < A T.GetLength(1); k++)ATA[i, j] += AT[i, k] * A[k, j];}}}// 矩阵求逆private void Inverse(double[,] A,double[,] AR){int i,j,h,k;int n = A.GetLength(0);double P;double[,] Q=new double[A.GetLength(0),2*A.GetLength(1)];for(i=0;i<n;i++) //1 2 3 //构造高斯矩阵for(j=0;j<n;j++) //2 3 4Q[i,j]=A[i,j]; //5 3 2for(i=0;i<n;i++)for(j=n;j<2*n;j++){ //1 2 3 1 0 0if(i+n==j) //2 3 4 0 1 0Q[i,j]=1; //5 3 2 0 0 1elseQ[i,j]=0;}for(h=k=0;k<n-1;k++,h++)//消去对角线以下的数据for(i=k+1;i<n;i++){if(Q[k,h]==0) // 0 X X 1 0 0for(int g=0;g<n;g++) // X X X 0 1 0if(Q[g,h]!=0) // X X x 0 0 1{ // 这种特殊情况的判断以及处理方式for(j=0;j<2*n;j++)Q[k,j]-=Q[g,j];break;}if(Q[i,h]==0) //将矩阵化为X X X X X Xcontinue; // 0 X X X X XP=Q[k,h]/Q[i,h]; // 0 0 X X X Xfor(j=0;j<2*n;j++) // 的形式{Q[i,j]*=P;Q[i,j]-=Q[k,j];}}for(h=k=n-1;k>0;k--,h--) // 消去对角线以上的数据for(i=k-1;i>=0;i--) // 此时无需考虑{if(Q[i,h]==0) // X X X X X Xcontinue; // 0 X X X X XP=Q[k,h]/Q[i,h]; // 0 0 0 X X Xfor(j=0;j<2*n;j++) //这种情况,因为此时矩阵对应的行列式值为0,即该矩阵不存在逆矩阵{Q[i,j]*=P;Q[i,j]-=Q[k,j];}}for(i=0;i<n;i++)//将对角线上数据化为1{P=1.0/Q[i,i];for(j=0;j<2*n;j++)Q[i,j]*=P;}for(i=0;i<n;i++) //提取逆矩阵for(j=0;j<n;j++)AR[i,j]=Q[i,j+n];}#endregion#region/////////////////////////////////////////////////////////////相对定向/////////////////////////////////////////////////////////////////// //初始化private void Initial(int i){//初始值if (i == 0){φ1[0] = 0;ω1[0] = 0;κ1[0] = 0;φ2[0] = 0;ω2[0] = 0;κ2[0] = 0;}else{φ1[i] = φ2[i - 1];ω1[i] = ω2[i - 1];κ1[i] = κ2[i - 1];φ2[i] = 0;ω2[i] = 0;κ2[i] = 0;}u[i] = 0;v[i] = 0;bx[i] = 200.0 / 1000.0;//像点像空间辅助坐标X1[i] = new double[C[i]];Y1[i] = new double[C[i]];Z1[i] = new double[C[i]];X2[i] = new double[C[i]];Y2[i] = new double[C[i]];Z2[i] = new double[C[i]];//投影系数和上下视差N1[i] = new double[C[i]];N2[i] = new double[C[i]];Q[i] = new double[C[i]];//模型点像空间辅助坐标Xm[i] = new double[C[i]];Ym[i] = new double[C[i]];Zm[i] = new double[C[i]];}//相对定向private void Directional(int i){//定义变量int n = 0;//统计迭代次数double d = 0.00000001;//精度double[,] R1 = new double[3, 3];//旋转矩阵R1double[,] R2 = new double[3, 3];//旋转矩阵R2double[,] A = new double[C[i], 5];//系数阵Adouble[,] AT = new double[5, C[i]];//A的转置ATdouble[,] ATA = new double[5, 5];//AT与A的乘积A TAdouble[,] ATAR = new double[5, 5];///ATA的逆阵ATARdouble[,] ATART = new double[5, C[i]];//ATAR的转置A TARTdouble[,] L = new double[C[i], 1];//误差方程中的常数项double[,] dx = new double[5, 1];//相对定向元素改正数Initial(i);//左片旋转矩阵R1,书79页R1[0, 0] = Math.Cos(φ1[i]) * Math.Cos(κ1[i]) - Math.Sin(φ1[i]) * Math.Sin(ω1[i]) * Math.Sin(κ1[i]);R1[0, 1] = -Math.Cos(φ1[i]) * Math.Sin(κ1[i]) - Math.Sin(φ1[i]) * Math.Sin(ω1[i]) * Math.Cos(κ1[i]);R1[0, 2] = -Math.Sin(φ1[i]) * Math.Cos(ω1[i]);R1[1, 0] = Math.Cos(ω1[i]) * Math.Sin(κ1[i]);R1[1, 1] = Math.Cos(ω1[i]) * Math.Cos(κ1[i]);R1[1, 2] = -Math.Sin(ω1[i]);R1[2, 0] = Math.Sin(φ1[i]) * Math.Cos(κ1[i]) + Math.Cos(φ1[i]) * Math.Sin(ω1[i]) * Math.Sin(κ1[i]);R1[2, 1] = -Math.Sin(φ1[i]) * Math.Sin(κ1[i]) + Math.Cos(φ1[i]) * Math.Sin(ω1[i]) * Math.Cos(κ1[i]);R1[2, 2] = Math.Cos(φ1[i]) * Math.Cos(ω1[i]);//左片像点像空辅坐标for (int j = 0; j < C[i]; j++){X1[i][j] = R1[0, 0] * x1[i][j] + R1[0, 1] * y1[i][j] - R1[0, 2] * f;Y1[i][j] = R1[1, 0] * x1[i][j] + R1[1, 1] * y1[i][j] - R1[1, 2] * f;Z1[i][j] = R1[2, 0] * x1[i][j] + R1[2, 1] * y1[i][j] - R1[2, 2] * f;}do{//by,bzby[i] = bx[i] * u[i];bz[i] = bx[i] * v[i];//右片旋转矩阵R2,书79页R2[0, 0] = Math.Cos(φ2[i]) * Math.Cos(κ2[i]) - Math.Sin(φ2[i]) * Math.Si n(ω2[i]) * Math.Sin(κ2[i]);R2[0, 1] = -Math.Cos(φ2[i]) * Math.Sin(κ2[i]) - Math.Sin(φ2[i]) * Math.Sin(ω2[i]) * Math.Cos(κ2[i]);R2[0, 2] = -Math.Sin(φ2[i]) * Math.Cos(ω2[i]);R2[1, 0] = Math.Cos(ω2[i]) * Math.Sin(κ2[i]);R2[1, 1] = Math.Cos(ω2[i]) * Math.Cos(κ2[i]);R2[1, 2] = -Math.Sin(ω2[i]);R2[2, 0] = Math.Sin(φ2[i]) * Math.Cos(κ2[i]) + Math.Cos(φ2[i]) * Math.Sin(ω2[i]) * Math.Sin(κ2[i]);R2[2, 1] = -Math.Sin(φ2[i]) * Math.Sin(κ2[i]) + Math.Cos(φ2[i]) * Math.Sin(ω2[i]) * Math.Cos(κ2[i]);R2[2, 2] = Math.Cos(φ2[i]) * Math.Cos(ω2[i]);for (int j = 0; j < C[i]; j++){//右片像点像空辅坐标X2[i][j] = R2[0, 0] * x2[i][j] + R2[0, 1] * y2[i][j] - R2[0, 2] * f;Y2[i][j] = R2[1, 0] * x2[i][j] + R2[1, 1] * y2[i][j] - R2[1, 2] * f;Z2[i][j] = R2[2, 0] * x2[i][j] + R2[2, 1] * y2[i][j] - R2[2, 2] * f;//N1,N2,QN1[i][j] = (bx[i] * Z2[i][j] - bz[i] * X2[i][j]) / (X1[i][j] * Z2[i][j] - X2[i][j] * Z1[i][j]);N2[i][j] = (bx[i] * Z1[i][j] - bz[i] * X1[i][j]) / (X1[i][j] * Z2[i][j] - X2[i][j] * Z1[i][j]);Q[i][j] = N1[i][j] * Y1[i][j] - N2[i][j] * Y2[i][j] - by[i];//误差方程系数矩阵A,书83页A[j, 0] = bx[i];A[j, 1] = -(Y2[i][j] / Z2[i][j]) * bx[i];A[j, 2] = -((X2[i][j] * Y2[i][j]) / Z2[i][j]) * N2[i][j];A[j, 3] = -(Z2[i][j] + Y2[i][j] * Y2[i][j] / Z2[i][j]) * N2[i][j];A[j, 4] = X2[i][j] * N2[i][j];//常数项LL[j, 0] = Q[i][j];}//A的转置ATTranspose(A, A T);//AT与A的乘积A TAMatrix(A T, A, ATA);//ATA的逆阵ATARInverse(ATA, A TAR);//ATAR与AT的乘积ATARTMatrix(A TAR, A T, ATART);//ATART *与L的乘积dxMatrix(A TART, L, dx);n++;if (n > N){MessageBox.Show("计算" + (n - 1)+"次后计算失败!", "请检查迭代次数和限差!", MessageBoxButtons.OK, MessageBoxIcon.Warning);break;}//相对定向元素新值u[i] += dx[0, 0];v[i] += dx[1, 0];φ2[i] += dx[2, 0];ω2[i] += dx[3, 0];κ2[i] += dx[4, 0];} while (Math.Abs(dx[0, 0]) >= d || Math.Abs(dx[1, 0]) >= d || Math.Abs(dx[2, 0]) >= d || Math.Abs(dx[3, 0]) >= d || Math.Abs(dx[4, 0]) >= d);//显示相对定向元素ListViewItem a;a = lst相对定向元素.Items.Add((i + 1).ToString());a.SubItems.Add(u[i].ToString("0.000000"));a.SubItems.Add(v[i].ToString("0.000000"));a.SubItems.Add(φ2[i].ToString("0.000000"));a.SubItems.Add(ω2[i].ToString("0.000000"));a.SubItems.Add(κ2[i].ToString("0.000000"));//模型点的像空间辅助坐标for (int j = 0; j < C[i]; j++){Xm[i][j] = N1[i][j] * X1[i][j];Ym[i][j] = (N1[i][j] * Y1[i][j] + N2[i][j] * Y2[i][j] + by[i]) * 0.5;Zm[i][j] = N1[i][j] * Z1[i][j];}tab处理.SelectedTab = tab相对定向;}private void 相对定向ToolStripMenuItem_Click(object sender, EventArgs e){//相对定向3次for (int i = 0; i < 3; i++)Directional(i);}#endregion#region/////////////////////////////////////////////////////////////模型连接,绝对定向,结果检查/////////////////////////////////////////////////private void 模型连接ToolStripMenuItem_Click_1(object sender, EventArgs e){//摄站的摄影测量坐标double[] Xps = new double[4];double[] Yps = new double[4];double[] Zps = new double[4];//归化系数double[] k = new double[3];double[] kk = new double[2];//比例尺归化系数for (int i = 0; i < 2; i++){int num = 0;for (int l = 0; l < C[i]; l++){for (int j = 0; j < C[i + 1]; j++){if (LDot[i][l] == LDot[i + 1][j]){if (i == 0)kk[i] += (Zm[i][l] - bz[i]) / Zm[i + 1][j];elsekk[i] += (Zm[i][l] - bz[i]) * kk[i - 1] / Zm[i + 1][j];num++;}}}kk[i] = kk[i] / num;//平均数}k[0] = 1;k[1] = kk[0];k[2] = kk[1];lblK1.Text = "k1=" + k[1].ToString("0.000000");lblK2.Text = "k2=" + k[2].ToString("0.000000");//比例尺m(1201,1205,1206)double[] MID = new double[3];/////////////////////////////////////////////每段长度比MID[0] = (Math.Sqrt((Xta[0] - Xta[1]) * (Xta[0] - Xta[1]) + (Yta[0] - Yta[1]) * (Yta[0] - Yta[1]))) /(Math.Sqrt((x1[0][0] - x1[0][5]) * (x1[0][0] - x1[0][5]) + (y1[0][0] - y1[0][5]) * (y1[0][0] - y1[0][5])));MID[1] = (Math.Sqrt((Xta[0] - Xta[2]) * (Xta[0] - Xta[2]) + (Yta[0] - Yta[2]) * (Yta[0] - Yta[2]))) /(Math.Sqrt((x1[0][0] - x1[0][6]) * (x1[0][0] - x1[0][6]) + (y1[0][0] - y1[0][6]) * (y1[0][0] - y1[0][6])));MID[2] = (Math.Sqrt((Xta[2] - Xta[1]) * (Xta[2] - Xta[1]) + (Yta[2] - Yta[1]) * (Yta[2] - Yta[1]))) /(Math.Sqrt((x1[0][6] - x1[0][5]) * (x1[0][6] - x1[0][5]) + (y1[0][6] - y1[0][5]) * (y1[0][6] - y1[0][5])));m = (MID[0] + MID[1] +MID[2]) / 3;lblm.Text = "m=" + m.ToString("0.000000");//模型摄站S的摄影测量坐标for (int i = 0; i < 4; i++){if (i == 0){Xps[0] = 0.0;Yps[0] = 0.0;Zps[0] = m * f;}else{Xps[i] = Xps[i - 1] + m * k[i - 1] * bx[i - 1];Yps[i] = Yps[i - 1] + m * k[i - 1] * by[i - 1];Zps[i] = Zps[i - 1] + m * k[i - 1] * bz[i - 1];}}//实例化模型点的摄影测量坐标for (int i = 0; i < 3; i++){Xp[i] = new double[C[i]];Yp[i] = new double[C[i]];Zp[i] = new double[C[i]];}//各模型点的摄影测量坐标for (int i = 0; i < 3; i++)for (int j = 0; j < C[i]; j++){Xp[i][j] = Xps[i] + k[i] * m * N1[i][j] * X1[i][j];Yp[i][j] = 0.5 * (Yps[i] + k[i] * m * N1[i][j] * Y1[i][j] + Yps[i + 1] + k[i] * m * N2[i][j] * Y2[i][j]);Zp[i][j] = Zps[i] + k[i] * m * N1[i][j] * Z1[i][j];}ListViewItem a;for (int i = 0; i < 3; i++)for (int j = 0; j < C[i]; j++){a = lst模型连接.Items.Add((LDot[i][j]).ToString());a.SubItems.Add(Xp[i][j].ToString("0.0000000"));a.SubItems.Add(Yp[i][j].ToString("0.0000000"));a.SubItems.Add(Zp[i][j].ToString("0.0000000"));}tab处理.SelectedTab = tab模型连接;}private void 绝对定向ToolStripMenuItem_Click(object sender, EventArgs e) {double ΔXt = 0, ΔYt = 0;//大地坐标差double ΔXp = 0, ΔYp = 0;//摄影测量坐标差double a, b, λ1;int n_1 = 0;//标记控制点1bool flag;//选定1和2两个控制点//从第一个模型里找到1点flag = false;for (int i = 0; i < 4; i++){for (int j = 0; j < C[0]; j++){if (LDot[0][j] == Control_Points[i]){ΔXt = Xta[i];ΔYt = Yta[i];ΔXp = Xp[0][j];ΔYp = Yp[0][j];n_1 = i;flag = true;}if (flag)break;}if (flag)break;}//从第三个模型里找到2点flag = false;for (int i = 0; i < 4; i++){for (int j = 0; j < C[2]; j++){if (LDot[2][j] == Control_Points[i]){ΔXt = Xta[i] - ΔXt;ΔYt = Yt a[i] - ΔYt;ΔXp = Xp[2][j] - ΔXp;ΔYp = Yp[2][j] - ΔYp;flag = true;}if (flag)break;}if (flag)break;}//a,b,λ1,书100页a = (ΔXp * ΔYt + ΔYp * ΔXt) / (ΔXt * ΔXt + ΔYt * ΔYt);b = (ΔXp * ΔXt - ΔYp * ΔYt) / (ΔXt * ΔXt + ΔYt * ΔYt);λ1 = Math.Sqrt(a * a + b * b);//控制点大地坐标转换为地面摄影测量坐标,书100页,6-2-11 for (int i = 0; i < 4; i++){Xtpa[i] = b * (Xta[i] - Xta[n_1]) + a * (Yta[i] - Yta[n_1]);Ytpa[i] = a * (Xta[i] - Xta[n_1]) - b * (Yta[i] - Yta[n_1]);Ztpa[i] = λ1 * (Zta[i] - Zta[n_1]);}//相同点号的控制点与对应的模型点for (int l = 0; l < 4; l++)for (int i = 0; i < 3; i++)for (int j = 0; j < C[i]; j++){if (LDot[i][j] == Control_Points[l]){Xpa[l] = Xp[i][j];Ypa[l] = Yp[i][j];Zpa[l] = Zp[i][j];}}int n = 0;double d = 0.0000001;double[,] R = new double[3, 3];//旋转矩阵Rdouble[,] A = new double[12, 7];//系数阵Adouble[,] AT = new double[7, 12];//A的转置ATdouble[,] A TA = new double[7, 7];//AT与A的乘积A TA double[,] ATAR = new double[7, 7];//ATA的逆阵ATAR double[,] ATART = new double[7, 12];//ATAR的转置ATARTdouble[,] L = new double[12, 1];//常数项double[,] dx = new double[7, 1];//改正数dxΔX = 0; ΔY = 0; ΔZ = 0; λ = 1; Φ = 0; Ω = 0; Κ = 0; //绝对定向元素的初始值for (int i = 0; i < 4; i++)//系数矩阵A{A[3 * i, 0] = 1;A[3 * i, 1] = 0;A[3 * i, 2] = 0;A[3 * i, 3] = Xpa[i];A[3 * i, 4] = -Zpa[i];A[3 * i, 5] = 0;A[3 * i, 6] = -Ypa[i];A[3 * i + 1, 0] = 0;A[3 * i + 1, 1] = 1;A[3 * i + 1, 2] = 0;A[3 * i + 1, 3] = Ypa[i];A[3 * i + 1, 4] = 0;A[3 * i + 1, 5] = -Zpa[i];A[3 * i + 1, 6] = Xpa[i];A[3 * i + 2, 0] = 0;A[3 * i + 2, 1] = 0;A[3 * i + 2, 2] = 1;A[3 * i + 2, 3] = Zpa[i];A[3 * i + 2, 4] = Xpa[i];A[3 * i + 2, 5] = Ypa[i];A[3 * i + 2, 6] = 0;}do{//计算旋转矩阵R,书79页R[0, 0] = Math.Cos(Φ) * Math.Cos(Κ) - Math.Sin(Φ) * Math.Sin(Ω) * Math.Sin(Κ);R[0, 1] = -Math.Cos(Φ) * Math.Sin(Κ) - Math.Sin(Φ) * Math.Sin(Ω) * Math.Cos(Κ);R[0, 2] = -Math.Sin(Φ) * Math.Cos(Ω);R[1, 0] = Math.Cos(Ω) * Math.Sin(Κ);R[1, 1] = Math.Cos(Ω) * Math.Cos(Κ);R[1, 2] = -Math.Sin(Ω);R[2, 0] = Math.Sin(Φ) * Math.Cos(Κ) + Math.Cos(Φ) * Math.Sin(Ω) * Math.Sin(Κ);R[2, 1] = -Math.Sin(Φ) * Math.Sin(Κ) + Math.Cos(Φ) * Math.Sin(Ω) * Math.Cos(Κ);R[2, 2] = Math.Cos(Φ) * Math.Cos(Ω);//c3//常数项Lfor (int i = 0; i < 4; i++){L[3 * i, 0] = Xtpa[i] - λ * (Xpa[i] - Κ * Ypa[i] - Φ * Zpa[i]) - ΔX;L[3 * i + 1, 0] = Ytpa[i] - λ * (Κ * Xpa[i] + Ypa[i] - Ω * Zpa[i]) - ΔY;L[3 * i + 2, 0] = Ztpa[i] - λ * (Φ * Xpa[i] + Ω * Ypa[i] + Zpa[i]) - ΔZ;}//A的转置ATTranspose(A, A T);//AT与A的乘积A TAMatrix(A T, A, ATA);//ATA的逆矩阵A TARInverse(ATA,A TAR);//ATAR与AT的乘积ATARTMatrix(A TAR, A T, ATART);//ATART与L的乘积dxMatrix(A TART, L, dx);n++;if (n > N){MessageBox.Show("计算" + (n - 1) + "次后计算失败!", "请检查迭代次数和限差!", MessageBoxButtons.OK, MessageBoxIcon.Warning);break;}//绝对定向元素新值ΔX += dx[0, 0];ΔY += dx[1, 0];ΔZ += dx[2, 0];λ += dx[3, 0];Φ += dx[4, 0];Ω += dx[5, 0];Κ += dx[6, 0];} while (Math.Abs(dx[0, 0]) >= d || Math.Abs(dx[1, 0]) >= d || Math.Abs(dx[2, 0]) >= d || Math.Abs(dx[3, 0]) >= d|| Math.Abs(dx[4, 0]) >= d || Math.Abs(dx[5, 0]) >= d || Math.Abs(dx[6, 0]) >= d);lblΔX.Text = "ΔX=" + ΔX.ToString("0.000000");lblΔY.Text = "ΔY=" + ΔY.ToString("0.000000");lblΔZ.Text = "ΔZ=" + ΔZ.ToString("0.000000");lblλ.Text = "λ=" + λ.ToString("0.000000");lblΦ.Text = "Φ=" + Φ.ToString("0.000000");lblΩ.Text = "Ω=" + Ω.ToString("0.000000");lblΚ.Text = "Κ=" + Κ.ToString("0.000000");//加密点的大地坐标//实例化模型点地面摄影测量坐标和大地坐标for (int i = 0; i < 3; i++){Xtp[i] = new double[C[i]];Ytp[i] = new double[C[i]];Ztp[i] = new double[C[i]];Xt[i] = new double[C[i]];Yt[i] = new double[C[i]];Zt[i] = new double[C[i]];}//模型点地面摄影测量坐标for (int i = 0; i < 3; i++)for (int j = 0; j < C[i]; j++){Xtp[i][j] = λ * (Xp[i][j] - Κ * Yp[i][j] - Φ * Zp[i][j]) + ΔX;Ytp[i][j] = λ * (Κ * Xp[i][j] + Yp[i][j] - Ω * Zp[i][j]) + ΔY;Ztp[i][j] = λ * (Φ * Xp[i][j] + Ω * Yp[i][j] + Zp[i][j]) + ΔZ;}//地面摄影测量坐标转换为大地坐标for (int i = 0; i < 3; i++)for (int j = 0; j < C[i]; j++){Xt[i][j] = (b * Xtp[i][j] + a * Ytp[i][j]) / (λ1 * λ1) + Xta[n_1];Yt[i][j] = (a * Xtp[i][j] - b * Ytp[i][j]) / (λ1 * λ1) + Yta[n_1];Zt[i][j] = Ztp[i][j] / λ1 + Zta[n_1];}ListViewItem g;for (int i = 0; i < 3; i++)for (int j = 0; j < C[i]; j++){g = lst绝对定向.Items.Add((LDot[i][j]).ToString());g.SubItems.Add(Xt[i][j].ToString("0.000000"));g.SubItems.Add(Yt[i][j].ToString("0.000000"));g.SubItems.Add(Zt[i][j].ToString("0.000000"));}tab处理.SelectedTab = tab绝对定向;}private void 结果检查ToolStripMenuItem_Click(object sender, EventArgs e){//////////////////////////////////////////////////////////////////////////计算检查点与与之对应像点解求的大地坐标之间的差值for (int l = 0; l < 5; l++)for (int i = 0; i < 3; i++)for (int j = 0; j < C[i]; j++){if (CheckPoint[l] == LDot[i][j]){oX[l] = Xt[i][j] - oXt[l];oY[l] = Yt[i][j] - oYt[l];oZ[l] = Zt[i][j] - oZt[l];}}//////////////////////////////////////////////////////////////////////////在窗口中显示检查结果ListViewItem g;for (int i = 0; i < 5; i++){g = lst检查结果.Items.Add((CheckPoint[i]).ToString());g.SubItems.Add(oX[i].ToString("0.000000"));g.SubItems.Add(oY[i].ToString("0.000000"));g.SubItems.Add(oZ[i].ToString("0.000000"));}tab处理.SelectedTab = tab结果检查;}#endregion#region/////////////////////////////////////////////////////////////退出///////////////////////////////////////////////////////////////////////private void 退出ToolStripMenuItem_Click(object sender, EventArgs e){SaveFileDialog FILE = new SaveFileDialog();FILE.Filter = "文本文件(*.txt)|*.txt| 所有文件(*.*)|*.*";FILE.FilterIndex = 1;if (FILE.ShowDialog() == DialogResult.OK){StreamWriter MSW = new StreamWriter(FILE.FileName);MSW.WriteLine("########################################1.相对定向元素####################################");for (int i = 0; i < 3; i++){MSW.WriteLine("像对" + Convert.ToString(i + 1));MSW.WriteLine("u=" + u[i].ToString("0.000000"));MSW.WriteLine("v=" + v[i].ToString("0.000000"));MSW.WriteLine("φ=" + φ2[i].ToString("0.000000"));MSW.WriteLine("ω=" + ω2[i].ToString("0.000000"));MSW.WriteLine("κ=" + κ2[i].ToString("0.000000"));MSW.WriteLine(" ");}for (int i = 0; i < 3; i++){MSW.WriteLine("第" + (i + 1) + "个模型点的像空间辅助坐标:");MSW.WriteLine(" ");MSW.WriteLine("点号" + "\t\t" + "Xm" + "\t\t" + " Ym" + "\t\t" + " Zm");for (int j = 0; j < C[i]; j++){MSW.WriteLine(LDot[i][j] + " " + Xm[i][j].ToString("0.0000000") + " " + Ym[i][j].ToString("0.0000000") + " " + Zm[i][j].ToString("0.0000000"));}MSW.WriteLine(" ");}MSW.WriteLine("########################################2.模型连接########################################");for (int i = 0; i < 3; i++){MSW.WriteLine("第" + (i + 1) + "个模型点的摄影测量坐标:");MSW.WriteLine(" ");MSW.WriteLine("点号" + "\t\t" + "Xp" + "\t\t" + " Yp" + "\t\t" + " Zp");for (int j = 0; j < C[i]; j++){MSW.WriteLine(LDot[i][j] + " " + Xp[i][j].ToString("0.0000000") + " " + Yp[i][j].ToString("0.0000000") + " " + Zp[i][j].ToString("0.0000000"));}MSW.WriteLine(" ");}MSW.WriteLine(" ");MSW.WriteLine("########################################3.绝对定向########################################");MSW.WriteLine(" ");MSW.WriteLine("绝对定向元素:");MSW.WriteLine("ΔX=" + ΔX.ToString("0.000000"));MSW.WriteLine("ΔY=" + ΔY.ToString("0.000000"));MSW.WriteLine("ΔZ=" + ΔZ.ToString("0.000000"));MSW.WriteLine("λ=" + λ.ToString("0.000000"));MSW.WriteLine("Φ=" + Φ.ToString("0.000000"));MSW.WriteLine("Ω=" + Ω.ToString("0.000000"));MSW.WriteLine("Κ=" + Κ.ToString("0.000000"));MSW.WriteLine(" ");for (int i = 0; i < 3; i++){MSW.WriteLine("第" + (i + 1) + "个模型点的地面摄影测量坐标为:");MSW.WriteLine(" ");MSW.WriteLine("点号" + "\t\t" + "Xtp" + "\t\t" + "Ytp" + "\t\t" + "Ztp");for (int j = 0; j < C[i]; j++){MSW.WriteLine(LDot[i][j] + "\t" + " " + Xtp[i][j].ToString("0.000000") + "\t" + " " + Ytp[i][j].ToString("0.000000") + "\t" + " " + Ztp[i][j].ToString("0.000000"));}MSW.WriteLine(" ");}for (int i = 0; i < 3; i++){MSW.WriteLine("第" + (i + 1) + "个像对的大地坐标为:");MSW.WriteLine(" ");MSW.WriteLine("点号" + "\t\t" + "Xt" + "\t\t" + "Yt" + "\t\t" + "Zt");for (int j = 0; j < C[i]; j++){MSW.WriteLine(LDot[i][j] + "\t" + " " + Xt[i][j].ToString("0.000000") + "\t" + " " + Yt[i][j].ToString("0.000000") + "\t" + " " + Zt[i][j].ToString("0.000000"));}MSW.WriteLine(" ");}MSW.WriteLine(" ");MSW.WriteLine("########################################4.结果检查########################################");MSW.WriteLine(" ");MSW.WriteLine("点号" + "\t\t" + "ΔXt" + "\t\t" + "ΔYt" + "\t\t" + "ΔZt");for (int i = 0; i < 5; i++){MSW.WriteLine(CheckPoint[i] + "\t\t" + oX[i].ToString("0.000000") + "\t\t" + oY[i].ToString("0.000000") + "\t\t" + oZ[i].ToString("0.000000"));}MSW.Close();MessageBox.Show("成功保存到" + FILE.FileName);}。
实验二、解析空中三角测量一、实验目的:了解VirtuoZo运行环境及软件模块的操作特点,了解软件使用大致流程,从而能对数字摄影测量有个整体概念。
完成航测影像的内定向,相对定向,绝对定向等工作。
二、实验工具:VirtuoZo软件三、实验原理:内定向: 建立影像扫描坐标与像点坐标的转换关系,求取转换参数;相对定向:通过量取模型的同名像点,解算两相邻影像的相对位置关系;绝对定向:通过量取地面控制点对应的像点坐标,解算模型的外方位元素,将模型纳入到大地坐标系中。
四、实验步骤:1.安装Virtuozo软件,安装好软件后再在“网上邻居”中的“本地连接”中将网络地址改为:。
2.建立测区:输入测区的相应参数(给出测区路径及测区名称、控制点文件路径及文件名、加密点文件路径及文件名、相机参数文件路径及文件名等)3.输入影像文件,将像素大小改为-14.新建模型:新建一个模型,并将左右影像导入(164为左影像,165为右影像)5.内定向:选择“处理--模型定向--内定向。
对各个框标进行调整,使他们的位置与模型的框标准确的重合.6.自动相对定向:在此步中,需要加入适当数量的控制点(即在实验一中选出的控制点,至少选择4个)。
然后点击鼠标右键进行自动相对定向。
根据右边的定向结果,删除不符合要求的点,然后再进行相对定向。
7.绝对定向:以普通方式进行绝对定向。
缩短步距改正DX,DY,DZ使得每个控制点的DX=DY=DZ=0。
五、实验结果:六、实验心得:通过本次实验让我对VirtuoZo这个软件有了一个大致的了解,了解了它运行环境和模块特点。
对内定向,相对定向,绝对定向也有了更清晰的认识,实验中印象很深刻的是软件的高度自动化和简单操作性。
在内定向,相对定向,绝对定向这几个在课本中看起来实现过程比较复杂的步骤,只用了很短的时间就在软件中完成了。
在三个步骤后自动生成了质量报告。
因为在实验室做的时候,刚开始接触,对步骤不太熟悉,所以时间比较仓促,精度不太高。
单元十三解析空中三角测量加密计算(1)教案头(2)教学内容1)概述通过对VirtuoZoAAT解析空中三角测量加密过程的讲解,使学生对解析空中三角测量加密计算的流程有一个宏观认识;通过上机练习,使学生能利用VirtuoZoAAT进行解析空中三角测量加密计算。
2)教学内容在完成自动转点之后,开始进入空三加密作业的最后一步,即编辑连接点并进行平差。
一般说来,加密作业的步骤为:●量测控制点;●在标准点位增加像点;●调用平差程序进行平差计算;●删除或编辑粗差像点;●重复③④直至满足加密要求;●输出加密成果。
①交互式编辑点击空三-〉交互式编辑,可以查看点位分布;此时要求标准位置必须有点,也就是每个像片的蓝框点位处必须有量测点,若没有,在此处进行加点。
②添加控制点在交互式编辑中,找到控制点所在像对,然后在航带的首尾加入至少四个点。
加完四个点后,进行平差解算,然后点击工具栏上的预测控制点选项,程序可预测出其它控制点的位置,再逐像对加入控制点。
注意:在加点过程中,必须要选择右边工具栏里的ctrl(如下图蓝色标记)选项,而且控制点点号必须一致。
如果不需要某一像片,可以点击空格键排除(显示很多横条)。
③带控制点的平差解算在AATM中选择平差-〉平差解算。
控制点精度预设为10 ,进行解算。
如果错误!未找到引用源。
中红标记中不是全为零,则点击左下角的被挑出的粗差点,修测标有星号的点,直接点击该点号,开始编辑。
编辑完成后,重复上述步骤,直到红标记中全为零。
④完成后,进行精确计算,如下图;⑤错误自检校。
进行相应设置(如下图),并执行。
⑥生成加密点。
进入AAT/PATB界面,如下点击相应菜单。
至此空三结束。
3)任务实施首先由教师在机房演示利用VirtuoZo软件进行解析空中三角测量加密计算的流程,并指导学生上机练习进行解析空中三角测量加密计算。
4)检查评价通过相互问答,由学生编写解析空中三角测量加密计算的成果报告,根据上交的成果情况,然后学生互评,而最终成绩由教师打分、学生互评、学生自评进行综合评定。
using System;using System.Collections.Generic;using ponentModel;using System.Data;using System.Drawing;using System.Text;using System.Windows.Forms;using System.IO;using System.Data.OleDb;namespace 解析空中三角测量{public partial class Form1 : Form{public Form1(){InitializeComponent();}#region/////////////////////////////////////////////////////////////定义静态变量///////////////////////////////////////////////////////////////const int N = 150;int[] C = new int[3] { 15, 8, 11 };//各像对像点个数int[][] LDot = new int[3][];//像点点号int[] Control_Points = new int[4];//控制点点号int[] CheckPoint = new int[5];//检查点点号. double f = 153.033 / 1000.0;//主距double m;//比例尺//像对像点坐标double[][] x1 = new double[3][];double[][] y1 = new double[3][];double[][] x2 = new double[3][];double[][] y2 = new double[3][];//像点的像空间辅助坐标double[][] X1 = new double[3][];double[][] Y1 = new double[3][];double[][] Z1 = new double[3][];double[][] X2 = new double[3][];double[][] Y2 = new double[3][];double[][] Z2 = new double[3][];//相对定向元素double[] φ1 = new do uble[3];double[] ω1 = new double[3];double[] κ1 = new double[3];double[] φ2 = new double[3];double[] ω2 = new double[3];double[] κ2 = new double[3];double[] u = new double[3];double[] v = new double[3];//摄影基线分量double[] bx = new double[3];double[] by = new double[3];double[] bz = new double[3];//左、右像片投影系数N1,N2double[][] N1 = new double[3][];double[][] N2 = new double[3][];//上下视差Qdouble[][] Q = new double[3][];//模型点像空间辅助坐标double[][] Xm = new double[3][];double[][] Ym = new double[3][];double[][] Zm = new double[3][];//三个直线元素double[] Xs = new double[4];double[] Ys = new double[4];double[] Zs = new double[4];//模型点摄影测量坐标double[][] Xp = new double[3][];double[][] Yp = new double[3][];double[][] Zp = new double[3][];//绝对定向元素double ΔX, ΔY, ΔZ, λ, Φ, Ω,Κ;//控制点大地坐标double[] Xta = new double[4];double[] Yta = new double[4];double[] Zta = new double[4];//控制点地面摄影测量坐标double[] Xtpa = new double[4];double[] Ytpa = new double[4];double[] Ztpa = new double[4];//控制点摄影测量坐标double[] Xpa = new double[4];double[] Ypa = new double[4];double[] Zpa = new double[4];//模型点地面摄影测量坐标double[][] Xtp = new double[3][];double[][] Ytp = new double[3][];double[][] Ztp = new double[3][];//模型点大地坐标double[][] Xt = new double[3][];double[][] Yt = new double[3][];double[][] Zt = new double[3][];//检查点大地坐标double[] oXt = new double[5];double[] oYt = new double[5];double[] oZt = new double[5];//检查点的误差double[] oX = new double[5];double[] oY = new double[5];double[] oZ = new double[5];#endregion#region/////////////////////////////////////////////////////////////导入数据///////////////////////////////////////////////////////////////////private void 导入像点坐标数据ToolStripMenuItem_Click(object sender, EventArgs e){OpenFileDialog FILE = new OpenFileDialog();FILE.Filter = "文本文件(*.txt)|*.txt| 所有文件(*.*)|*.*";FILE.FilterIndex = 1;if (FILE.ShowDialog() == DialogResult.OK){StreamReader MSR = new StreamReader(FILE.FileName);string Line;//读取每行信息放在该字符串中double[,] Temp = new double[34, 5];//每行信息存放在该二维数组中int temp = 0;//将*.txt文件信息读到Temp[,]二维数组中while ((Line = MSR.ReadLine()) != null){char[] tt = new char[] { '\r', '\n' };string[] split = Line.Split(tt); //字符串转换为字符串数组string[] numbers;//读取的每行信息记录在数组中for (int i = 0; i < split.Length; i++){numbers = split[i].Split(' ');for (int j = 0, k = 0; j < numbers.Length && numbers[j] != ""; j++) Temp[temp, k++] = double.Parse(numbers[j]);}temp++;}MSR.Close();//用Temp中的数据赋值,并将单位换成米,并实例化像点坐标for (int i = 0; i < 3; i++){LDot[i] = new int[C[i]];x1[i] = new double[C[i]];y1[i] = new double[C[i]];x2[i] = new double[C[i]];y2[i] = new double[C[i]];}//像对1的坐标for (int i = 0; i < 15; i++){LDot[0][i] = (int)Temp[i, 0];x1[0][i] = Temp[i, 1] / 1000000.0;y1[0][i] = Temp[i, 2] / 1000000.0;x2[0][i] = Temp[i, 3] / 1000000.0;y2[0][i] = Temp[i, 4] / 1000000.0;}//像对2的坐标for (int i = 0; i < 8; i++){LDot[1][i] = (int)Temp[i + 15, 0];x1[1][i] = Temp[i + 15, 1] / 1000000.0;y1[1][i] = Temp[i + 15, 2] / 1000000.0;x2[1][i] = Temp[i + 15, 3] / 1000000.0;y2[1][i] = Temp[i + 15, 4] / 1000000.0;}//像对3的坐标for (int i = 0; i < 11; i++){LDot[2][i] = (int)Temp[i + 23, 0];x1[2][i] = Temp[i + 23, 1] / 1000000.0;y1[2][i] = Temp[i + 23, 2] / 1000000.0;x2[2][i] = Temp[i + 23, 3] / 1000000.0;y2[2][i] = Temp[i + 23, 4] / 1000000.0;}//显示像对坐标数据for (int i = 0; i < 34; i++){ListViewItem a;a = lst像对坐标数据.Items.Add(Temp[i, 0].ToString());a.SubItems.Add(Temp[i, 1].ToString());a.SubItems.Add(Temp[i, 2].ToString());a.SubItems.Add(Temp[i, 3].ToString());a.SubItems.Add(Temp[i, 4].ToString());}}}private void 导入控制点坐标数据ToolStripMenuItem_Click_1(object sender, EventArgs e){OpenFileDialog FILE = new OpenFileDialog();FILE.Filter = "文本文件(*.txt)|*.txt| 所有文件(*.*)|*.*";FILE.FilterIndex = 1;if (FILE.ShowDialog() == DialogResult.OK){StreamReader MSR = new StreamReader(FILE.FileName);string Line;//读取每行信息放在该字符串中double[,] Temp = new double[34, 5];//每行信息存放在该二维数组中int temp = 0;//将*.txt文件信息读到Temp[,]二维数组中while ((Line = MSR.ReadLine()) != null){char[] tt = new char[] { '\r', '\n' };string[] split = Line.Split(tt); //字符串转换为字符串数组string[] numbers;//读取的每行信息记录在数组中for (int i = 0; i < split.Length; i++){numbers = split[i].Split(' ');for (int j = 0, k = 0; j < numbers.Length && numbers[j] != ""; j++)Temp[temp, k++] = double.Parse(numbers[j]);}temp++;}MSR.Close();//用Temp中的数据赋值for (int i = 0; i < 4; i++){Control_Points[i] = (int)Temp[i, 0];Xta[i] = Temp[i, 1];Yta[i] = Temp[i, 2];Zta[i] = Temp[i, 3];}//显示控制点坐标数据for (int i = 0; i < 4; i++){ListViewItem a;a = lst控制点数据.Items.Add(Temp[i, 0].ToString());a.SubItems.Add(Temp[i, 1].ToString());a.SubItems.Add(Temp[i, 2].ToString());a.SubItems.Add(Temp[i, 3].ToString());}tab数据.SelectedTab = tab控制点数据;}}private void 导入检查点坐标数据ToolStripMenuItem_Click(object sender, EventArgs e){OpenFileDialog FILE = new OpenFileDialog();FILE.Filter = "文本文件(*.txt)|*.txt| 所有文件(*.*)|*.*";FILE.FilterIndex = 1;if (FILE.ShowDialog() == DialogResult.OK){StreamReader MSR = new StreamReader(FILE.FileName);string Line;//读取每行信息放在该字符串中double[,] Temp = new double[34, 5];//每行信息存放在该二维数组中int temp = 0;//将*.txt文件信息读到Temp[,]二维数组中while ((Line = MSR.ReadLine()) != null){char[] tt = new char[] { '\r', '\n' };string[] split = Line.Split(tt); //字符串转换为字符串数组string[] numbers;//读取的每行信息记录在数组中for (int i = 0; i < split.Length; i++){numbers = split[i].Split(' ');for (int j = 0, k = 0; j < numbers.Length && numbers[j] != ""; j++)Temp[temp, k++] = double.Parse(numbers[j]);}temp++;}MSR.Close();//用Temp中的数据赋值for (int i = 0; i < 5; i++){CheckPoint[i] = (int)Temp[i, 0];oXt[i] = Temp[i, 1];oYt[i] = Temp[i, 2];oZt[i] = Temp[i, 3];}//显示控制点坐标数据for (int i = 0; i < 5; i++){ListViewItem a;a = lst检查点数据.Items.Add(Temp[i, 0].ToString());a.SubItems.Add(Temp[i, 1].ToString());a.SubItems.Add(Temp[i, 2].ToString());a.SubItems.Add(Temp[i, 3].ToString());}}tab数据.SelectedTab = tab检查点坐标数据;}#endregion#region/////////////////////////////////////////////////////////////矩阵运算/////////////////////////////////////////////////////////////////////矩阵的转置运算private void Transpose(double[,] A, double[,] A T){int i, j;for (i = 0; i < A.GetLength(1); i++){for (j = 0; j < A.GetLength(0); j++){A T[i, j] = A[j, i];}}}//矩阵的乘法运算private void Matrix(double[,] AT, double[,] A, double[,] ATA){int i, j, k;for (i = 0; i < ATA.GetLength(0); i++){for (j = 0; j < ATA.GetLength(1); j++){A TA[i, j] = 0;for (k = 0; k < A T.GetLength(1); k++)ATA[i, j] += AT[i, k] * A[k, j];}}}// 矩阵求逆private void Inverse(double[,] A,double[,] AR){int i,j,h,k;int n = A.GetLength(0);double P;double[,] Q=new double[A.GetLength(0),2*A.GetLength(1)];for(i=0;i<n;i++) //1 2 3 //构造高斯矩阵for(j=0;j<n;j++) //2 3 4Q[i,j]=A[i,j]; //5 3 2for(i=0;i<n;i++)for(j=n;j<2*n;j++){ //1 2 3 1 0 0if(i+n==j) //2 3 4 0 1 0Q[i,j]=1; //5 3 2 0 0 1elseQ[i,j]=0;}for(h=k=0;k<n-1;k++,h++)//消去对角线以下的数据for(i=k+1;i<n;i++){if(Q[k,h]==0) // 0 X X 1 0 0for(int g=0;g<n;g++) // X X X 0 1 0if(Q[g,h]!=0) // X X x 0 0 1{ // 这种特殊情况的判断以及处理方式for(j=0;j<2*n;j++)Q[k,j]-=Q[g,j];break;}if(Q[i,h]==0) //将矩阵化为X X X X X Xcontinue; // 0 X X X X XP=Q[k,h]/Q[i,h]; // 0 0 X X X Xfor(j=0;j<2*n;j++) // 的形式{Q[i,j]*=P;Q[i,j]-=Q[k,j];}}for(h=k=n-1;k>0;k--,h--) // 消去对角线以上的数据for(i=k-1;i>=0;i--) // 此时无需考虑{if(Q[i,h]==0) // X X X X X Xcontinue; // 0 X X X X XP=Q[k,h]/Q[i,h]; // 0 0 0 X X Xfor(j=0;j<2*n;j++) //这种情况,因为此时矩阵对应的行列式值为0,即该矩阵不存在逆矩阵{Q[i,j]*=P;Q[i,j]-=Q[k,j];}}for(i=0;i<n;i++)//将对角线上数据化为1{P=1.0/Q[i,i];for(j=0;j<2*n;j++)Q[i,j]*=P;}for(i=0;i<n;i++) //提取逆矩阵for(j=0;j<n;j++)AR[i,j]=Q[i,j+n];}#endregion#region/////////////////////////////////////////////////////////////相对定向/////////////////////////////////////////////////////////////////// //初始化private void Initial(int i){//初始值if (i == 0){φ1[0] = 0;ω1[0] = 0;κ1[0] = 0;φ2[0] = 0;ω2[0] = 0;κ2[0] = 0;}else{φ1[i] = φ2[i - 1];ω1[i] = ω2[i - 1];κ1[i] = κ2[i - 1];φ2[i] = 0;ω2[i] = 0;κ2[i] = 0;}u[i] = 0;v[i] = 0;bx[i] = 200.0 / 1000.0;//像点像空间辅助坐标X1[i] = new double[C[i]];Y1[i] = new double[C[i]];Z1[i] = new double[C[i]];X2[i] = new double[C[i]];Y2[i] = new double[C[i]];Z2[i] = new double[C[i]];//投影系数和上下视差N1[i] = new double[C[i]];N2[i] = new double[C[i]];Q[i] = new double[C[i]];//模型点像空间辅助坐标Xm[i] = new double[C[i]];Ym[i] = new double[C[i]];Zm[i] = new double[C[i]];}//相对定向private void Directional(int i){//定义变量int n = 0;//统计迭代次数double d = 0.00000001;//精度double[,] R1 = new double[3, 3];//旋转矩阵R1double[,] R2 = new double[3, 3];//旋转矩阵R2double[,] A = new double[C[i], 5];//系数阵Adouble[,] AT = new double[5, C[i]];//A的转置ATdouble[,] ATA = new double[5, 5];//AT与A的乘积A TAdouble[,] ATAR = new double[5, 5];///ATA的逆阵ATARdouble[,] ATART = new double[5, C[i]];//ATAR的转置A TARTdouble[,] L = new double[C[i], 1];//误差方程中的常数项double[,] dx = new double[5, 1];//相对定向元素改正数Initial(i);//左片旋转矩阵R1,书79页R1[0, 0] = Math.Cos(φ1[i]) * Math.Cos(κ1[i]) - Math.Sin(φ1[i]) * Math.Sin(ω1[i]) * Math.Sin(κ1[i]);R1[0, 1] = -Math.Cos(φ1[i]) * Math.Sin(κ1[i]) - Math.Sin(φ1[i]) * Math.Sin(ω1[i]) * Math.Cos(κ1[i]);R1[0, 2] = -Math.Sin(φ1[i]) * Math.Cos(ω1[i]);R1[1, 0] = Math.Cos(ω1[i]) * Math.Sin(κ1[i]);R1[1, 1] = Math.Cos(ω1[i]) * Math.Cos(κ1[i]);R1[1, 2] = -Math.Sin(ω1[i]);R1[2, 0] = Math.Sin(φ1[i]) * Math.Cos(κ1[i]) + Math.Cos(φ1[i]) * Math.Sin(ω1[i]) * Math.Sin(κ1[i]);R1[2, 1] = -Math.Sin(φ1[i]) * Math.Sin(κ1[i]) + Math.Cos(φ1[i]) * Math.Sin(ω1[i]) * Math.Cos(κ1[i]);R1[2, 2] = Math.Cos(φ1[i]) * Math.Cos(ω1[i]);//左片像点像空辅坐标for (int j = 0; j < C[i]; j++){X1[i][j] = R1[0, 0] * x1[i][j] + R1[0, 1] * y1[i][j] - R1[0, 2] * f;Y1[i][j] = R1[1, 0] * x1[i][j] + R1[1, 1] * y1[i][j] - R1[1, 2] * f;Z1[i][j] = R1[2, 0] * x1[i][j] + R1[2, 1] * y1[i][j] - R1[2, 2] * f;}do{//by,bzby[i] = bx[i] * u[i];bz[i] = bx[i] * v[i];//右片旋转矩阵R2,书79页R2[0, 0] = Math.Cos(φ2[i]) * Math.Cos(κ2[i]) - Math.Sin(φ2[i]) * Math.Si n(ω2[i]) * Math.Sin(κ2[i]);R2[0, 1] = -Math.Cos(φ2[i]) * Math.Sin(κ2[i]) - Math.Sin(φ2[i]) * Math.Sin(ω2[i]) * Math.Cos(κ2[i]);R2[0, 2] = -Math.Sin(φ2[i]) * Math.Cos(ω2[i]);R2[1, 0] = Math.Cos(ω2[i]) * Math.Sin(κ2[i]);R2[1, 1] = Math.Cos(ω2[i]) * Math.Cos(κ2[i]);R2[1, 2] = -Math.Sin(ω2[i]);R2[2, 0] = Math.Sin(φ2[i]) * Math.Cos(κ2[i]) + Math.Cos(φ2[i]) * Math.Sin(ω2[i]) * Math.Sin(κ2[i]);R2[2, 1] = -Math.Sin(φ2[i]) * Math.Sin(κ2[i]) + Math.Cos(φ2[i]) * Math.Sin(ω2[i]) * Math.Cos(κ2[i]);R2[2, 2] = Math.Cos(φ2[i]) * Math.Cos(ω2[i]);for (int j = 0; j < C[i]; j++){//右片像点像空辅坐标X2[i][j] = R2[0, 0] * x2[i][j] + R2[0, 1] * y2[i][j] - R2[0, 2] * f;Y2[i][j] = R2[1, 0] * x2[i][j] + R2[1, 1] * y2[i][j] - R2[1, 2] * f;Z2[i][j] = R2[2, 0] * x2[i][j] + R2[2, 1] * y2[i][j] - R2[2, 2] * f;//N1,N2,QN1[i][j] = (bx[i] * Z2[i][j] - bz[i] * X2[i][j]) / (X1[i][j] * Z2[i][j] - X2[i][j] * Z1[i][j]);N2[i][j] = (bx[i] * Z1[i][j] - bz[i] * X1[i][j]) / (X1[i][j] * Z2[i][j] - X2[i][j] * Z1[i][j]);Q[i][j] = N1[i][j] * Y1[i][j] - N2[i][j] * Y2[i][j] - by[i];//误差方程系数矩阵A,书83页A[j, 0] = bx[i];A[j, 1] = -(Y2[i][j] / Z2[i][j]) * bx[i];A[j, 2] = -((X2[i][j] * Y2[i][j]) / Z2[i][j]) * N2[i][j];A[j, 3] = -(Z2[i][j] + Y2[i][j] * Y2[i][j] / Z2[i][j]) * N2[i][j];A[j, 4] = X2[i][j] * N2[i][j];//常数项LL[j, 0] = Q[i][j];}//A的转置ATTranspose(A, A T);//AT与A的乘积A TAMatrix(A T, A, ATA);//ATA的逆阵ATARInverse(ATA, A TAR);//ATAR与AT的乘积ATARTMatrix(A TAR, A T, ATART);//ATART *与L的乘积dxMatrix(A TART, L, dx);n++;if (n > N){MessageBox.Show("计算" + (n - 1)+"次后计算失败!", "请检查迭代次数和限差!", MessageBoxButtons.OK, MessageBoxIcon.Warning);break;}//相对定向元素新值u[i] += dx[0, 0];v[i] += dx[1, 0];φ2[i] += dx[2, 0];ω2[i] += dx[3, 0];κ2[i] += dx[4, 0];} while (Math.Abs(dx[0, 0]) >= d || Math.Abs(dx[1, 0]) >= d || Math.Abs(dx[2, 0]) >= d || Math.Abs(dx[3, 0]) >= d || Math.Abs(dx[4, 0]) >= d);//显示相对定向元素ListViewItem a;a = lst相对定向元素.Items.Add((i + 1).ToString());a.SubItems.Add(u[i].ToString("0.000000"));a.SubItems.Add(v[i].ToString("0.000000"));a.SubItems.Add(φ2[i].ToString("0.000000"));a.SubItems.Add(ω2[i].ToString("0.000000"));a.SubItems.Add(κ2[i].ToString("0.000000"));//模型点的像空间辅助坐标for (int j = 0; j < C[i]; j++){Xm[i][j] = N1[i][j] * X1[i][j];Ym[i][j] = (N1[i][j] * Y1[i][j] + N2[i][j] * Y2[i][j] + by[i]) * 0.5;Zm[i][j] = N1[i][j] * Z1[i][j];}tab处理.SelectedTab = tab相对定向;}private void 相对定向ToolStripMenuItem_Click(object sender, EventArgs e){//相对定向3次for (int i = 0; i < 3; i++)Directional(i);}#endregion#region/////////////////////////////////////////////////////////////模型连接,绝对定向,结果检查/////////////////////////////////////////////////private void 模型连接ToolStripMenuItem_Click_1(object sender, EventArgs e){//摄站的摄影测量坐标double[] Xps = new double[4];double[] Yps = new double[4];double[] Zps = new double[4];//归化系数double[] k = new double[3];double[] kk = new double[2];//比例尺归化系数for (int i = 0; i < 2; i++){int num = 0;for (int l = 0; l < C[i]; l++){for (int j = 0; j < C[i + 1]; j++){if (LDot[i][l] == LDot[i + 1][j]){if (i == 0)kk[i] += (Zm[i][l] - bz[i]) / Zm[i + 1][j];elsekk[i] += (Zm[i][l] - bz[i]) * kk[i - 1] / Zm[i + 1][j];num++;}}}kk[i] = kk[i] / num;//平均数}k[0] = 1;k[1] = kk[0];k[2] = kk[1];lblK1.Text = "k1=" + k[1].ToString("0.000000");lblK2.Text = "k2=" + k[2].ToString("0.000000");//比例尺m(1201,1205,1206)double[] MID = new double[3];/////////////////////////////////////////////每段长度比MID[0] = (Math.Sqrt((Xta[0] - Xta[1]) * (Xta[0] - Xta[1]) + (Yta[0] - Yta[1]) * (Yta[0] - Yta[1]))) /(Math.Sqrt((x1[0][0] - x1[0][5]) * (x1[0][0] - x1[0][5]) + (y1[0][0] - y1[0][5]) * (y1[0][0] - y1[0][5])));MID[1] = (Math.Sqrt((Xta[0] - Xta[2]) * (Xta[0] - Xta[2]) + (Yta[0] - Yta[2]) * (Yta[0] - Yta[2]))) /(Math.Sqrt((x1[0][0] - x1[0][6]) * (x1[0][0] - x1[0][6]) + (y1[0][0] - y1[0][6]) * (y1[0][0] - y1[0][6])));MID[2] = (Math.Sqrt((Xta[2] - Xta[1]) * (Xta[2] - Xta[1]) + (Yta[2] - Yta[1]) * (Yta[2] - Yta[1]))) /(Math.Sqrt((x1[0][6] - x1[0][5]) * (x1[0][6] - x1[0][5]) + (y1[0][6] - y1[0][5]) * (y1[0][6] - y1[0][5])));m = (MID[0] + MID[1] +MID[2]) / 3;lblm.Text = "m=" + m.ToString("0.000000");//模型摄站S的摄影测量坐标for (int i = 0; i < 4; i++){if (i == 0){Xps[0] = 0.0;Yps[0] = 0.0;Zps[0] = m * f;}else{Xps[i] = Xps[i - 1] + m * k[i - 1] * bx[i - 1];Yps[i] = Yps[i - 1] + m * k[i - 1] * by[i - 1];Zps[i] = Zps[i - 1] + m * k[i - 1] * bz[i - 1];}}//实例化模型点的摄影测量坐标for (int i = 0; i < 3; i++){Xp[i] = new double[C[i]];Yp[i] = new double[C[i]];Zp[i] = new double[C[i]];}//各模型点的摄影测量坐标for (int i = 0; i < 3; i++)for (int j = 0; j < C[i]; j++){Xp[i][j] = Xps[i] + k[i] * m * N1[i][j] * X1[i][j];Yp[i][j] = 0.5 * (Yps[i] + k[i] * m * N1[i][j] * Y1[i][j] + Yps[i + 1] + k[i] * m * N2[i][j] * Y2[i][j]);Zp[i][j] = Zps[i] + k[i] * m * N1[i][j] * Z1[i][j];}ListViewItem a;for (int i = 0; i < 3; i++)for (int j = 0; j < C[i]; j++){a = lst模型连接.Items.Add((LDot[i][j]).ToString());a.SubItems.Add(Xp[i][j].ToString("0.0000000"));a.SubItems.Add(Yp[i][j].ToString("0.0000000"));a.SubItems.Add(Zp[i][j].ToString("0.0000000"));}tab处理.SelectedTab = tab模型连接;}private void 绝对定向ToolStripMenuItem_Click(object sender, EventArgs e) {double ΔXt = 0, ΔYt = 0;//大地坐标差double ΔXp = 0, ΔYp = 0;//摄影测量坐标差double a, b, λ1;int n_1 = 0;//标记控制点1bool flag;//选定1和2两个控制点//从第一个模型里找到1点flag = false;for (int i = 0; i < 4; i++){for (int j = 0; j < C[0]; j++){if (LDot[0][j] == Control_Points[i]){ΔXt = Xta[i];ΔYt = Yta[i];ΔXp = Xp[0][j];ΔYp = Yp[0][j];n_1 = i;flag = true;}if (flag)break;}if (flag)break;}//从第三个模型里找到2点flag = false;for (int i = 0; i < 4; i++){for (int j = 0; j < C[2]; j++){if (LDot[2][j] == Control_Points[i]){ΔXt = Xta[i] - ΔXt;ΔYt = Yt a[i] - ΔYt;ΔXp = Xp[2][j] - ΔXp;ΔYp = Yp[2][j] - ΔYp;flag = true;}if (flag)break;}if (flag)break;}//a,b,λ1,书100页a = (ΔXp * ΔYt + ΔYp * ΔXt) / (ΔXt * ΔXt + ΔYt * ΔYt);b = (ΔXp * ΔXt - ΔYp * ΔYt) / (ΔXt * ΔXt + ΔYt * ΔYt);λ1 = Math.Sqrt(a * a + b * b);//控制点大地坐标转换为地面摄影测量坐标,书100页,6-2-11 for (int i = 0; i < 4; i++){Xtpa[i] = b * (Xta[i] - Xta[n_1]) + a * (Yta[i] - Yta[n_1]);Ytpa[i] = a * (Xta[i] - Xta[n_1]) - b * (Yta[i] - Yta[n_1]);Ztpa[i] = λ1 * (Zta[i] - Zta[n_1]);}//相同点号的控制点与对应的模型点for (int l = 0; l < 4; l++)for (int i = 0; i < 3; i++)for (int j = 0; j < C[i]; j++){if (LDot[i][j] == Control_Points[l]){Xpa[l] = Xp[i][j];Ypa[l] = Yp[i][j];Zpa[l] = Zp[i][j];}}int n = 0;double d = 0.0000001;double[,] R = new double[3, 3];//旋转矩阵Rdouble[,] A = new double[12, 7];//系数阵Adouble[,] AT = new double[7, 12];//A的转置ATdouble[,] A TA = new double[7, 7];//AT与A的乘积A TA double[,] ATAR = new double[7, 7];//ATA的逆阵ATAR double[,] ATART = new double[7, 12];//ATAR的转置ATARTdouble[,] L = new double[12, 1];//常数项double[,] dx = new double[7, 1];//改正数dxΔX = 0; ΔY = 0; ΔZ = 0; λ = 1; Φ = 0; Ω = 0; Κ = 0; //绝对定向元素的初始值for (int i = 0; i < 4; i++)//系数矩阵A{A[3 * i, 0] = 1;A[3 * i, 1] = 0;A[3 * i, 2] = 0;A[3 * i, 3] = Xpa[i];A[3 * i, 4] = -Zpa[i];A[3 * i, 5] = 0;A[3 * i, 6] = -Ypa[i];A[3 * i + 1, 0] = 0;A[3 * i + 1, 1] = 1;A[3 * i + 1, 2] = 0;A[3 * i + 1, 3] = Ypa[i];A[3 * i + 1, 4] = 0;A[3 * i + 1, 5] = -Zpa[i];A[3 * i + 1, 6] = Xpa[i];A[3 * i + 2, 0] = 0;A[3 * i + 2, 1] = 0;A[3 * i + 2, 2] = 1;A[3 * i + 2, 3] = Zpa[i];A[3 * i + 2, 4] = Xpa[i];A[3 * i + 2, 5] = Ypa[i];A[3 * i + 2, 6] = 0;}do{//计算旋转矩阵R,书79页R[0, 0] = Math.Cos(Φ) * Math.Cos(Κ) - Math.Sin(Φ) * Math.Sin(Ω) * Math.Sin(Κ);R[0, 1] = -Math.Cos(Φ) * Math.Sin(Κ) - Math.Sin(Φ) * Math.Sin(Ω) * Math.Cos(Κ);R[0, 2] = -Math.Sin(Φ) * Math.Cos(Ω);R[1, 0] = Math.Cos(Ω) * Math.Sin(Κ);R[1, 1] = Math.Cos(Ω) * Math.Cos(Κ);R[1, 2] = -Math.Sin(Ω);R[2, 0] = Math.Sin(Φ) * Math.Cos(Κ) + Math.Cos(Φ) * Math.Sin(Ω) * Math.Sin(Κ);R[2, 1] = -Math.Sin(Φ) * Math.Sin(Κ) + Math.Cos(Φ) * Math.Sin(Ω) * Math.Cos(Κ);R[2, 2] = Math.Cos(Φ) * Math.Cos(Ω);//c3//常数项Lfor (int i = 0; i < 4; i++){L[3 * i, 0] = Xtpa[i] - λ * (Xpa[i] - Κ * Ypa[i] - Φ * Zpa[i]) - ΔX;L[3 * i + 1, 0] = Ytpa[i] - λ * (Κ * Xpa[i] + Ypa[i] - Ω * Zpa[i]) - ΔY;L[3 * i + 2, 0] = Ztpa[i] - λ * (Φ * Xpa[i] + Ω * Ypa[i] + Zpa[i]) - ΔZ;}//A的转置ATTranspose(A, A T);//AT与A的乘积A TAMatrix(A T, A, ATA);//ATA的逆矩阵A TARInverse(ATA,A TAR);//ATAR与AT的乘积ATARTMatrix(A TAR, A T, ATART);//ATART与L的乘积dxMatrix(A TART, L, dx);n++;if (n > N){MessageBox.Show("计算" + (n - 1) + "次后计算失败!", "请检查迭代次数和限差!", MessageBoxButtons.OK, MessageBoxIcon.Warning);break;}//绝对定向元素新值ΔX += dx[0, 0];ΔY += dx[1, 0];ΔZ += dx[2, 0];λ += dx[3, 0];Φ += dx[4, 0];Ω += dx[5, 0];Κ += dx[6, 0];} while (Math.Abs(dx[0, 0]) >= d || Math.Abs(dx[1, 0]) >= d || Math.Abs(dx[2, 0]) >= d || Math.Abs(dx[3, 0]) >= d|| Math.Abs(dx[4, 0]) >= d || Math.Abs(dx[5, 0]) >= d || Math.Abs(dx[6, 0]) >= d);lblΔX.Text = "ΔX=" + ΔX.ToString("0.000000");lblΔY.Text = "ΔY=" + ΔY.ToString("0.000000");lblΔZ.Text = "ΔZ=" + ΔZ.ToString("0.000000");lblλ.Text = "λ=" + λ.ToString("0.000000");lblΦ.Text = "Φ=" + Φ.ToString("0.000000");lblΩ.Text = "Ω=" + Ω.ToString("0.000000");lblΚ.Text = "Κ=" + Κ.ToString("0.000000");//加密点的大地坐标//实例化模型点地面摄影测量坐标和大地坐标for (int i = 0; i < 3; i++){Xtp[i] = new double[C[i]];Ytp[i] = new double[C[i]];Ztp[i] = new double[C[i]];Xt[i] = new double[C[i]];Yt[i] = new double[C[i]];Zt[i] = new double[C[i]];}//模型点地面摄影测量坐标for (int i = 0; i < 3; i++)for (int j = 0; j < C[i]; j++){Xtp[i][j] = λ * (Xp[i][j] - Κ * Yp[i][j] - Φ * Zp[i][j]) + ΔX;Ytp[i][j] = λ * (Κ * Xp[i][j] + Yp[i][j] - Ω * Zp[i][j]) + ΔY;Ztp[i][j] = λ * (Φ * Xp[i][j] + Ω * Yp[i][j] + Zp[i][j]) + ΔZ;}//地面摄影测量坐标转换为大地坐标for (int i = 0; i < 3; i++)for (int j = 0; j < C[i]; j++){Xt[i][j] = (b * Xtp[i][j] + a * Ytp[i][j]) / (λ1 * λ1) + Xta[n_1];Yt[i][j] = (a * Xtp[i][j] - b * Ytp[i][j]) / (λ1 * λ1) + Yta[n_1];Zt[i][j] = Ztp[i][j] / λ1 + Zta[n_1];}ListViewItem g;for (int i = 0; i < 3; i++)for (int j = 0; j < C[i]; j++){g = lst绝对定向.Items.Add((LDot[i][j]).ToString());g.SubItems.Add(Xt[i][j].ToString("0.000000"));g.SubItems.Add(Yt[i][j].ToString("0.000000"));g.SubItems.Add(Zt[i][j].ToString("0.000000"));}tab处理.SelectedTab = tab绝对定向;}private void 结果检查ToolStripMenuItem_Click(object sender, EventArgs e){//////////////////////////////////////////////////////////////////////////计算检查点与与之对应像点解求的大地坐标之间的差值for (int l = 0; l < 5; l++)for (int i = 0; i < 3; i++)for (int j = 0; j < C[i]; j++){if (CheckPoint[l] == LDot[i][j]){oX[l] = Xt[i][j] - oXt[l];oY[l] = Yt[i][j] - oYt[l];oZ[l] = Zt[i][j] - oZt[l];}}//////////////////////////////////////////////////////////////////////////在窗口中显示检查结果ListViewItem g;for (int i = 0; i < 5; i++){g = lst检查结果.Items.Add((CheckPoint[i]).ToString());g.SubItems.Add(oX[i].ToString("0.000000"));g.SubItems.Add(oY[i].ToString("0.000000"));g.SubItems.Add(oZ[i].ToString("0.000000"));}tab处理.SelectedTab = tab结果检查;}#endregion#region/////////////////////////////////////////////////////////////退出///////////////////////////////////////////////////////////////////////private void 退出ToolStripMenuItem_Click(object sender, EventArgs e){SaveFileDialog FILE = new SaveFileDialog();FILE.Filter = "文本文件(*.txt)|*.txt| 所有文件(*.*)|*.*";FILE.FilterIndex = 1;if (FILE.ShowDialog() == DialogResult.OK){StreamWriter MSW = new StreamWriter(FILE.FileName);MSW.WriteLine("########################################1.相对定向元素####################################");for (int i = 0; i < 3; i++){MSW.WriteLine("像对" + Convert.ToString(i + 1));MSW.WriteLine("u=" + u[i].ToString("0.000000"));MSW.WriteLine("v=" + v[i].ToString("0.000000"));MSW.WriteLine("φ=" + φ2[i].ToString("0.000000"));MSW.WriteLine("ω=" + ω2[i].ToString("0.000000"));MSW.WriteLine("κ=" + κ2[i].ToString("0.000000"));MSW.WriteLine(" ");}for (int i = 0; i < 3; i++){MSW.WriteLine("第" + (i + 1) + "个模型点的像空间辅助坐标:");MSW.WriteLine(" ");MSW.WriteLine("点号" + "\t\t" + "Xm" + "\t\t" + " Ym" + "\t\t" + " Zm");for (int j = 0; j < C[i]; j++){MSW.WriteLine(LDot[i][j] + " " + Xm[i][j].ToString("0.0000000") + " " + Ym[i][j].ToString("0.0000000") + " " + Zm[i][j].ToString("0.0000000"));}MSW.WriteLine(" ");}MSW.WriteLine("########################################2.模型连接########################################");for (int i = 0; i < 3; i++){MSW.WriteLine("第" + (i + 1) + "个模型点的摄影测量坐标:");MSW.WriteLine(" ");MSW.WriteLine("点号" + "\t\t" + "Xp" + "\t\t" + " Yp" + "\t\t" + " Zp");for (int j = 0; j < C[i]; j++){MSW.WriteLine(LDot[i][j] + " " + Xp[i][j].ToString("0.0000000") + " " + Yp[i][j].ToString("0.0000000") + " " + Zp[i][j].ToString("0.0000000"));}MSW.WriteLine(" ");}MSW.WriteLine(" ");MSW.WriteLine("########################################3.绝对定向########################################");MSW.WriteLine(" ");MSW.WriteLine("绝对定向元素:");MSW.WriteLine("ΔX=" + ΔX.ToString("0.000000"));MSW.WriteLine("ΔY=" + ΔY.ToString("0.000000"));MSW.WriteLine("ΔZ=" + ΔZ.ToString("0.000000"));MSW.WriteLine("λ=" + λ.ToString("0.000000"));MSW.WriteLine("Φ=" + Φ.ToString("0.000000"));MSW.WriteLine("Ω=" + Ω.ToString("0.000000"));MSW.WriteLine("Κ=" + Κ.ToString("0.000000"));MSW.WriteLine(" ");for (int i = 0; i < 3; i++){MSW.WriteLine("第" + (i + 1) + "个模型点的地面摄影测量坐标为:");MSW.WriteLine(" ");MSW.WriteLine("点号" + "\t\t" + "Xtp" + "\t\t" + "Ytp" + "\t\t" + "Ztp");for (int j = 0; j < C[i]; j++){MSW.WriteLine(LDot[i][j] + "\t" + " " + Xtp[i][j].ToString("0.000000") + "\t" + " " + Ytp[i][j].ToString("0.000000") + "\t" + " " + Ztp[i][j].ToString("0.000000"));}MSW.WriteLine(" ");}for (int i = 0; i < 3; i++){MSW.WriteLine("第" + (i + 1) + "个像对的大地坐标为:");MSW.WriteLine(" ");MSW.WriteLine("点号" + "\t\t" + "Xt" + "\t\t" + "Yt" + "\t\t" + "Zt");for (int j = 0; j < C[i]; j++){MSW.WriteLine(LDot[i][j] + "\t" + " " + Xt[i][j].ToString("0.000000") + "\t" + " " + Yt[i][j].ToString("0.000000") + "\t" + " " + Zt[i][j].ToString("0.000000"));}MSW.WriteLine(" ");}MSW.WriteLine(" ");MSW.WriteLine("########################################4.结果检查########################################");MSW.WriteLine(" ");MSW.WriteLine("点号" + "\t\t" + "ΔXt" + "\t\t" + "ΔYt" + "\t\t" + "ΔZt");for (int i = 0; i < 5; i++){MSW.WriteLine(CheckPoint[i] + "\t\t" + oX[i].ToString("0.000000") + "\t\t" + oY[i].ToString("0.000000") + "\t\t" + oZ[i].ToString("0.000000"));}MSW.Close();MessageBox.Show("成功保存到" + FILE.FileName);}。
using System;using System.Collections.Generic;using ponentModel;using System.Data;using System.Drawing;using System.Text;using System.Windows.Forms;using System.IO;using System.Data.OleDb;namespace 解析空中三角测量{public partial class Form1 : Form{public Form1(){InitializeComponent();}#region/////////////////////////////////////////////////////////////定义静态变量///////////////////////////////////////////////////////////////const int N = 150;int[] C = new int[3] { 15, 8, 11 };//各像对像点个数int[][] LDot = new int[3][];//像点点号int[] Control_Points = new int[4];//控制点点号int[] CheckPoint = new int[5];//检查点点号. double f = 153.033 / 1000.0;//主距double m;//比例尺//像对像点坐标double[][] x1 = new double[3][];double[][] y1 = new double[3][];double[][] x2 = new double[3][];double[][] y2 = new double[3][];//像点的像空间辅助坐标double[][] X1 = new double[3][];double[][] Y1 = new double[3][];double[][] Z1 = new double[3][];double[][] X2 = new double[3][];double[][] Y2 = new double[3][];double[][] Z2 = new double[3][];//相对定向元素double[] φ1 = new do uble[3];double[] ω1 = new double[3];double[] κ1 = new double[3];double[] φ2 = new double[3];double[] ω2 = new double[3];double[] κ2 = new double[3];double[] u = new double[3];double[] v = new double[3];//摄影基线分量double[] bx = new double[3];double[] by = new double[3];double[] bz = new double[3];//左、右像片投影系数N1,N2double[][] N1 = new double[3][];double[][] N2 = new double[3][];//上下视差Qdouble[][] Q = new double[3][];//模型点像空间辅助坐标double[][] Xm = new double[3][];double[][] Ym = new double[3][];double[][] Zm = new double[3][];//三个直线元素double[] Xs = new double[4];double[] Ys = new double[4];double[] Zs = new double[4];//模型点摄影测量坐标double[][] Xp = new double[3][];double[][] Yp = new double[3][];double[][] Zp = new double[3][];//绝对定向元素double ΔX, ΔY, ΔZ, λ, Φ, Ω,Κ;//控制点大地坐标double[] Xta = new double[4];double[] Yta = new double[4];double[] Zta = new double[4];//控制点地面摄影测量坐标double[] Xtpa = new double[4];double[] Ytpa = new double[4];double[] Ztpa = new double[4];//控制点摄影测量坐标double[] Xpa = new double[4];double[] Ypa = new double[4];double[] Zpa = new double[4];//模型点地面摄影测量坐标double[][] Xtp = new double[3][];double[][] Ytp = new double[3][];double[][] Ztp = new double[3][];//模型点大地坐标double[][] Xt = new double[3][];double[][] Yt = new double[3][];double[][] Zt = new double[3][];//检查点大地坐标double[] oXt = new double[5];double[] oYt = new double[5];double[] oZt = new double[5];//检查点的误差double[] oX = new double[5];double[] oY = new double[5];double[] oZ = new double[5];#endregion#region/////////////////////////////////////////////////////////////导入数据///////////////////////////////////////////////////////////////////private void 导入像点坐标数据ToolStripMenuItem_Click(object sender, EventArgs e){OpenFileDialog FILE = new OpenFileDialog();FILE.Filter = "文本文件(*.txt)|*.txt| 所有文件(*.*)|*.*";FILE.FilterIndex = 1;if (FILE.ShowDialog() == DialogResult.OK){StreamReader MSR = new StreamReader(FILE.FileName);string Line;//读取每行信息放在该字符串中double[,] Temp = new double[34, 5];//每行信息存放在该二维数组中int temp = 0;//将*.txt文件信息读到Temp[,]二维数组中while ((Line = MSR.ReadLine()) != null){char[] tt = new char[] { '\r', '\n' };string[] split = Line.Split(tt); //字符串转换为字符串数组string[] numbers;//读取的每行信息记录在数组中for (int i = 0; i < split.Length; i++){numbers = split[i].Split(' ');for (int j = 0, k = 0; j < numbers.Length && numbers[j] != ""; j++) Temp[temp, k++] = double.Parse(numbers[j]);}temp++;}MSR.Close();//用Temp中的数据赋值,并将单位换成米,并实例化像点坐标for (int i = 0; i < 3; i++){LDot[i] = new int[C[i]];x1[i] = new double[C[i]];y1[i] = new double[C[i]];x2[i] = new double[C[i]];y2[i] = new double[C[i]];}//像对1的坐标for (int i = 0; i < 15; i++){LDot[0][i] = (int)Temp[i, 0];x1[0][i] = Temp[i, 1] / 1000000.0;y1[0][i] = Temp[i, 2] / 1000000.0;x2[0][i] = Temp[i, 3] / 1000000.0;y2[0][i] = Temp[i, 4] / 1000000.0;}//像对2的坐标for (int i = 0; i < 8; i++){LDot[1][i] = (int)Temp[i + 15, 0];x1[1][i] = Temp[i + 15, 1] / 1000000.0;y1[1][i] = Temp[i + 15, 2] / 1000000.0;x2[1][i] = Temp[i + 15, 3] / 1000000.0;y2[1][i] = Temp[i + 15, 4] / 1000000.0;}//像对3的坐标for (int i = 0; i < 11; i++){LDot[2][i] = (int)Temp[i + 23, 0];x1[2][i] = Temp[i + 23, 1] / 1000000.0;y1[2][i] = Temp[i + 23, 2] / 1000000.0;x2[2][i] = Temp[i + 23, 3] / 1000000.0;y2[2][i] = Temp[i + 23, 4] / 1000000.0;}//显示像对坐标数据for (int i = 0; i < 34; i++){ListViewItem a;a = lst像对坐标数据.Items.Add(Temp[i, 0].ToString());a.SubItems.Add(Temp[i, 1].ToString());a.SubItems.Add(Temp[i, 2].ToString());a.SubItems.Add(Temp[i, 3].ToString());a.SubItems.Add(Temp[i, 4].ToString());}}}private void 导入控制点坐标数据ToolStripMenuItem_Click_1(object sender, EventArgs e){OpenFileDialog FILE = new OpenFileDialog();FILE.Filter = "文本文件(*.txt)|*.txt| 所有文件(*.*)|*.*";FILE.FilterIndex = 1;if (FILE.ShowDialog() == DialogResult.OK){StreamReader MSR = new StreamReader(FILE.FileName);string Line;//读取每行信息放在该字符串中double[,] Temp = new double[34, 5];//每行信息存放在该二维数组中int temp = 0;//将*.txt文件信息读到Temp[,]二维数组中while ((Line = MSR.ReadLine()) != null){char[] tt = new char[] { '\r', '\n' };string[] split = Line.Split(tt); //字符串转换为字符串数组string[] numbers;//读取的每行信息记录在数组中for (int i = 0; i < split.Length; i++){numbers = split[i].Split(' ');for (int j = 0, k = 0; j < numbers.Length && numbers[j] != ""; j++)Temp[temp, k++] = double.Parse(numbers[j]);}temp++;}MSR.Close();//用Temp中的数据赋值for (int i = 0; i < 4; i++){Control_Points[i] = (int)Temp[i, 0];Xta[i] = Temp[i, 1];Yta[i] = Temp[i, 2];Zta[i] = Temp[i, 3];}//显示控制点坐标数据for (int i = 0; i < 4; i++){ListViewItem a;a = lst控制点数据.Items.Add(Temp[i, 0].ToString());a.SubItems.Add(Temp[i, 1].ToString());a.SubItems.Add(Temp[i, 2].ToString());a.SubItems.Add(Temp[i, 3].ToString());}tab数据.SelectedTab = tab控制点数据;}}private void 导入检查点坐标数据ToolStripMenuItem_Click(object sender, EventArgs e){OpenFileDialog FILE = new OpenFileDialog();FILE.Filter = "文本文件(*.txt)|*.txt| 所有文件(*.*)|*.*";FILE.FilterIndex = 1;if (FILE.ShowDialog() == DialogResult.OK){StreamReader MSR = new StreamReader(FILE.FileName);string Line;//读取每行信息放在该字符串中double[,] Temp = new double[34, 5];//每行信息存放在该二维数组中int temp = 0;//将*.txt文件信息读到Temp[,]二维数组中while ((Line = MSR.ReadLine()) != null){char[] tt = new char[] { '\r', '\n' };string[] split = Line.Split(tt); //字符串转换为字符串数组string[] numbers;//读取的每行信息记录在数组中for (int i = 0; i < split.Length; i++){numbers = split[i].Split(' ');for (int j = 0, k = 0; j < numbers.Length && numbers[j] != ""; j++)Temp[temp, k++] = double.Parse(numbers[j]);}temp++;}MSR.Close();//用Temp中的数据赋值for (int i = 0; i < 5; i++){CheckPoint[i] = (int)Temp[i, 0];oXt[i] = Temp[i, 1];oYt[i] = Temp[i, 2];oZt[i] = Temp[i, 3];}//显示控制点坐标数据for (int i = 0; i < 5; i++){ListViewItem a;a = lst检查点数据.Items.Add(Temp[i, 0].ToString());a.SubItems.Add(Temp[i, 1].ToString());a.SubItems.Add(Temp[i, 2].ToString());a.SubItems.Add(Temp[i, 3].ToString());}}tab数据.SelectedTab = tab检查点坐标数据;}#endregion#region/////////////////////////////////////////////////////////////矩阵运算/////////////////////////////////////////////////////////////////////矩阵的转置运算private void Transpose(double[,] A, double[,] A T){int i, j;for (i = 0; i < A.GetLength(1); i++){for (j = 0; j < A.GetLength(0); j++){A T[i, j] = A[j, i];}}}//矩阵的乘法运算private void Matrix(double[,] AT, double[,] A, double[,] ATA){int i, j, k;for (i = 0; i < ATA.GetLength(0); i++){for (j = 0; j < ATA.GetLength(1); j++){A TA[i, j] = 0;for (k = 0; k < A T.GetLength(1); k++)ATA[i, j] += AT[i, k] * A[k, j];}}}// 矩阵求逆private void Inverse(double[,] A,double[,] AR){int i,j,h,k;int n = A.GetLength(0);double P;double[,] Q=new double[A.GetLength(0),2*A.GetLength(1)];for(i=0;i<n;i++) //1 2 3 //构造高斯矩阵for(j=0;j<n;j++) //2 3 4Q[i,j]=A[i,j]; //5 3 2for(i=0;i<n;i++)for(j=n;j<2*n;j++){ //1 2 3 1 0 0if(i+n==j) //2 3 4 0 1 0Q[i,j]=1; //5 3 2 0 0 1elseQ[i,j]=0;}for(h=k=0;k<n-1;k++,h++)//消去对角线以下的数据for(i=k+1;i<n;i++){if(Q[k,h]==0) // 0 X X 1 0 0for(int g=0;g<n;g++) // X X X 0 1 0if(Q[g,h]!=0) // X X x 0 0 1{ // 这种特殊情况的判断以及处理方式for(j=0;j<2*n;j++)Q[k,j]-=Q[g,j];break;}if(Q[i,h]==0) //将矩阵化为X X X X X Xcontinue; // 0 X X X X XP=Q[k,h]/Q[i,h]; // 0 0 X X X Xfor(j=0;j<2*n;j++) // 的形式{Q[i,j]*=P;Q[i,j]-=Q[k,j];}}for(h=k=n-1;k>0;k--,h--) // 消去对角线以上的数据for(i=k-1;i>=0;i--) // 此时无需考虑{if(Q[i,h]==0) // X X X X X Xcontinue; // 0 X X X X XP=Q[k,h]/Q[i,h]; // 0 0 0 X X Xfor(j=0;j<2*n;j++) //这种情况,因为此时矩阵对应的行列式值为0,即该矩阵不存在逆矩阵{Q[i,j]*=P;Q[i,j]-=Q[k,j];}}for(i=0;i<n;i++)//将对角线上数据化为1{P=1.0/Q[i,i];for(j=0;j<2*n;j++)Q[i,j]*=P;}for(i=0;i<n;i++) //提取逆矩阵for(j=0;j<n;j++)AR[i,j]=Q[i,j+n];}#endregion#region/////////////////////////////////////////////////////////////相对定向/////////////////////////////////////////////////////////////////// //初始化private void Initial(int i){//初始值if (i == 0){φ1[0] = 0;ω1[0] = 0;κ1[0] = 0;φ2[0] = 0;ω2[0] = 0;κ2[0] = 0;}else{φ1[i] = φ2[i - 1];ω1[i] = ω2[i - 1];κ1[i] = κ2[i - 1];φ2[i] = 0;ω2[i] = 0;κ2[i] = 0;}u[i] = 0;v[i] = 0;bx[i] = 200.0 / 1000.0;//像点像空间辅助坐标X1[i] = new double[C[i]];Y1[i] = new double[C[i]];Z1[i] = new double[C[i]];X2[i] = new double[C[i]];Y2[i] = new double[C[i]];Z2[i] = new double[C[i]];//投影系数和上下视差N1[i] = new double[C[i]];N2[i] = new double[C[i]];Q[i] = new double[C[i]];//模型点像空间辅助坐标Xm[i] = new double[C[i]];Ym[i] = new double[C[i]];Zm[i] = new double[C[i]];}//相对定向private void Directional(int i){//定义变量int n = 0;//统计迭代次数double d = 0.00000001;//精度double[,] R1 = new double[3, 3];//旋转矩阵R1double[,] R2 = new double[3, 3];//旋转矩阵R2double[,] A = new double[C[i], 5];//系数阵Adouble[,] AT = new double[5, C[i]];//A的转置ATdouble[,] ATA = new double[5, 5];//AT与A的乘积A TAdouble[,] ATAR = new double[5, 5];///ATA的逆阵ATARdouble[,] ATART = new double[5, C[i]];//ATAR的转置A TARTdouble[,] L = new double[C[i], 1];//误差方程中的常数项double[,] dx = new double[5, 1];//相对定向元素改正数Initial(i);//左片旋转矩阵R1,书79页R1[0, 0] = Math.Cos(φ1[i]) * Math.Cos(κ1[i]) - Math.Sin(φ1[i]) * Math.Sin(ω1[i]) * Math.Sin(κ1[i]);R1[0, 1] = -Math.Cos(φ1[i]) * Math.Sin(κ1[i]) - Math.Sin(φ1[i]) * Math.Sin(ω1[i]) * Math.Cos(κ1[i]);R1[0, 2] = -Math.Sin(φ1[i]) * Math.Cos(ω1[i]);R1[1, 0] = Math.Cos(ω1[i]) * Math.Sin(κ1[i]);R1[1, 1] = Math.Cos(ω1[i]) * Math.Cos(κ1[i]);R1[1, 2] = -Math.Sin(ω1[i]);R1[2, 0] = Math.Sin(φ1[i]) * Math.Cos(κ1[i]) + Math.Cos(φ1[i]) * Math.Sin(ω1[i]) * Math.Sin(κ1[i]);R1[2, 1] = -Math.Sin(φ1[i]) * Math.Sin(κ1[i]) + Math.Cos(φ1[i]) * Math.Sin(ω1[i]) * Math.Cos(κ1[i]);R1[2, 2] = Math.Cos(φ1[i]) * Math.Cos(ω1[i]);//左片像点像空辅坐标for (int j = 0; j < C[i]; j++){X1[i][j] = R1[0, 0] * x1[i][j] + R1[0, 1] * y1[i][j] - R1[0, 2] * f;Y1[i][j] = R1[1, 0] * x1[i][j] + R1[1, 1] * y1[i][j] - R1[1, 2] * f;Z1[i][j] = R1[2, 0] * x1[i][j] + R1[2, 1] * y1[i][j] - R1[2, 2] * f;}do{//by,bzby[i] = bx[i] * u[i];bz[i] = bx[i] * v[i];//右片旋转矩阵R2,书79页R2[0, 0] = Math.Cos(φ2[i]) * Math.Cos(κ2[i]) - Math.Sin(φ2[i]) * Math.Si n(ω2[i]) * Math.Sin(κ2[i]);R2[0, 1] = -Math.Cos(φ2[i]) * Math.Sin(κ2[i]) - Math.Sin(φ2[i]) * Math.Sin(ω2[i]) * Math.Cos(κ2[i]);R2[0, 2] = -Math.Sin(φ2[i]) * Math.Cos(ω2[i]);R2[1, 0] = Math.Cos(ω2[i]) * Math.Sin(κ2[i]);R2[1, 1] = Math.Cos(ω2[i]) * Math.Cos(κ2[i]);R2[1, 2] = -Math.Sin(ω2[i]);R2[2, 0] = Math.Sin(φ2[i]) * Math.Cos(κ2[i]) + Math.Cos(φ2[i]) * Math.Sin(ω2[i]) * Math.Sin(κ2[i]);R2[2, 1] = -Math.Sin(φ2[i]) * Math.Sin(κ2[i]) + Math.Cos(φ2[i]) * Math.Sin(ω2[i]) * Math.Cos(κ2[i]);R2[2, 2] = Math.Cos(φ2[i]) * Math.Cos(ω2[i]);for (int j = 0; j < C[i]; j++){//右片像点像空辅坐标X2[i][j] = R2[0, 0] * x2[i][j] + R2[0, 1] * y2[i][j] - R2[0, 2] * f;Y2[i][j] = R2[1, 0] * x2[i][j] + R2[1, 1] * y2[i][j] - R2[1, 2] * f;Z2[i][j] = R2[2, 0] * x2[i][j] + R2[2, 1] * y2[i][j] - R2[2, 2] * f;//N1,N2,QN1[i][j] = (bx[i] * Z2[i][j] - bz[i] * X2[i][j]) / (X1[i][j] * Z2[i][j] - X2[i][j] * Z1[i][j]);N2[i][j] = (bx[i] * Z1[i][j] - bz[i] * X1[i][j]) / (X1[i][j] * Z2[i][j] - X2[i][j] * Z1[i][j]);Q[i][j] = N1[i][j] * Y1[i][j] - N2[i][j] * Y2[i][j] - by[i];//误差方程系数矩阵A,书83页A[j, 0] = bx[i];A[j, 1] = -(Y2[i][j] / Z2[i][j]) * bx[i];A[j, 2] = -((X2[i][j] * Y2[i][j]) / Z2[i][j]) * N2[i][j];A[j, 3] = -(Z2[i][j] + Y2[i][j] * Y2[i][j] / Z2[i][j]) * N2[i][j];A[j, 4] = X2[i][j] * N2[i][j];//常数项LL[j, 0] = Q[i][j];}//A的转置ATTranspose(A, A T);//AT与A的乘积A TAMatrix(A T, A, ATA);//ATA的逆阵ATARInverse(ATA, A TAR);//ATAR与AT的乘积ATARTMatrix(A TAR, A T, ATART);//ATART *与L的乘积dxMatrix(A TART, L, dx);n++;if (n > N){MessageBox.Show("计算" + (n - 1)+"次后计算失败!", "请检查迭代次数和限差!", MessageBoxButtons.OK, MessageBoxIcon.Warning);break;}//相对定向元素新值u[i] += dx[0, 0];v[i] += dx[1, 0];φ2[i] += dx[2, 0];ω2[i] += dx[3, 0];κ2[i] += dx[4, 0];} while (Math.Abs(dx[0, 0]) >= d || Math.Abs(dx[1, 0]) >= d || Math.Abs(dx[2, 0]) >= d || Math.Abs(dx[3, 0]) >= d || Math.Abs(dx[4, 0]) >= d);//显示相对定向元素ListViewItem a;a = lst相对定向元素.Items.Add((i + 1).ToString());a.SubItems.Add(u[i].ToString("0.000000"));a.SubItems.Add(v[i].ToString("0.000000"));a.SubItems.Add(φ2[i].ToString("0.000000"));a.SubItems.Add(ω2[i].ToString("0.000000"));a.SubItems.Add(κ2[i].ToString("0.000000"));//模型点的像空间辅助坐标for (int j = 0; j < C[i]; j++){Xm[i][j] = N1[i][j] * X1[i][j];Ym[i][j] = (N1[i][j] * Y1[i][j] + N2[i][j] * Y2[i][j] + by[i]) * 0.5;Zm[i][j] = N1[i][j] * Z1[i][j];}tab处理.SelectedTab = tab相对定向;}private void 相对定向ToolStripMenuItem_Click(object sender, EventArgs e){//相对定向3次for (int i = 0; i < 3; i++)Directional(i);}#endregion#region/////////////////////////////////////////////////////////////模型连接,绝对定向,结果检查/////////////////////////////////////////////////private void 模型连接ToolStripMenuItem_Click_1(object sender, EventArgs e){//摄站的摄影测量坐标double[] Xps = new double[4];double[] Yps = new double[4];double[] Zps = new double[4];//归化系数double[] k = new double[3];double[] kk = new double[2];//比例尺归化系数for (int i = 0; i < 2; i++){int num = 0;for (int l = 0; l < C[i]; l++){for (int j = 0; j < C[i + 1]; j++){if (LDot[i][l] == LDot[i + 1][j]){if (i == 0)kk[i] += (Zm[i][l] - bz[i]) / Zm[i + 1][j];elsekk[i] += (Zm[i][l] - bz[i]) * kk[i - 1] / Zm[i + 1][j];num++;}}}kk[i] = kk[i] / num;//平均数}k[0] = 1;k[1] = kk[0];k[2] = kk[1];lblK1.Text = "k1=" + k[1].ToString("0.000000");lblK2.Text = "k2=" + k[2].ToString("0.000000");//比例尺m(1201,1205,1206)double[] MID = new double[3];/////////////////////////////////////////////每段长度比MID[0] = (Math.Sqrt((Xta[0] - Xta[1]) * (Xta[0] - Xta[1]) + (Yta[0] - Yta[1]) * (Yta[0] - Yta[1]))) /(Math.Sqrt((x1[0][0] - x1[0][5]) * (x1[0][0] - x1[0][5]) + (y1[0][0] - y1[0][5]) * (y1[0][0] - y1[0][5])));MID[1] = (Math.Sqrt((Xta[0] - Xta[2]) * (Xta[0] - Xta[2]) + (Yta[0] - Yta[2]) * (Yta[0] - Yta[2]))) /(Math.Sqrt((x1[0][0] - x1[0][6]) * (x1[0][0] - x1[0][6]) + (y1[0][0] - y1[0][6]) * (y1[0][0] - y1[0][6])));MID[2] = (Math.Sqrt((Xta[2] - Xta[1]) * (Xta[2] - Xta[1]) + (Yta[2] - Yta[1]) * (Yta[2] - Yta[1]))) /(Math.Sqrt((x1[0][6] - x1[0][5]) * (x1[0][6] - x1[0][5]) + (y1[0][6] - y1[0][5]) * (y1[0][6] - y1[0][5])));m = (MID[0] + MID[1] +MID[2]) / 3;lblm.Text = "m=" + m.ToString("0.000000");//模型摄站S的摄影测量坐标for (int i = 0; i < 4; i++){if (i == 0){Xps[0] = 0.0;Yps[0] = 0.0;Zps[0] = m * f;}else{Xps[i] = Xps[i - 1] + m * k[i - 1] * bx[i - 1];Yps[i] = Yps[i - 1] + m * k[i - 1] * by[i - 1];Zps[i] = Zps[i - 1] + m * k[i - 1] * bz[i - 1];}}//实例化模型点的摄影测量坐标for (int i = 0; i < 3; i++){Xp[i] = new double[C[i]];Yp[i] = new double[C[i]];Zp[i] = new double[C[i]];}//各模型点的摄影测量坐标for (int i = 0; i < 3; i++)for (int j = 0; j < C[i]; j++){Xp[i][j] = Xps[i] + k[i] * m * N1[i][j] * X1[i][j];Yp[i][j] = 0.5 * (Yps[i] + k[i] * m * N1[i][j] * Y1[i][j] + Yps[i + 1] + k[i] * m * N2[i][j] * Y2[i][j]);Zp[i][j] = Zps[i] + k[i] * m * N1[i][j] * Z1[i][j];}ListViewItem a;for (int i = 0; i < 3; i++)for (int j = 0; j < C[i]; j++){a = lst模型连接.Items.Add((LDot[i][j]).ToString());a.SubItems.Add(Xp[i][j].ToString("0.0000000"));a.SubItems.Add(Yp[i][j].ToString("0.0000000"));a.SubItems.Add(Zp[i][j].ToString("0.0000000"));}tab处理.SelectedTab = tab模型连接;}private void 绝对定向ToolStripMenuItem_Click(object sender, EventArgs e) {double ΔXt = 0, ΔYt = 0;//大地坐标差double ΔXp = 0, ΔYp = 0;//摄影测量坐标差double a, b, λ1;int n_1 = 0;//标记控制点1bool flag;//选定1和2两个控制点//从第一个模型里找到1点flag = false;for (int i = 0; i < 4; i++){for (int j = 0; j < C[0]; j++){if (LDot[0][j] == Control_Points[i]){ΔXt = Xta[i];ΔYt = Yta[i];ΔXp = Xp[0][j];ΔYp = Yp[0][j];n_1 = i;flag = true;}if (flag)break;}if (flag)break;}//从第三个模型里找到2点flag = false;for (int i = 0; i < 4; i++){for (int j = 0; j < C[2]; j++){if (LDot[2][j] == Control_Points[i]){ΔXt = Xta[i] - ΔXt;ΔYt = Yt a[i] - ΔYt;ΔXp = Xp[2][j] - ΔXp;ΔYp = Yp[2][j] - ΔYp;flag = true;}if (flag)break;}if (flag)break;}//a,b,λ1,书100页a = (ΔXp * ΔYt + ΔYp * ΔXt) / (ΔXt * ΔXt + ΔYt * ΔYt);b = (ΔXp * ΔXt - ΔYp * ΔYt) / (ΔXt * ΔXt + ΔYt * ΔYt);λ1 = Math.Sqrt(a * a + b * b);//控制点大地坐标转换为地面摄影测量坐标,书100页,6-2-11 for (int i = 0; i < 4; i++){Xtpa[i] = b * (Xta[i] - Xta[n_1]) + a * (Yta[i] - Yta[n_1]);Ytpa[i] = a * (Xta[i] - Xta[n_1]) - b * (Yta[i] - Yta[n_1]);Ztpa[i] = λ1 * (Zta[i] - Zta[n_1]);}//相同点号的控制点与对应的模型点for (int l = 0; l < 4; l++)for (int i = 0; i < 3; i++)for (int j = 0; j < C[i]; j++){if (LDot[i][j] == Control_Points[l]){Xpa[l] = Xp[i][j];Ypa[l] = Yp[i][j];Zpa[l] = Zp[i][j];}}int n = 0;double d = 0.0000001;double[,] R = new double[3, 3];//旋转矩阵Rdouble[,] A = new double[12, 7];//系数阵Adouble[,] AT = new double[7, 12];//A的转置ATdouble[,] A TA = new double[7, 7];//AT与A的乘积A TA double[,] ATAR = new double[7, 7];//ATA的逆阵ATAR double[,] ATART = new double[7, 12];//ATAR的转置ATARTdouble[,] L = new double[12, 1];//常数项double[,] dx = new double[7, 1];//改正数dxΔX = 0; ΔY = 0; ΔZ = 0; λ = 1; Φ = 0; Ω = 0; Κ = 0; //绝对定向元素的初始值for (int i = 0; i < 4; i++)//系数矩阵A{A[3 * i, 0] = 1;A[3 * i, 1] = 0;A[3 * i, 2] = 0;A[3 * i, 3] = Xpa[i];A[3 * i, 4] = -Zpa[i];A[3 * i, 5] = 0;A[3 * i, 6] = -Ypa[i];A[3 * i + 1, 0] = 0;A[3 * i + 1, 1] = 1;A[3 * i + 1, 2] = 0;A[3 * i + 1, 3] = Ypa[i];A[3 * i + 1, 4] = 0;A[3 * i + 1, 5] = -Zpa[i];A[3 * i + 1, 6] = Xpa[i];A[3 * i + 2, 0] = 0;A[3 * i + 2, 1] = 0;A[3 * i + 2, 2] = 1;A[3 * i + 2, 3] = Zpa[i];A[3 * i + 2, 4] = Xpa[i];A[3 * i + 2, 5] = Ypa[i];A[3 * i + 2, 6] = 0;}do{//计算旋转矩阵R,书79页R[0, 0] = Math.Cos(Φ) * Math.Cos(Κ) - Math.Sin(Φ) * Math.Sin(Ω) * Math.Sin(Κ);R[0, 1] = -Math.Cos(Φ) * Math.Sin(Κ) - Math.Sin(Φ) * Math.Sin(Ω) * Math.Cos(Κ);R[0, 2] = -Math.Sin(Φ) * Math.Cos(Ω);R[1, 0] = Math.Cos(Ω) * Math.Sin(Κ);R[1, 1] = Math.Cos(Ω) * Math.Cos(Κ);R[1, 2] = -Math.Sin(Ω);R[2, 0] = Math.Sin(Φ) * Math.Cos(Κ) + Math.Cos(Φ) * Math.Sin(Ω) * Math.Sin(Κ);R[2, 1] = -Math.Sin(Φ) * Math.Sin(Κ) + Math.Cos(Φ) * Math.Sin(Ω) * Math.Cos(Κ);R[2, 2] = Math.Cos(Φ) * Math.Cos(Ω);//c3//常数项Lfor (int i = 0; i < 4; i++){L[3 * i, 0] = Xtpa[i] - λ * (Xpa[i] - Κ * Ypa[i] - Φ * Zpa[i]) - ΔX;L[3 * i + 1, 0] = Ytpa[i] - λ * (Κ * Xpa[i] + Ypa[i] - Ω * Zpa[i]) - ΔY;L[3 * i + 2, 0] = Ztpa[i] - λ * (Φ * Xpa[i] + Ω * Ypa[i] + Zpa[i]) - ΔZ;}//A的转置ATTranspose(A, A T);//AT与A的乘积A TAMatrix(A T, A, ATA);//ATA的逆矩阵A TARInverse(ATA,A TAR);//ATAR与AT的乘积ATARTMatrix(A TAR, A T, ATART);//ATART与L的乘积dxMatrix(A TART, L, dx);n++;if (n > N){MessageBox.Show("计算" + (n - 1) + "次后计算失败!", "请检查迭代次数和限差!", MessageBoxButtons.OK, MessageBoxIcon.Warning);break;}//绝对定向元素新值ΔX += dx[0, 0];ΔY += dx[1, 0];ΔZ += dx[2, 0];λ += dx[3, 0];Φ += dx[4, 0];Ω += dx[5, 0];Κ += dx[6, 0];} while (Math.Abs(dx[0, 0]) >= d || Math.Abs(dx[1, 0]) >= d || Math.Abs(dx[2, 0]) >= d || Math.Abs(dx[3, 0]) >= d|| Math.Abs(dx[4, 0]) >= d || Math.Abs(dx[5, 0]) >= d || Math.Abs(dx[6, 0]) >= d);lblΔX.Text = "ΔX=" + ΔX.ToString("0.000000");lblΔY.Text = "ΔY=" + ΔY.ToString("0.000000");lblΔZ.Text = "ΔZ=" + ΔZ.ToString("0.000000");lblλ.Text = "λ=" + λ.ToString("0.000000");lblΦ.Text = "Φ=" + Φ.ToString("0.000000");lblΩ.Text = "Ω=" + Ω.ToString("0.000000");lblΚ.Text = "Κ=" + Κ.ToString("0.000000");//加密点的大地坐标//实例化模型点地面摄影测量坐标和大地坐标for (int i = 0; i < 3; i++){Xtp[i] = new double[C[i]];Ytp[i] = new double[C[i]];Ztp[i] = new double[C[i]];Xt[i] = new double[C[i]];Yt[i] = new double[C[i]];Zt[i] = new double[C[i]];}//模型点地面摄影测量坐标for (int i = 0; i < 3; i++)for (int j = 0; j < C[i]; j++){Xtp[i][j] = λ * (Xp[i][j] - Κ * Yp[i][j] - Φ * Zp[i][j]) + ΔX;Ytp[i][j] = λ * (Κ * Xp[i][j] + Yp[i][j] - Ω * Zp[i][j]) + ΔY;Ztp[i][j] = λ * (Φ * Xp[i][j] + Ω * Yp[i][j] + Zp[i][j]) + ΔZ;}//地面摄影测量坐标转换为大地坐标for (int i = 0; i < 3; i++)for (int j = 0; j < C[i]; j++){Xt[i][j] = (b * Xtp[i][j] + a * Ytp[i][j]) / (λ1 * λ1) + Xta[n_1];Yt[i][j] = (a * Xtp[i][j] - b * Ytp[i][j]) / (λ1 * λ1) + Yta[n_1];Zt[i][j] = Ztp[i][j] / λ1 + Zta[n_1];}ListViewItem g;for (int i = 0; i < 3; i++)for (int j = 0; j < C[i]; j++){g = lst绝对定向.Items.Add((LDot[i][j]).ToString());g.SubItems.Add(Xt[i][j].ToString("0.000000"));g.SubItems.Add(Yt[i][j].ToString("0.000000"));g.SubItems.Add(Zt[i][j].ToString("0.000000"));}tab处理.SelectedTab = tab绝对定向;}private void 结果检查ToolStripMenuItem_Click(object sender, EventArgs e){//////////////////////////////////////////////////////////////////////////计算检查点与与之对应像点解求的大地坐标之间的差值for (int l = 0; l < 5; l++)for (int i = 0; i < 3; i++)for (int j = 0; j < C[i]; j++){if (CheckPoint[l] == LDot[i][j]){oX[l] = Xt[i][j] - oXt[l];oY[l] = Yt[i][j] - oYt[l];oZ[l] = Zt[i][j] - oZt[l];}}//////////////////////////////////////////////////////////////////////////在窗口中显示检查结果ListViewItem g;for (int i = 0; i < 5; i++){g = lst检查结果.Items.Add((CheckPoint[i]).ToString());g.SubItems.Add(oX[i].ToString("0.000000"));g.SubItems.Add(oY[i].ToString("0.000000"));g.SubItems.Add(oZ[i].ToString("0.000000"));}tab处理.SelectedTab = tab结果检查;}#endregion#region/////////////////////////////////////////////////////////////退出///////////////////////////////////////////////////////////////////////private void 退出ToolStripMenuItem_Click(object sender, EventArgs e){SaveFileDialog FILE = new SaveFileDialog();FILE.Filter = "文本文件(*.txt)|*.txt| 所有文件(*.*)|*.*";FILE.FilterIndex = 1;if (FILE.ShowDialog() == DialogResult.OK){StreamWriter MSW = new StreamWriter(FILE.FileName);MSW.WriteLine("########################################1.相对定向元素####################################");for (int i = 0; i < 3; i++){MSW.WriteLine("像对" + Convert.ToString(i + 1));MSW.WriteLine("u=" + u[i].ToString("0.000000"));MSW.WriteLine("v=" + v[i].ToString("0.000000"));MSW.WriteLine("φ=" + φ2[i].ToString("0.000000"));MSW.WriteLine("ω=" + ω2[i].ToString("0.000000"));MSW.WriteLine("κ=" + κ2[i].ToString("0.000000"));MSW.WriteLine(" ");}for (int i = 0; i < 3; i++){MSW.WriteLine("第" + (i + 1) + "个模型点的像空间辅助坐标:");MSW.WriteLine(" ");MSW.WriteLine("点号" + "\t\t" + "Xm" + "\t\t" + " Ym" + "\t\t" + " Zm");for (int j = 0; j < C[i]; j++){MSW.WriteLine(LDot[i][j] + " " + Xm[i][j].ToString("0.0000000") + " " + Ym[i][j].ToString("0.0000000") + " " + Zm[i][j].ToString("0.0000000"));}MSW.WriteLine(" ");}MSW.WriteLine("########################################2.模型连接########################################");for (int i = 0; i < 3; i++){MSW.WriteLine("第" + (i + 1) + "个模型点的摄影测量坐标:");MSW.WriteLine(" ");MSW.WriteLine("点号" + "\t\t" + "Xp" + "\t\t" + " Yp" + "\t\t" + " Zp");for (int j = 0; j < C[i]; j++){MSW.WriteLine(LDot[i][j] + " " + Xp[i][j].ToString("0.0000000") + " " + Yp[i][j].ToString("0.0000000") + " " + Zp[i][j].ToString("0.0000000"));}MSW.WriteLine(" ");}MSW.WriteLine(" ");MSW.WriteLine("########################################3.绝对定向########################################");MSW.WriteLine(" ");MSW.WriteLine("绝对定向元素:");MSW.WriteLine("ΔX=" + ΔX.ToString("0.000000"));MSW.WriteLine("ΔY=" + ΔY.ToString("0.000000"));MSW.WriteLine("ΔZ=" + ΔZ.ToString("0.000000"));MSW.WriteLine("λ=" + λ.ToString("0.000000"));MSW.WriteLine("Φ=" + Φ.ToString("0.000000"));MSW.WriteLine("Ω=" + Ω.ToString("0.000000"));MSW.WriteLine("Κ=" + Κ.ToString("0.000000"));MSW.WriteLine(" ");for (int i = 0; i < 3; i++){MSW.WriteLine("第" + (i + 1) + "个模型点的地面摄影测量坐标为:");MSW.WriteLine(" ");MSW.WriteLine("点号" + "\t\t" + "Xtp" + "\t\t" + "Ytp" + "\t\t" + "Ztp");for (int j = 0; j < C[i]; j++){MSW.WriteLine(LDot[i][j] + "\t" + " " + Xtp[i][j].ToString("0.000000") + "\t" + " " + Ytp[i][j].ToString("0.000000") + "\t" + " " + Ztp[i][j].ToString("0.000000"));}MSW.WriteLine(" ");}for (int i = 0; i < 3; i++){MSW.WriteLine("第" + (i + 1) + "个像对的大地坐标为:");MSW.WriteLine(" ");MSW.WriteLine("点号" + "\t\t" + "Xt" + "\t\t" + "Yt" + "\t\t" + "Zt");for (int j = 0; j < C[i]; j++){MSW.WriteLine(LDot[i][j] + "\t" + " " + Xt[i][j].ToString("0.000000") + "\t" + " " + Yt[i][j].ToString("0.000000") + "\t" + " " + Zt[i][j].ToString("0.000000"));}MSW.WriteLine(" ");}MSW.WriteLine(" ");MSW.WriteLine("########################################4.结果检查########################################");MSW.WriteLine(" ");MSW.WriteLine("点号" + "\t\t" + "ΔXt" + "\t\t" + "ΔYt" + "\t\t" + "ΔZt");for (int i = 0; i < 5; i++){MSW.WriteLine(CheckPoint[i] + "\t\t" + oX[i].ToString("0.000000") + "\t\t" + oY[i].ToString("0.000000") + "\t\t" + oZ[i].ToString("0.000000"));}MSW.Close();MessageBox.Show("成功保存到" + FILE.FileName);}。