测绘程序设计四 函数实验报告.docx
《测绘程序设计四 函数实验报告.docx》由会员分享,可在线阅读,更多相关《测绘程序设计四 函数实验报告.docx(19页珍藏版)》请在冰豆网上搜索。
![测绘程序设计四 函数实验报告.docx](https://file1.bdocx.com/fileroot1/2023-1/24/a5be038b-6730-4550-b64d-8ed50b4cd77e/a5be038b-6730-4550-b64d-8ed50b4cd77e1.gif)
测绘程序设计四函数实验报告
《测绘程序设计(VC.net)》
上机实验报告
(VisualC++.Net)
班级:
测绘1402
学号:
0401140207
姓名:
施庆章
序号:
sm_207
二零一六年五月
实验4函数
一、实验目的
∙掌握函数的定义、引用及应用方法。
二、实验内容
1.交会定点计算函数设计
把前方交会、测边交会、后方交会程序写成函数的形式,然后再通过主程序调用。
提示:
后方交会计算函数设计思路
(1)
基本原理及计算公式。
若将Pa、Pb、Pc看成权,则P点的坐标即为三个已知点的加权平均值
(2)计算程序设计步骤
设计界面,用于输入3个已知点的坐标和三个观测角、和,以及用于输出待定点坐标的文本框(12个)、静态标签框和Button按钮;
定义文本框控件变量(Value);
创建后方交会定点计算函数,函数的输入为三个观测角和三个已知点的坐标,输出为待定点坐标,输出可以用引用参数的方式输出,具体计算步骤;
a.根据已知点计算三个内角A、B、C;
b.计算Tan()、Tan()、Tan()、Tan(A)、Tan(B)、Tan(C);
c.计算Pa、Pb、Pc;
d.计算待定点坐标Xp、Yp。
创建“计算”Button按钮的Click事件函数,在该事件函数中调用后方交会计算函数,并在相应的文本框中显示计算结果。
2.高斯投影正反算计算函数设计
编写高斯投影正算与反算的两个函数,并设计简单界面对函数计算的正确性进行测试。
正算公式:
反算公式:
界面设计:
控件类型
控件ID
控件名称
变量
函数
EditControl
IDC_EDITx1
x1
EditControl
IDC_EDITx2
x2
EditControl
IDC_EDITy1
y1
EditControl
IDC_EDITy2
y2
EditControl
IDC_EDITDap
Dap
EditControl
IDC_EDITDbp
Dbp
EditControl
IDC_EDITxp
xp
EditControl
IDC_EDITyp
yp
EditControl
IDC_EDITX1
X1
EditControl
IDC_EDITX2
X2
EditControl
IDC_EDITY1
Y1
EditControl
IDC_EDITY2
Y2
EditControl
IDC_EDITalpha
a
EditControl
IDC_EDITbetta
b
EditControl
IDC_EDITXp
Xp
EditControl
IDC_EDITYp
Yp
Button
ID_BUTTON_DELETE
清除
OnBnClickedDELETE
Button
ID_BUTTON_OK2
计算前方交会
OnBnClickedOK2
Button
ID_BUTTON_OK
计算侧方交会
OnBnClickedOK
Button
ID_BUTTON_CANCLE
取消
OnBnClickedCANCLE
控件类型
控件ID
变量
控件名称
函数
EditControl
IDC_EDITXA
XA
EditControl
IDC_EDITYA
YA
EditControl
IDC_EDITXB
XB
EditControl
IDC_EDITYB
YB
EditControl
IDC_EDITXC
XC
EditControl
IDC_EDITYC
YC
EditControl
IDC_EDITalpha
alpha
EditControl
IDC_EDITbetta
betta
EditControl
IDC_EDITgamma
gamma
EditControl
IDC_EDITXP
XP
EditControl
IDC_EDITYP
YP
Button
ID_BUTTON_OK
计算
OnBnClickedOK
Button
ID_BUTTON_DELETE
清除
OnBnClickedELETE
控件类型
控件ID
变量
控件名称
函数
EditControl
IDC_EDITX
X
EditControl
IDC_EDITY
Y
EditControl
IDC_EDITB
B
EditControl
IDC_EDITL
L
EditControl
IDC_EDIT2
n
Button
ID_BUTTON_Inverse
OnBnClickedInverse
Button
ID_BUTTON_Delete
OnBnClickedDelete
Button
ID_BUTTON_Coordinate
OnBnClickedCoordinate
Button
ID_BUTTON_Cancel
OnBnClickedCancel
主要代码:
doublePI=3.1415926;
doubleEPSILON=1.0E-10;
voidFowardIntersection(doubleXa1,doubleYa1,doubleXb1,doubleYb1,doublea,doubleb,double&Xp1,double&Yp1)//前方交会函数
{
doublecota=1/tan(a);
doublecotb=1/tan(b);
Xp1=(Xa1*cotb+Xb1*cota+Yb1-Ya1)/(cota+cotb);
Yp1=(Ya1*cotb+Yb1*cota+Xa1-Xb1)/(cota+cotb);
}
voidSideIntersection(doubleXa2,doubleYa2,doubleXb2,doubleYb2,doubleDap,doubleDbp,double&Xp2,double&Yp2)//侧方交会函数
{
doubledx=Xb2-Xa2;
doubledy=Yb2-Ya2+EPSILON;//计算AB方位角(弧度制)
doubleangleAB;
if(dy>=0)
{
angleAB=0.5*PI-atan(dx/dy);
}
else
{
angleAB=1.5*PI-atan(dx/dy);
}
//计算角A
doubleDab;//AB边长
doubleA;//角A
doubleangleAP;//方位角AP
Dab=sqrt((Xb2-Xa2)*(Xb2-Xa2)+(Yb2-Ya2)*(Yb2-Ya2));
A=acos((Dab*Dab+Dap*Dap-Dbp*Dbp)/(2*Dab*Dap));
angleAP=angleAB-A;
Xp2=Xa2+Dap*cos(angleAP);
Yp2=Ya2+Dap*sin(angleAP);
}
voidCsqz2Dlg:
:
OnBnClickedCancle()//清空数据
{
UpdateData(true);
X1=0;
Y1=0;
X2=0;
Y2=0;
a=0;
b=0;
Xp=0;
Yp=0;
x1=0;
y1=0;
x2=0;
y2=0;
Dap=0;
Dbp=0;
xp=0;
yp=0;
UpdateData(false);
}
voidCsqz2Dlg:
:
OnBnClickedOk2()//进行侧方交会计算
{
UpdateData(true);
SideIntersection(x1,y1,x2,y2,Dap,Dbp,xp,yp);//调用函数
UpdateData(false);
}voidCsqz2Dlg:
:
OnBnClickedOk()//进行前方交会计算
{
UpdateData(true);
FowardIntersection(X1,Y1,X2,Y2,a,b,Xp,Yp);//调用函数
UpdateData(false);
}
doublePxy(doublex,doubley)//计算x,y的函数
{
doubleP;
P=(tan(x)*tan(y))/(tan(x)-tan(y));
returnP;
}
voidCsqzDlg:
:
OnBnClickedOk()//进行后方交会的计算
{
UpdateData(TRUE);
doublePa;
doublePb;
doublePc;
doublea,b,c,A,B,C;
a=sqrt((XC-XB)*(XC-XB)+(YC-YB)*(YC-YB));
b=sqrt((XC-XA)*(XC-XA)+(YC-YA)*(YC-YA));
c=sqrt((XB-XA)*(XB-XA)+(YB-YA)-(YB-YA));
A=acos((b*b+c*c-a*a)/(2*b*c))*180/3.1415926;
B=acos((a*a+c*c-b*b)/(2*a*c))*180/3.1415926;
C=acos((b*b+a*a-c*c)/(2*b*a))*180/3.1415926;
if(alpha+betta+C<170||alpha+betta+C>190)//判断危险圆
{
Pa=Pxy(alpha,A);
Pb=Pxy(betta,B);
Pc=Pxy(gamma,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);
}
#include"math.h"
doublePI=3.1415926;//一些常数的定义
doublep2=206265;
doublea=6378140.0;
doubleb=6356755.2881575287;
doublee=(sqrt(a*a-b*b))/a;
doublee1=(sqrt(a*a-b*b))/b;
doubledmstodgree(doubledmg)//度分秒转换成度
{
doubledge;
intDgree;
intMin;
intSecend;
Dgree=int(dmg);//截取度的整数部分
Min=int((dmg-Dgree)*100);//截取分的部分
Secend=int((dmg-Dgree)*100-Min)*100;//截取秒的部分
dge=Dgree+(Min/60)+(Secend/3600);//将度分秒转换为度
returndge;//返回度
}
doubledgreetodms(doubledrg)//度转换成度分秒
{
doubledge;
intDgree;
intMin;
intSecend;
Dgree=int(drg);//截取度的整数部分
Min=int((drg-Dgree)*60);//截取分的整数部分
Secend=int(((drg-Dgree)*60-Min)*60);//截取秒的整数部分
dge=Dgree+Min/100+Secend/10000;//将度转换成度分秒
returndge;//返回度分秒
}
doublecaculateS(doubleB)//计算X
{
doubleA0=1+3/4*e*e+45/64*pow(e,4)+350/512*pow(e,6)+11025/16384*pow(e,8);
doubleA2=-1/2*(3/4*e*e+60/64*pow(e,4)+525/512*pow(e,6)+17640/16384*pow(e,8));
doubleA4=1/4*(15/64*pow(e,4)+210/512*pow(e,6)+8820/16384*pow(e,8));
doubleA6=-1/6*(35/512*pow(e,6)+2520/16384*pow(e,8));
doubleA8=1/8*(315/16384*pow(e,8));
doubleS=a*(1-e*e)*(A0*B+A2*sin(2*B)+A4*sin(4*B)+A6*sin(6*B)+A8*sin(8*B));
returnS;
}
doublecaculateBf(doubleX)//计算Bf
{
doubleA0=1+3/4*e*e+45/64*pow(e,4)+350/512*pow(e,6)+11025/16384*pow(e,8);
doubleB0=caculateS(X)/(a*(1-e*e)*A0);
doublek0=1/2*(3/4*e*e+45/64*pow(e,4)+350/512*pow(e,6)+11025/16384*pow(e,8));
doublek2=-1/3*(63/64*pow(e,4)+1108/512*pow(e,6)+58239/16384*pow(e,8));
doublek4=1/3*(604/512*pow(e,6)+68484/16384*pow(e,8));
doublek6=-1/3*(26328/16384*pow(e,8));
doubleBf=B0+sin(2*B0)*(k0+sin(B0)*sin(B0)*(k2+sin(B0)*sin(B0)*(k4+k6*sin(B0)*sin(B0))));
returnBf;
}
voidcoordinatecalculate(doubleB,doubleL,doublen,double&X,double&Y)//正算
{
doubledl=dmstodgree(L);
doubleN=dmstodgree(n);
doublel=(dl-N)*3600/206265;
doubleb=dmstodgree(B)*PI/180;
doublen1=e1*cos(b);
doublet=tan(b);
doubleN1=a/sqrt(1-e*e*sin(b)*sin(b));
doublel2=abs(l-(int(l)*6-3))*3600;//经度L同当前子午线的差值单位为秒
doubles=p2*p2*p2*p2;
doublev=l2*l2*l2*l2;
doubleu=cos(b)*cos(b)*cos(b);
X=caculateS(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;
}
voidcoordinateinversecalculation(doubleX,doubleY,doublen,double&B,double&L)//反算
{doubleBf=caculateBf(X);
doublex=X;
doubleTf=tan(Bf);
doublenf=e1*cos(Bf);
doubleNf=a/sqrt(1-e*e*sin(Bf)*sin(Bf));
doubleMf=Nf/(1+e1*e1*cos(Bf)*cos(Bf));
doubleg=Nf*Nf*Nf*Nf;
doubleh=Y*Y*Y*Y;
doublec=Tf*Tf*Tf*Tf;
doubleb=Bf-Tf/(2*Mf*Nf)*Y*Y+Tf/(24*Mf*pow(Nf,3))*(5+3*Tf*Tf+nf*nf-9*nf*nf*Tf*Tf)*h-Tf/(720*Mf*pow(Nf,5))*(61+90*Tf*Tf+45*c)*h*Y*Y;
doublel=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;
l=l+n;
B=dmstodgree(b);//转换
L=dmstodgree(l);
}
voidqingchu(doubleX,doubleY,doublen,doubleB,doubleL)//清除
{
X=0;
Y=0;
n=0;
B=0;
L=0;
}
voidCCalculationofcoordinateDlg:
:
OnBnClickedCoordinate()//正算
{
UpdateData(true);
coordinatecalculate(B,L,n,X,Y);//调用正算函数
UpdateData(false);
}
voidCCalculationofcoordinateDlg:
:
OnBnClickedInverse()//反算
{
UpdateData(true);
coordinateinversecalculation(X,Y,n,B,L);//调用反算函数
UpdateData(false);
}
voidCCalculationofcoordinateDlg:
:
OnBnClickeddelete()//清除
{
UpdateData(true);
qingchu(X,Y,n,B,L);
UpdateData(false);
}
voidCCalculationofcoordinateDlg:
:
OnBnClickedCancel()//退出
{
OnCancel();
}
计算结果
总结
次实验虽然思维不复杂,但是因为高斯投影正反算公式比较复杂,导致工作量有点大,但还是顺利完成了。
大量添加窗体或者控件后,发现无法由系统IDE自动生成代码,如自动添加按钮响应函数等,rc管理器界面双击按钮添加函数,会出现提示框“无法执行添加/移除操作,因为代码元素Csqz是只读的”。
始认为可能是对应的.cpp和.h被加了只读属性,后来发现是工程的ncb文件引起的。
于是我在网上找到了答案,关闭vs,删除工程对应的.ncb文件,重启vs就好了。
要特别注意这样复杂的字母比较多的情况下命名就特别的重要了。
Welcome!
!
!
欢迎您的下载,
资料仅供参考!