测绘程序实验报告
验 实验 1
Visual C++.Net 环境和程序设计初步
1.掌握 VC++.net 语言的基本语法; 2.理解顺序结构、选择结构和循环结构程序设计的特点及应用; 3.掌握对基于对话框的 MFC 应用程序设计方法; 4.掌握一些简单算法。
5.编写一个方位角计算程序。提示:先使用反正切函数计算,然后利用坐标增量 的符号来判断所在的象限。
:
设计思路:在按钮下面添加程序。X Y 同时大于 0 在第一象限,方位角等于 arctan(y/x);X>0,Y<0 在第二象限,方位角等于 arctan(y/x)+90;X<0,Y<0 在第三象限,方位角等于arctan(y/x)+180;X<0,Y>0 在第四象限,方位角等于 arctan(y/x)+270; 界面设计:
主要代码:// 0145110615 ymh 2.1Dlg.h : 头文件 protected:
HICON m_hIcon;
// 生成的消息映射函数
virtual BOOL OnInitDialog();
afx_msg void OnSysCommand(UINT nID, LPARAM lParam);
afx_msg void OnPaint();
afx_msg HCURSOR OnQueryDragIcon();
DECLARE_MESSAGE_MAP() public:
double x;
double y;
double Q;
afx_msg void OnBnClickedOk();
afx_msg void OnBnClickedCancel();
afx_msg void OnBnClickedButton1();
double A; }; // 0145110615 ymh 2.1Dlg.cpp : 实现文件 #include "stdafx.h" #include "0145110615 ymh 2.1.h" #include "0145110615 ymh 2.1Dlg.h" #include <math.h> #ifdef _DEBUG #define new DEBUG_NEW #endif void CMy0145110615ymh21Dlg::OnBnClickedOk()//计算 {
// TODO: 在此添加控件通知处理程序代码
UpdateData(TRUE);
if(x>0)
{if(y>0)
{Q=1;
A=atan(y/x);}//x大于y大于在第一象限
else{Q=4;
A=atan(y/x)+270;}//x大于y小于在第四象限
}
else if(y>0)
{Q=2;
A=atan(y/x)+90;}//x大于y小于在第二象限
else{Q=3;
A=atan(y/x)+180;}//x小于y小于在第三象限
UpdateData(FALSE);
//OnOK(); } void CMy0145110615ymh21Dlg::OnBnClickedCancel()//清除 { // TODO: 在此添加控件通知处理程序代码
UpdateData(true);
x=0;
y=0;
Q=0;
A=0;
UpdateData(false); } void CMy0145110615ymh21Dlg::OnBnClickedButton1()//退出 {
// TODO: 在此添加控件通知处理程序代码
OnCancel(); } 运行结果:
总 总
结
第一次做这个实验的时候真的觉得挺难得可是当我经过更难的实验的洗礼之后在返回来看它真是顿时亲切了许多,其实当时是对这个软件不了解简单的东西把它想得很复杂绕来绕去都不知道该怎么实现一些很简单的东西了。
实验 2.2 .设计同一参考椭球下的三维地心坐标(笛卡儿坐标系)与大地坐标系转换的程 序。
(提示:用 do„while 迭代,B、H 初始为 0 进行迭代,直到 H 的精度达到 0.00001 米)
注意:东经 0~180(Y>0),西经:0~-180(Y<0) 式中,B、L、H 为椭球面上的大地纬度、大地经度、大地高;X、Y、Z 为空间直 角坐标;N 为卯酉圈曲率半径,e 为椭球的偏心率,a 为椭球的长半径,b 为椭球 的短半径。
(WGS84 椭球参数:长半径 a=6378137m,扁率α=1/298.257223563)
设计思路:在按钮下面设置主程序,按照指导书给的思路编辑公式 界面设计:
主要代码:
// 0145110615 ymh 2.2Dlg.h : 头文件 protected:
HICON m_hIcon;
// 生成的消息映射函数
virtual BOOL OnInitDialog();
afx_msg void OnSysCommand(UINT nID, LPARAM lParam);
afx_msg void OnPaint();
afx_msg HCURSOR OnQueryDragIcon();
DECLARE_MESSAGE_MAP() public:
double B;
double L;
double H;
double X;
double Y;
double Z;
afx_msg void OnBnClickedOk(); }; // 0145110615 ymh 2.2Dlg.cpp : 实现文件 #include "stdafx.h" #include "0145110615 ymh 2.2.h" #include "0145110615 ymh 2.2Dlg.h" #include <math.h> #ifdef _DEBUG #define new DEBUG_NEW #endif void CMy0145110615ymh22Dlg::OnBnClickedOk()//大地坐标转换为空间直角坐标 {
// TODO: 在此添加控件通知处理程序代码
UpdateData(true);
double r=1/298.257223563;
double e=sqrt((2*r)-(r*r));
int a=6378137;
double W=sqrt(1-e*e*sin(B)*sin(B));
double N=a/W;
X=(N+H)*cos(B)*cos(L);
Y=(N+H)*cos(B)*cos(L);
Z=(N*(1-e*e)+H)*sin(B);UpdateData(false); //OnOK(); 运行结果:
。
实验 2.3 .编写一个后方交会计算程序。
3.1 基本原理及计算公式 若将 Pa、Pb、Pc 看成权,则 P 点的坐标即为三个已知点的加权平均值 3.2 计算程序设计步骤 (1)设计界面,用于输入 3
于输出待定点坐标的文本框(12 个)、静态标签框和 Button 按钮; (2)定义文本框控件变量(Value); (3)根据已知点计算三个内角 A、B、C; (4)计算 Tan( )、Tan(β)、Tan(γ)、Tan(A)、Tan(B)、Tan(C); (5)计算 Pa、Pb、Pc; (6)计算待定点坐标 Xp、Yp。
界面要求:
三个坐标输入框,两个角度输入框 一个坐标结果输出框 一个计算按钮,一个清除按钮,一个退出按钮。
2.由三角形三个边长求内角函数 计算公式:
设计思路:通过示例编辑框添加变量,在按钮下面添加程序。先将α、β、的度分秒之转换成度利用三角形内角和等于 180 算出γ并将γ转换成弧度。接着计算三角形的内角,判断 P 点是否在危险圆上若不在则计算 P 点坐标若在则弹出“该点在危险圆上”。
界面设计:
主要 代码:protected:
HICON m_hIcon;
// 生成的消息映射函数
virtual BOOL OnInitDialog();
afx_msg void OnSysCommand(UINT nID, LPARAM lParam);
afx_msg void OnPaint();
afx_msg HCURSOR OnQueryDragIcon();
DECLARE_MESSAGE_MAP() public:
afx_msg void OnEnChangeEdit5();
double XA;
double YA;
double XB;
double YB;
double XC;
double YC;
double alfa;
double bet;
double Xp;
double Yp;
afx_msg void OnBnClickedButton1();
afx_msg void OnBnClickedOk(); }; #include "stdafx.h" #include "dss2-3.h" #include "dss2-3Dlg.h" #include <math.h> const double PI=3.1415926535897932; #ifdef _DEBUG
#define new DEBUG_NEW #endif void Cdss23Dlg::OnBnClickedButton1() {
// TODO: 在此添加控件通知处理程序代码
UpdateData(TRUE);
double afAB,afAC,afBC,afBA,afCA,afCB,A,B,C,Pa,Pb,Pc;
int D1,M1,D2,M2;
double S1,S2,alfa1,bet1,gama1,alfa2,bet2,gama2;
//将alfa转换成度
D1=int(alfa);
M1=int((alfa-D1)*100);
S1=((alfa-D1)*100-M1)*100;
alfa1=D1+M1/60+S1/3600;
alfa2=alfa1*PI/180;
//将bet转换成度
D2=int(bet);
M2=int((bet-D2)*100);
S2=((bet-D2)*100-M2)*100;
bet1=D2+M2/60+S2/3600;
bet2=bet*PI/180;
//计算gama1的值
gama1=180-bet1-alfa1;
gama2=gama1*PI/180;//将gama1的值转换成弧度
//计算已知点的三个内角
afAB=atan((YB-YA)/(XB-XA));
afAC=atan((YC-YA)/(XC-XA));
afBA=atan((YA-YB)/(XA-XB));
afBC=atan((YC-YB)/(XC-XB));
afCA=atan((YA-YC)/(XA-XC));
afCB=atan((YB-YC)/(XB-XC));
A=afAB-afAC;
B=afBC-afBA;
C=afCA-afCB;
//判断点是否在危险圆上若不在则计算P点坐标
if(alfa+bet+C<170||alfa+bet+C>190)
{
Pa=(tan(alfa2)*tan(A))/(tan(alfa2)-tan(A));
Pb=(tan(bet2)*tan(B))/(tan(bet2)-tan(B));
Pc=(tan(gama2)*tan(C))/(tan(gama2)-tan(C));
Xp=(XA*Pa+XB*Pb+XC*Pc)/(Pa+Pb+Pc);
Yp=(YA*Pa+YB*Pb+YC*Pc)/(Pa+Pb+Pc);
}
else//若在则弹出“该点位于危险圆上”
MessageBox(_T("该点位于危险圆上"));
UpdateData(FALSE);
//OnCancel(); }
void Cdss23Dlg::OnBnClickedOk() {
// TODO: 在此添加控件通知处理程序代码
UpdateData(TRUE);
XA=0;
YA=0;
XB=0;
YB=0;
XC=0;
YC=0;
alfa=0;
bet=0;
Xp=0;
Yp=0;
UpdateData(FALSE);
//OnOK(); }; 运行结果:
总 总
结
本次实验刚开始还是遇到了很多问题的比如说根本不就不知道该如何用程序来实现后方交会这个过程,后来经过问同学、上网查资料等大概弄懂了实现步骤可是写完程序后我发现他根本计算不了点计算按按钮一点反应都没有。又开始找问题才发现是UpdateData(FALSE)和 UpdateData(TRUE)忘写了,还发现程序中没有进行度分秒到度的转换,就顺便把这个实现也加进去了。这个程序也就算完成了。
实验 三 数组、指针与函数
一、实验目的
掌握数组的定义、引用及应用方法。
掌握指针与动态数组。
掌握函数的定义、引用及应用方法。
二、实验内容 1.编写一个求任意多边形面积的程序。提示:通过界面输入数据,并把数据保存 在一个二维数组或一个一维的自定义结构体类型的数组中,然后再进行计算。要 求计算部分写成函数的形式,使计算程序与界面无关。
动态数组 创建动态数组
结构体的定义 多边形面积计算原理及算法 计算原理:
面积计算的算法:
提示:显示框用 Cedit 控件变量 对每个输入的坐标 用 CString str 临时变量 格式化,然后用 CEdit 的控件变量插入
设计思路:将实现写在按钮在下面。添加顶点下面实现创建动态数组,确认按钮实现返回数组大小值并将添加的数据显示到显示框中去,通过计算按钮实现多边形面积的计算,清除按钮实现清除输入的数据,退出按钮退出程序。
界面设计:
主要代码:// 实现 protected:
HICON m_hIcon;
// 生成的消息映射函数
virtual BOOL OnInitDialog();
afx_msg void OnSysCommand(UINT nID, LPARAM lParam);
afx_msg void OnPaint();
afx_msg HCURSOR OnQueryDragIcon();
DECLARE_MESSAGE_MAP() public:
double x;
double y;
double result;
CEdit edit;
afx_msg void OnBnClickedButton4();
afx_msg void OnBnClickedButton3();
afx_msg void OnBnClickedButton2();
afx_msg void OnBnClickedButton1();
afx_msg void OnBnClickedButton5();
int n;
double *px;
double *py;
CEdit m_strdis; };
#include "stdafx.h" #include "0145110615(3).h" #include "0145110615(3)Dlg.h"
#ifdef _DEBUG #define new DEBUG_NEW #endif
// 用于应用程序“关于”菜单项的CAboutDlg 对话框 double calarea(double x[],double y[],int n) {
double s=0;
int i;
for(i=0;i<n;i++)
{
s+=0.5*(x[i]+x[i+1])*(y[i+1]-y[i]);
}
return s; };
void CMy01451105173Dlg::OnBnClickedButton4() {
// TODO: 在此添加控件通知处理程序代码
UpdateData(TRUE);
result=calarea(px,py,n);
UpdateData(FALSE); }
void CMy01451105173Dlg::OnBnClickedButton3() {
// TODO: 在此添加控件通知处理程序代码 UpdateData(TRUE);
px=new double[n];
py=new double[n];
UpdateData(FALSE); }
void CMy01451105173Dlg::OnBnClickedButton2() {
// TODO: 在此添加控件通知处理程序代码 // TODO: 在此添加控件通知处理程序代码
UpdateData(TRUE);
delete[] px;
delete[] py;
px=NULL;
py=NULL;
n=0;
result=0;
m_strdis.SetWindowTextW(_T(""));
UpdateData(FALSE); }
int t=0; void CMy01451105173Dlg::OnBnClickedButton1() {
// TODO: 在此添加控件通知处理程序代码 UpdateData(TRUE);
CString str;
t+=1;
if(t>n)
{
MessageBox(_T("Warning!"));
};
str.Format(_T("No.%d % lf %lf \r\n"),t,x,y);
m_strdis.ReplaceSel(str);
px[t-1]=x;
py[t-1]=y;
UpdateData(FALSE); } void CMy01451105173Dlg::OnBnClickedButton5() {
// TODO: 在此添加控件通知处理程序代码
exit(0); } 运 行 结 果 :
总 总
结:这个实验相比前面几个实验感觉难了好多。首先是不知道怎么实现动态数组也不知道怎样将输入的内容显示到示例编辑框里。总之在眼前的都是一堆问题,但面临的问题总得解决所以就只能看书、上网查资料、问同学等各种方法来解决问题,最终把问题解决。
实验 四 类的创建 一、实验目的 1. 掌握面向对象编程基本思想 2. 掌握 VC++.net 中创建类 3. 掌握建立和使用对象 4. 掌握运算符号重载 5. 理解类的继承和多态性 二、实验内容 1.设计一个角度类。要求该类具有度分秒至度的换算、度至度分秒的换算、度与 弧度的换算等功能。提示:设置一个角度大小属性,并设定该属性为缺省属性; 另设一个状态属性,表示当前设置的角度大小的形式;度分秒、度、弧度间的相 互转换的方法;定义运算符号(加、减)方法,使得角度类能够像一种普通的数
据类型样的方便使用。
:
设计思路:设计一个角度类在类的头文件里申明度到度分秒的转换、度分秒到度的转换、度到弧度的转换、运算符的重载,在类的.cpp 文件中写出具体的函数实现,在按钮下面调用类的各个函数来实现角度的转换。
界面设计:
主要代码:
DECLARE_MESSAGE_MAP() public:
double dmstodgree(double dmg);//声明度分秒到度的转换函数
double dgreetodms(double drgree);//声明度到度分秒的转换函数
double dgreetohd(double dgree);//声明度到弧度的转换函数 };
DECLARE_MESSAGE_MAP() public:
afx_msg void OnBnClickedCancel();
double dgree;
double dms;
double hd;
afx_msg void OnBnClickedButton1();
afx_msg void OnBnClickedButton2();
afx_msg void OnBnClickedButton3();
afx_msg void OnBnClickedOk(); };
void Cymh4Dlg::OnBnClickedCancel() {
// TODO: 在此添加控件通知处理程序代码
OnCancel(); }
void Cymh4Dlg::OnBnClickedButton1() {
// TODO: 在此添加控件通知处理程序代码
UpdateData(true);
Angle sf;
sf.dgreetodms(dgree);
UpdateData(false); }
void Cymh4Dlg::OnBnClickedButton2() {
// TODO: 在此添加控件通知处理程序代码
UpdateData(true);
Angle sf;
sf.dmstodgree(dms);
UpdateData(false); }
void Cymh4Dlg::OnBnClickedButton3() {
// TODO: 在此添加控件通知处理程序代码
UpdateData(true);
Angle sf;
sf.dgreetohd(dgree);
UpdateData(false); }
void Cymh4Dlg::OnBnClickedOk() {
// TODO: 在此添加控件通知处理程序代码
//OnOK();
UpdateData(true);
dgree=0;
dms=0;
hd=0;
UpdateData(false); }
运行结果:这个实验调试最终没有通过所以没有结果
总 总
结
这个实验给我的最大的感受是细节决定成败,实践总会比想象的困难,虽然我非常清除实验原理可是但我按照我的思路去写的时候各种调试改还是有错,我不清楚为什么 Angle sf;
sf.dgreetodms(dgree);这样的语句在程序七中调试能通过而这个程序中却死活不行。
实验 五文 件 一、实验目的
掌握文件对话框的使用方法。
掌握 C++文件操作的一般步骤及实现方法。
了解 MFC 文件操作的特点及使用方法。
二、实验内容 1. 编制简单的 Cass 数据文件进行数据整理的程序。整理后的数据文件中要求无 重复点数据,且数据按点号大小的升序进行排序。要求整理后的数据按与原始数 据文件同样的格式保存为另外一个文件 示例数据“民用园燃气.dat”文件数据格式:
总点数 点号,编码,X,Y,H „ 例如:
要求:
a.用 SaveFileDialog 和 OpenFileDialog 控件获取文件打开或保存的文件 名。
b.自定义一个测量点数据结构体,其元素包括:点号,编码,X,Y,H c.用文本框显示原始数据和整理后的数据 d..按编程规范进行编码 a. 读数据、保存数据、判断一个点数据是否已经存在、排序、在文本框中 显示文件内容等可以分别定义成一个子过程或函数。
c.编程技巧 打开文件
获得总点数根据点数调整数组的大 逐行读取数据,判断该点是否已经存在数组 中,若不存在,则把该数据存放在数组中 根据删除重复点后的总点 数,重新调整数组大小 按点号大小的升序排序 按原数据格式输出到另外一个文件 设计思路:在按钮下面设置主程序。通过打开文件按钮将原文件打开并显示到示例编辑框内,通过保存文件按钮实现对文件分行、删除重复点、排序、保存更改后的文件并把它显示到示例编辑框中等操作。
界面设计:
主要代码:// 实现 protected:
HICON m_hIcon;
// 生成的消息映射函数
virtual BOOL OnInitDialog();
afx_msg void OnSysCommand(UINT nID, LPARAM lParam);
afx_msg void OnPaint();
afx_msg HCURSOR OnQueryDragIcon();
DECLARE_MESSAGE_MAP() public:
afx_msg void OnBnClickedOk();
afx_msg void OnBnClickedCancel();
CString yuanshi;
CString xiugai;
CString *CMy0145110615ymh5Dlg::Splitstring(CString str,char split,int &isubstr); // 0145110615 ymh 5Dlg.cpp : 实现文件 #include "stdafx.h" #include "0145110615 ymh 5.h" #include "0145110615 ymh 5Dlg.h" #include <locale.h> #include <string.h> #ifdef _DEBUG #define new DEBUG_NEW #endif //定义结构体里面的数据类型包括点号、编码、X、Y、H struct Point {
int number;
CString coder;
double X;
double Y;
double H; }; CString *CMy0145110615ymh5Dlg::Splitstring(CString str,char split,int &isubstr)//分割函数 {
int M=0;//分割位置
int N=0;//分割符的总数
CString strLeft=str;
CString strRight;//定义两个字符串变量
//计算字符串的总数
while(M!=-1)
{
M=strLeft.Find(split);//查找分割位置并赋给M
strRight=strLeft.Mid(M+1,str.GetLength());// 把 字 符 串 位 置 和 长 度 信 息 赋 给strRight字符串
strLeft=strRight;
N++;//字符串总数加一
if(N==0)//如果分割符的总数为字符串数就是字符串本身
{
isubstr=1;
return NULL;
}
}
isubstr=N+1;//字符串数等于分割符数加
CString* pStrSlipt;//创建字符串指针
pStrSlipt=new CString[isubstr];//创建字符串数组
strLeft=str;
CString strLeftss;
for(int i=0;i<N;i++)
{
M=strLeft.Find(split);
strLeftss=strLeft.Left(M);
strRight=strLeft.Mid(M+1,strLeft.GetLength());//把字符串位置和长度信息赋给strRight字符串
strLeft=strRight;
pStrSlipt[i]=strLeftss;
}
pStrSlipt[N]=strLeft;
return pStrSlipt; }
void CMy0145110615ymh5Dlg::OnBnClickedOk() {
// TODO: 在此添加控件通知处理程序代码
//OnOK();
UpdateData(true);
CFileDialog dlgFile(TRUE,_T("txt"),NULL,
OFN_ALLOWMULTISELECT|OFN_EXPLORER,_T("(文本文件)|*.txt"));//创建打开文件的对话框
if(dlgFile.DoModal()==IDCANCEL)return;//如果选择取消按钮则返回
CString strFileName=dlgFile.GetPathName();//获取打开文件文件全名(含全路径)
setlocale(LC_ALL,"");//设置语言环境
CStdioFile sf;//设置文件对象
if(!sf.Open(strFileName,CFile::modeRead))return;//如果没有打开文件则返回
CString strLine;//定义CString变量
yuanshi.Empty();//文件和显示框建立联系
BOOL bEOF=sf.ReadString(strLine);//把文件中读取的行之赋给变量bEOF
while(bEOF)
{
yuanshi+=strLine;
bEOF=sf.ReadString(strLine);
if(bEOF)yuanshi+=_T("\n");//判断文件是否结束
}
sf.Close();//关闭文件
UpdateData(false); }
void CMy0145110615ymh5Dlg::OnBnClickedCancel() {
// TODO: 在此添加控件通知处理程序代码
UpdateData(true);
CFileDialog dlgFile(FALSE,_T("dat"),NULL,
OFN_ALLOWMULTISELECT|OFN_EXPLORER,_T("文本文件)|*.dat"));//创建保存文件的对话框
if(dlgFile.DoModal()==IDCANCEL)return;//如果选择取消按钮则返回
CString strFileName=dlgFile.GetPathName();//获取保存文件的文件全名(含路径)
setlocale(LC_ALL,"");//设置语言环境
CStdioFile sf;//设置文件对象
if(!sf.Open(strFileName,CFile::modeRead))return;//如果没有保存文件则返回
sf.WriteString(yuanshi);//调用文件的写函数
sf.Close();
int aLine;//定义行变量
CString *pstrLine=Splitstring(yuanshi,"\n",aLine);//将文件进行分行并以此存入字符串数组中
int TotalPoint;//总点数
CString *strTmp=NULL;//定义字符串数组并初始化
TotalPoint=_ttoi(pstrLine[0]);//第一行为总点数
if(TotalPoint!=aLine-1)
MessageBox(_T("数据有误"));
Point *pPoint=new Point[TotalPoint];//创建大小为总点数的结构体数组
int n;
//用Split函数将文件逐行分离,给点结构体赋值
for(int i=0;i<TotalPoint;i++)
{
strTmp=Splitstring(pstrLine[i+1],",",n);//分离的行逐行存入字符串数组中
pPoint[i].number=_ttoi(strTmp[0]);//依次给结构体里的元素赋值
pPoint[i].coder=strTmp[1];
pPoint[i].X=_tstof(strTmp[2]);
pPoint[i].Y=_tstof(strTmp[3]);
pPoint[i].H=_tstof(strTmp[4]);
}
if(strTmp!=NULL)//赋值完毕时释放字符串数组的空间
{
delete[] strTmp;
strTmp=NULL;
}
//判断是否有相同的点号若有则删除点号相同的点
for(int i=0;i<TotalPoint;i++)
{
for(int j=i+1;j<TotalPoint;j++)
{
if(pPoint[i].number=pPoint[j].number)
delete [] pPoint;
//删除了点后改变结构体数组的大小并重新对其赋值
for(int m=j;m<TotalPoint-1;m++)
{
pPoint[m]=pPoint[m+1];
}
TotalPoint--;
}
}
//按点号的生序排列
for(int i=0;i<TotalPoint;i++)
{
for(int j=i+1;j<TotalPoint;j++)
{
int t;
if(pPoint[i].number>pPoint[j].number)
{
t=pPoint[i].number;pPoint[j].number=t;pPoint[i].number=pPoint[j].number;
}
}
}
//输出调整后的文件
xiugai.Format(_T("%d\r\n"),TotalPoint);//第一行输出点的总数
CString strOutPut;//定义字符串变量
for(int i=0;i<TotalPoint;i++)
{
strOutPut.Format(_T("%d,%s,%lf,%lf,%lf"),pPoint[i].number,pPoint[i].coder,pPoint[i].X,pPoint[i].Y,pPoint[i].H);
}
xiugai=xiugai+strOutPut;//将第一行和其他所有行合并
CString strLine;//定义CString变量
xiugai.Empty();//文件和显示框建立联系
BOOL bEOF=sf.ReadString(strLine);//把文件中读取的行之赋给变量bEOF
while(bEOF)
{
xiugai+=strLine;
bEOF=sf.ReadString(strLine);
if(bEOF)yuanshi+=_T("\n");//判断文件是否结束
}
sf.Close();//关闭文件
UpdateData(false);
//OnCancel(); } 运行 结果:
总 总
结:
这次实验的主要问题是遇到主要问题是程序调试花了很多事间。因为要完完整整的自己写出一个程序对我来说还是有难度的,所以我不得不照着书上和网上的一些写法来写的所以有一些语句不是特别清楚,所以调试的时候很多错误都觉得很奇怪。尽管如此还是花了很多时间先把程序的构架和一些语句弄懂了最终才把问题解决
实验 六 图形程序设计 一、实验目的
掌握 VC++.net 坐标系和各项设置方法。
掌握 GDI 绘图方法。
理解交互式图形程序设计 二、实验内容 1.下列数据为一变形监测点的 24 期位移监测结果(分别为 X,Y,H),编制程序绘 制出该点的变形曲线图,每个方向一个位移序列图。
设计思路:用类 DeformationCurve 实现原始文件的读入、文件的拆分、画图等功能,调用类的相关函数来实现相应的功能。
界面设计:因为是基于当文本的所以没有界面 主要代码:class DeformationCurve : public CWnd {
DECLARE_DYNAMIC(DeformationCurve) public:
DeformationCurve();
virtual ~DeformationCurve(); protected:
DECLARE_MESSAGE_MAP() public:
CString *DeformationCurve::Splitstring(CString str,char split,int &isubstr);
void DeformationCurve::ReadData(double *&X,double *&Y,double *&H);
void DeformationCurve::Draw(CDC* pDC,CRect& rect); }; // DeformationCurve.cpp : 实现文件 #include "stdafx.h" #include "0145110615 ymh 6.h" #include "DeformationCurve.h" #include <locale.h> CString *DeformationCurve::Splitstring(CString str,char split,int &isubstr)//分割函数 {
int M=0;//分割位置
int N=0;//分割符的总数
CString strLeft=str;
CString strRight;//定义两个字符串变量
//计算字符串的总数
while(M!=-1)
{
M=strLeft.Find(split);//查找分割位置并赋给M
strRight=strLeft.Mid(M+1,str.GetLength());// 把 字 符 串 位 置 和 长 度 信 息 赋 给strRight字符串
strLeft=strRight;
N++;//字符串总数加一
if(N==0)//如果分割符的总数为字符串数就是字符串本身
{
isubstr=1;
return NULL;
}
}
isubstr=N+1;//字符串数等于分割符数加
CString* pStrSlipt;//创建字符串指针
pStrSlipt=new CString[isubstr];//创建字符串数组
strLeft=str;
CString strLeftss;
for(int i=0;i<N;i++)
{
M=strLeft.Find(split);
strLeftss=strLeft.Left(M);
strRight=strLeft.Mid(M+1,strLeft.GetLength());//把字符串位置和长度信息赋给strRight字符串
strLeft=strRight;
pStrSlipt[i]=strLeftss;
}
pStrSlipt[N]=strLeft;
return pStrSlipt; }
void DeformationCurve::ReadData(double *&X,double *&Y,double *&H)//读取原始文件中的数据 {
CFileDialog dlgFile(TRUE,_T("txt"),NULL,
OFN_ALLOWMULTISELECT|OFN_EXPLORER,_T("(文本文件)|*.txt"));//创建打开文件的对话框
if(dlgFile.DoModal()==IDCANCEL)return;//如果选择取消按钮则返回
CString strFileName=dlgFile.GetPathName();//获取打开文件文件全名(含全路径)
setlocale(LC_ALL,"");//设置语言环境
CStdioFile sf;//设置文件对象
if(!sf.Open(strFileName,CFile::modeRead))return;//如果没有打开文件则返回
CString str;
CString strLine;
str.Empty();//文件和显示框建立联系
BOOL bEOF=sf.ReadString(strLine);//把文件中读取的行之赋给变量bEOF
while(bEOF)
{
str+=strLine;
bEOF=sf.ReadString(strLine);
if(bEOF)str+=_T("\n");//判断文件是否结束
}
sf.Close();//关闭文件
int aLine;//定义行变量
CString *pstrLine=Splitstring(str,"\n",aLine);//将文件进行分行并以此存入字符串数组中
if(aLine<2)
{
MessageBox(_T("数据不完整"));
return;
}
CString *strTmp=NULL;//定义字符串数组并初始化
int TotalPoint=_ttoi(pstrLine[0]);//第一行为总点数
//建立三个大小为总点数的数组
int n;
X= new double[TotalPoint];
Y= new double[TotalPoint];
H= new double[TotalPoint];
//间原始数据逐行、三个方向分离
for(int i=1;i<TotalPoint;i++)
{
strTmp=Splitstring(pstrLine[i+1],",",n);
X[i]=_tstof(strTmp[0]);
Y[i]=_tstof(strTmp[1]);
H[i]=_tstof(strTmp[2]);
}
if(strTmp!=NULL)//赋值完毕时释放字符串数组的空间
{
delete[] strTmp;
strTmp=NULL;
} } void DeformationCurve::Draw(CDC* pDC,CRect& rect)//绘制坐标轴 {
CPen pen(PS_SOLID,2,RGB(0,0,0));
CPen *pOldPen=pDC->SelectObject(&pen);
pDC->Rectangle(rect);
int dOrgX,dOrgY;
int dEndX,dEndY;
dOrgX=rect.left+int(0.2*rect.Width());
dOrgY=rect.bottom-int(0.2*rect.Height());
dEndX=rect.right-int(0.1*rect.Width());
dEndY=rect.top+int(0.2*rect.Height());
pDC->MoveTo(rect.left,rect.top+dOrgY);
pDC->LineTo(rect.right,rect.top+dOrgY);//绘制X轴
pDC->MoveTo(rect.left+dOrgX,rect.bottom);
pDC->LineTo(rect.left+dOrgX,rect.top);//绘制Y轴
int dx,dy;//定义两个变量用来表是X轴和Y轴的间隔
dy=(dOrgY-dEndY)/3;//Y轴的间隔为
dx=(dOrgX-dEndX)/24;//X轴的间隔为
//绘制水平线
for(int i=0;i<3;i++)
{
pDC->MoveTo(dOrgX,dEndY+i*dy);
pDC->LineTo(dEndX,dEndY+i*dy);
}
pDC->SelectObject(pOldPen);//画笔回到原点
LOGFONT lf;//定义变量
memset(&lf,0,sizeof(LOGFONT));//
lf.lfHeight=16;
_tcsncpy_s(lf.lfFaceName, LF_FACESIZE, _T("宋体"), 4);
CFont font;//创建字体
font.CreateFontIndirectW(&lf);
CFont*pOldFont=pDC->SelectObject(&font);//创建CFont指针指向font
CString str;
//绘制时间刻度
for(int i=1;i<=24;i++)
{
pDC->MoveTo(dx*i+dOrgX,dOrgY);
pDC->LineTo(dx*i+dOrgX,dOrgY - 5);
str.Format(_T("%d"),i);
if(i!=0)
{
pDC->TextOutW(dx*i+dOrgX, dOrgY + 10,str);
}
}
pDC->TextOut(dOrgX+400,dOrgY+30,_T("时间"));//确定X轴和Y轴的间隔分别是和个单位
pDC->TextOut(dOrgX+300,dEndY-50,_T("蓝:X方向绿:Y方向红:H方向"));
pDC->SelectObject(pOldFont);//画笔回到原来的位置
font.DeleteObject();//删除font的对象
//绘制坐标X、Y、H的刻度
CFont fontA;//创建坐标字体
fontA.CreateFontIndirectW(&lf);
pOldFont=pDC->SelectObject(&fontA);
pDC->TextOut(dOrgX-60,dEndY-30,_T("X"),1);//绘制X轴的刻度
pDC->TextOut(dOrgX-120,dEndY-30,_T("Y"),1);//绘制Y轴的刻度
pDC->TextOutW(dOrgX-180,dEndY-30,_T("H"),1);//绘制H轴的刻度
pDC->SelectObject(pOldFont);
for(int i=0;i<=3;i++)
{
str.Format(_T("%.3f"),32.585-0.005*i);
pDC->TextOutW(dOrgX-60,dEndY+i*dy,str);
}
for(int i=0;i<=3;i++)
{
str.Format(_T("%.3f"),-52.78-0.005*i);
pDC->TextOutW(dOrgX-120,dEndY+i*dy,str);
}
for(int i=0;i<=3;i++)
{
str.Format(_T("%.3f"),0.145-0.005*i);
pDC->TextOutW(dOrgX=180,dEndY+i*dy,str);
}
fontA.DeleteObject();
//调用函数读取数据,获得变形数据
double *X=NULL;
double *Y=NULL;
double *H=NULL;
ReadData(X,Y,H);
//创建蓝色画笔
CPen penBlue;
penBlue.CreatePen(PS_SOLID,2,RGB(0,0,255));
pDC->SelectObject(penBlue);
POINT ptX[256];//定义结构体变量
//实际坐标与屏幕坐标的转换
for(int i=0;i<24;i++)
{
ptX[i].x=dOrgX+i*dx;
ptX[i].y=dOrgY-int((X[i]-32.57)/0.015*3*dy);
}
pDC->Polyline(ptX,24);//绘制X方向的变形曲线
//回复原来绘图属性
pDC->SelectObject(pOldPen);
penBlue.DeleteObject();
//创建绿色画笔绘制Y方向变形曲线
CPen penGreen;
penGreen.CreatePen(PS_SOLID,2,RGB(0,255,0));
pDC->SelectObject(penGreen);
POINT ptY[256];
for(int i=0;i<24;i++)
{
ptY[i].x=dOrgX+i*dx;
ptY[i].y=dOrgY-int((Y[i]+52.795)/0.015*3*dy);
}
pDC->Polyline(ptY,24);
//回复原来的绘图属性
pDC->SelectObject(pOldPen);
penGreen.DeleteObject();
//创建红色画笔绘制H方向的变形曲线
CPen penRed;
penRed.CreatePen(PS_SOLID,2,RGB(255,0,0));
pDC->SelectObject(penRed);
POINT ptH[256];
for(int i=0;i<24;i++)
{
ptH[i].x=dOrgX+i*dx;
ptH[i].y=dOrgY-int((H[i]-0.13/0.015*3*dy));
}
pDC->Polyline(ptH,24);
//恢复原来绘图属性
pDC->SelectObject(pOldPen);
penRed.CreateObject(); } 运行结果:
总 总
结
这次实验也遇到了实验五同样的问题调试的时间也花了好多,但有了之前实验五的经验做起来稍稍好一些,不过程序运行出来之后我发现前面的折线有三条而后面却只有一条并且老师给的示例里面也只有一条线。我也不清楚我哪儿弄错了总之改了好多地方还是这样。
每次做完实验我都只想感叹自己的 C++基础是在是太差了很多东西别人轻而易举就弄出来了而我就是要在哪儿捣鼓好久,效率超级低人家实验八都已近快完成了可我还还停留在实验六里不停地出错不停的改错,一次一次的重复着有的时候真的很烦很想放弃可是想想老师考试会很难的样子,万一挂了就麻烦了还是硬着头皮往下做,最终还是做出来了。所以还是不能随随便便放弃。
实验 七
常用测量程序设计 一、实验目的
巩固类的创建与使用
掌握数组参数的传递
掌握常用测绘程序设计的技巧 二、实验内容 编写高斯投影正、反算程序 设计思路:设计了一个 Transformation 类这个类实现度分秒换成度、度换成度分秒、定义各类坐标的坐标参数、计算 S、计算 Bf、正算和反算的功能。变量从示例编辑框中添加,在按钮下面调用类的各种函数来实现坐标的转换。
界面设计:
主要代码:
#pragma once #include "afxwin.h"
DECLARE_MESSAGE_MAP() public:
afx_msg void OnBnClickedOk();
double b;
double l;
double x;
double y;
double n;
afx_msg void OnBnClickedSplit1();
afx_msg void OnBnClickedButton1();
afx_msg void OnBnClickedButton2();
afx_msg void OnCbnSelchangeCombo1(); CComboBox c_combox; // Transformation class Transformation : public CWnd {
DECLARE_DYNAMIC(Transformation) public:
Transformation();
virtual ~Transformation(); protected:
DECLARE_MESSAGE_MAP()
public:
double dmstodgree(double dmg);//声明度分秒到度的转换函数
double dgreetodms(double drg);//声明度到度分秒的转换函数
void parameter(int type);//声明给出坐标参数的函数
double CompexS(double B);//声明计算当前点到子午线的长度的计算公式函数
double CompexBf(double x);//声明计算底点纬度的函数
void zhengsuan(double b,double l,int type,double n,double &x,double&y);//声明正算函数
void fangsuan(double x,double y,int type,double n,double &b,double &l);//声明反算含数据
void clear(double x,double y,int type,double n,double b,double l);//声明清除函数 }; double Transformation::dmstodgree(double dmg)//度分秒转换成度 {
double dge;
int Dgree;
int Min;
int Secend;
Dgree=int(dmg);//截取度的整数部分
Min=int((dmg-Dgree)*100);//截取分的部分
Secend=int((dmg-Dgree)*100-Min)*100;//截取秒的部分
dge=Dgree+(Min/60)+(Secend/3600);//将度分秒转换为度
return dge;//返回度 } double Transformation::dgreetodms(double drg)//度转换成度分秒 {
double dge;
int Dgree;
int Min;
int Secend;
Dgree=int(drg);//截取度的整数部分
Min=int((drg-Dgree)*60);//截取分的整数部分
Secend=int(((drg-Dgree)*60-Min)*60);//截取秒的整数部分
dge=Dgree+Min/100+Secend/10000;//将度转换成度分秒
return dge;//返回度分秒
} void Transformation::parameter(int type) {
//北京坐标系参数
if(type==0)
{
double a=6378245.0;
double b=6356863.0187730473;
}
//国家坐标系参数
if(type==1)
{
double a=6378140.0;
double b=6356755.2881575287;
}
//WGS84坐标系参数
if(type==2)
{
double a=6378137.0;
double b=6356752.3142;
} } double Transformation::CompexS(double B) {
double A0=1+4/3*e*e+45/64*pow(e,4)+350/512*pow(e,6)+11025/16384*pow(e,8);
double A2=-1/2*(3/4*e*e+60/64*pow(e,4)+525/512*pow(e,6)+17640/16384*pow(e,8));
double A4=1/4*(15/64*pow(e,4)+210/512*pow(e,6)+8820/16384*pow(e,8));
double A6=-1/6*(35/512*pow(e,6)+2520/16384*pow(e,8));
double A8=1/8*(315/16384*pow(e,8));
double S=a*(1-e*e)*(A0*B+A2*sin(2*B)+A4*sin(4*B)+A6*sin(6*B)+1/8*A8*sin(8*B));//计算当前点到赤道的子午线长度
return S; }
double Transformation::CompexBf(double x) {
double A0=1+4/3*e*e+45/64*pow(e,4)+350/512*pow(e,6)+11025/16384*pow(e,8);
double B0=CompexS(x)/(a*(1-e*e)*A0);
double k0=1/2*(3/4*e*e+45/64*pow(e,4)+350/512*pow(e,6)+11025/16384*pow(e,8));
double k2=-1/3*(63/64*pow(e,4)+1108/512*pow(e,6)+58239/16384*pow(e,8));
double k4=1/3*(604/512*pow(e,6)+68484/16384*pow(e,8));
double k6=-1/3*(26328/16384*pow(e,8));
double Bf=(B0)+sin(2*(B0)*(k0+sin(B0)*sin(B0))*(k2+sin(B0)*sin(B0)*(k4+k6*sin(B0)*sin(B0))));
return Bf; } void Transformation::zhengsuan(double b,double l,int type,double n,double &x,double&y) {
double dl=dmstodgree(l);
double N=dmstodgree(n);
double L=(dl-N)*3600/206265;
double B=dmstodgree(b)*PI/180;
parameter(type);
double e;
e=(sqrt(a*a-b*b))/a;
double e1;
e1=(sqrt(a*a-b*b))/b;
double n1=e1*cos(B);
double t=tan(B);
double N1=a/sqrt(1-e*e*sin(B)*sin(B));
double p2=20626;//弧秒值
double l2=abs(L-(int(L)*6-3))*3600;//经度L同当前子午线的差值单位为秒
double s=p2*p2*p2*p2;
double v=l2*l2*l2*l2;
double u=cos(B)*cos(B)*cos(B);
x=CompexS(x)+N1/(2*(p2)*(p2))*sin(B)*cos(B)*(l2)*(l2)+N/(24*(p2)*(p2))*sin(B)*u*(5-t*t+9*n1*n1+4*n1*n1*n1*n1)*v+N1/(720*p2*p2*s)*sin(B)*cos(B)*cos(B)*u*(61-58*t*t+t*t*t*t)*l2*l2*v;
y=N1/(p2)*cos(B)*(l2)+N*p2/(6*s)*u*(1-t*t+n*n)*v/l2+N1/(120*p2*s)*cos(B)*cos(B)*u*(5-18*t*t+t*t*t*t-58*n1*n1*t*t)*l2*v;
}
void Transformation::fangsuan(double x,double y,int type,double n,double &b,double &l) {
parameter(type);
double Bf=CompexBf(x);
double Y=y-50000;
double X=x;
double Tf=tan(Bf);
double nf=e1*cos(Bf);
double Nf=a/sqrt(1-e*e*sin(Bf)*sin(Bf));
double Mf=Nf/(1+e1*e1*cos(Bf)*cos(Bf));
double g=Nf*Nf*Nf*Nf;
double h=Y*Y*Y*Y;
double c=Tf*Tf*Tf*Tf;
double B=Bf-Tf/(2*Mf*Nf)*Y*Y+Tf/(4*Mf*pow(Nf,3))*(5+3*Tf*Tf+nf*nf-9*nf*nf*Tf*Tf)*h-Tf/(720*Mf*Nf*g)*(61+90*Tf*Tf+45*c)*h*Y*Y;
double L=1/(Nf*cos(Bf))*Y-Nf/(6*g*cos(Bf))*(1+2*Tf*Tf+nf*nf)*h/Y+1/(120*Nf*g*cos(Bf))*(5+28*Tf*Tf+24*c+6*nf*nf+8*nf*nf*Tf*Tf)*h*Y;
b=dgreetodms(B);
l=dgreetodms(L); }
void Transformation::clear(double x,double y,int type,double n,double b,double l) {
x=0;
y=0;
type=0;
n=0;
b=0;
l=0; } #include "stdafx.h" #include "0145110615 ymh 7.h" #include "0145110615 ymh 7Dlg.h" #include "Transformation.h" #include
<iostream> #include
<math.h> void CMy0145110615ymh7Dlg::OnCbnSelchangeCombo1() {
// TODO: 在此添加控件通知处理程序代码
type=c_combox.GetCurSel(); } void CMy0145110615ymh7Dlg::OnBnClickedOk() {
// TODO: 在此添加控件通知处理程序代码
//OnOK();
UpdateData(true);
Transformation sb;
sb.clear(x, y, type, n, x, y);
UpdateData(false); } void CMy0145110615ymh7Dlg::OnBnClickedButton1()//正算 {
// TODO: 在此添加控件通知处理程序代码
UpdateData(true);
Transformation sb;
sb.zhengsuan( b, l, type, n, x,y);
UpdateData(false); } void CMy0145110615ymh7Dlg::OnBnClickedButton2()//反算 {
UpdateData(true);
Transformation sb;
sb.fangsuan( b, l, type, n, x,y);
UpdateData(false);
// TODO: 在此添加控件通知处理程序代码 }
运 行 结 果 :
总 总
结
这个实验虽然运行出来了可是结果却是不正确的,正算和反算好像都出了问题,清除按钮下面我也调用了类当中清除的函数可是点清除按钮的时候也没反应。我也仔细检查过可是最终还是没能解决问题。
在编程的过程中我发现一个问题就是程序没运行出来的时候大家都会想尽一切办法去解决掉他们,当程序运行出来了程序内部实现要是存在一些问题的话则很少有人会去改正这些错误。
实验八
平差程序设计基础
一、
实验目的
• 巩固过程的定义与调用 • 巩固类的创建与使用 • 巩固间接平差模型及平差计算 • 掌握平差程序设计的基本技巧与步骤
二、
实验内容
水准网平差程序设计。设计一个水准网平差的程序,要求数据从文件中读取, 计算部分与界面无关。
1. 水准网间接平差模型:
2. 计算示例:
近似高程计算:
3. 水准网平差计算一般步骤 (1)读取观测数据和已知数据;
(2)计算未知点高程近似值; (3)列高差观测值误差方程; (4)根据水准路线长度计算高差观测值的权; (5)组成法方程; (6)解法方程,求得未知点高程改正数及平差后高程值; (7)求高差观测值残差及平差后高差观测值; (8)精度评定; (9)输出平差结果。
4. 水准网高程近似值计算算法
实验代码:
#pragma once class
LevelControlPoint
{ public:
LevelControlPoint(void);
~LevelControlPoint(void); public:
CString strName;//点名
...
栏目最新:
- 2022年上半年党风廉政工作情况2023-03-13
- 2022年市委书记上半年抓基层党建工作述...2023-03-13
- 2022年“走路一阵风”“工作往前冲”:...2023-03-13
- 乡镇“旅游+电商”融合发展经验交流材料...2023-03-13
- 2022年学习《习近平谈治国理政》第四卷...2023-03-13
- 数字治税典型经验材料(范文推荐)2023-03-13
- 能力作风建设年典型发言提纲2023-03-13
- 2022年局长在正职干部培训班上发言材料2023-03-12
- 浅谈审查调查中几点谈话技巧(精选文档)2023-03-12
- 高新区上半年工作汇报【优秀范文】2023-03-12
相关文章: