一、程序内容
设计一个大地四边形类,注意大地四边形的基本属性,功能上只要求能够设置和返回已知点坐标、8个观测角度、闭合差以及待定点近似坐标的计算(采用条件平差进行计算,要求采用前方交会的方法计算C和D点的近似坐标)。
二、设计思路
1.新建一个C++类CGeoQuadrangle,在类的上方定义一个坐标结构体Point2D。
2.在类中声明私有访问类型的数据成员:已知点A,B;8个观测角(用一维数组存储)。
3.声明共有访问类型的成员函数:构造函数重载函数,获取数据成员的get函数,设置数据成员的set函数,能够计算C,D点坐标的前方交会函数,计算闭合差的函数。然后在类的.cpp文件中完成函数的定义。
4.设计简单的界面测试大地四边形类的功能。
三、主要代码
//CGeoQuadrangle.h;头文件
#pragma once
//定义二维坐标结构体
struct Point2D
{
double X;
double Y;
};
class CGeoQuadrangle
{
public:
CGeoQuadrangle(void);
~CGeoQuadrangle(void);
CGeoQuadrangle(Point2D A,Point2D B,double p[8]);//重载构造函数
private:
Point2D PA;
Point2D PB;
double Angle[8];
public:
double Dms_TO_Rad(double dDms); //度分秒转化为弧度
double Rad_TO_Dms(double dRad); //弧度转化为度分秒
double Dms_TO_Deg(double dDms); //度分秒转化为十进制度
void SetKnownPointA(Point2D &A); //设置已知点A坐标
void SetKnownPointB(Point2D &B); //设置已知点A坐标
struct Point2D GetKnownPointA(void); //返回已知点A坐标
struct Point2D GetKnownPointB(void); //返回已知点B坐标
void SetAngle(double p[8]); //设置个角度观测值
void GetAngle(double p[8]); //返回个角度观测值
struct Point2D ForwardIntersection(double Alpha,double Betta); //前方交会(Alpha,Betta为弧度制)
void CAL_CD(Point2D &C,Point2D &D); //求CD点坐标
void ClosingError_A(double &Omega1,double &Omega2,double &Omega3); //三角形闭合差
double ClosingError_D(void); //极条件闭合差
};
//GeoQuadrangle.cpp:实现文件
#include "StdAfx.h"
#include "GeoQuadrangle.h"
#include "math.h"
const double PI=4.0*atan(1.0);
const double rho=180/PI*3600; //弧秒值
CGeoQuadrangle::CGeoQuadrangle(void)
{
PA.X=0;
PA.Y=0;
PB.X=0;
PB.Y=0;
for (int i=0;i<8;i++)
{
Angle[i]=0;
}
}
CGeoQuadrangle::~CGeoQuadrangle(void)
{
}
//构造函数重载
CGeoQuadrangle::CGeoQuadrangle(Point2D A,Point2D B,double p[8])
{
Point2D PA=A;
Point2D PB=B;
for (int i=0;i<8;i++)
{
Angle[i]=p[i];
}
}
double CGeoQuadrangle::Dms_TO_Rad(double dDms)
{
//return 0;
return Dms_TO_Deg(dDms)/180*PI;
}
double CGeoQuadrangle::Rad_TO_Dms(double dRad)
{
//return 0;
dRad=dRad/PI*180;
int iDegree,iMin;
double dSec;
double dTmp;
double dDms;
iDegree=int(dRad);
dTmp=(dRad-iDegree)*60;
iMin=int(dTmp);
dSec=(dTmp-iMin)*60;
dDms=iDegree+double(iMin)/100+dSec/10000;
return dDms;
}
double CGeoQuadrangle::Dms_TO_Deg(double dDms)
{
//return 0;
double dDeg;
int iDegree,iMin;
double dSec;
iDegree=int(dDms);
iMin=int((dDms-iDegree)*100);
dSec=((dDms-iDegree)*100-iMin)*100;
dDeg=iDegree+double(iMin)/60+dSec/3600;
return dDeg;
}
void CGeoQuadrangle::SetKnownPointA(Point2D &A)
{
PA=A;
}
void CGeoQuadrangle::SetKnownPointB(Point2D &B)
{
PB=B;
}
struct Point2D CGeoQuadrangle::GetKnownPointA(void)
{
return PA;
}
struct Point2D CGeoQuadrangle::GetKnownPointB(void)
{
return PB;
}
void CGeoQuadrangle::SetAngle(double p[8])
{
for (int i=0;i<8;i++)
{
Angle[i]=p[i];
}
}
void CGeoQuadrangle::GetAngle(double p[8])
{
for (int i=0;i<8;i++)
{
p[i]=Angle[i];
}
}
struct Point2D CGeoQuadrangle::ForwardIntersection(double Alpha,double Betta)
{
struct Point2D P;
//计算A,B角余切值
double dCotA=1/tan(Alpha);
double dCotB=1/tan(Betta);
//计算前方交会定位值
P.X=((PA.X*dCotB+PB.X*dCotA)+(PB.Y-PA.Y))/(dCotA+dCotB);
P.Y=((PA.Y*dCotB+PB.Y*dCotA)+(PA.X-PB.X))/(dCotA+dCotB);
return P;
}
void CGeoQuadrangle::CAL_CD(Point2D &C,Point2D &D)
{
double angle[8];
GetAngle(angle); //得到8个观测角度
for (int i=0;i<8;i++)
{
angle[i]=Dms_TO_Rad(angle[i]);
}
double Alpha1=angle[1]+angle[2];
double Betta1=angle[0];
double Alpha2=angle[1];
double Betta2=angle[0]+angle[7];
C=ForwardIntersection(Alpha1,Betta1);
D=ForwardIntersection(Alpha2,Betta2);
}
void CGeoQuadrangle::ClosingError_A(double &Omega1,double &Omega2,double &Omega3)
{
double angle[8];
for (int i=0;i<8;i++)
{
angle[i]=Dms_TO_Rad(Angle[i]);
}
Omega1=(angle[4]+angle[5]+angle[6]+angle[7]-PI)*rho;//用秒存储
Omega2=(angle[0]+angle[1]+angle[2]+angle[3]-PI)*rho;
Omega3=(angle[0]+angle[1]+angle[6]+angle[7]-PI)*rho;
}
double CGeoQuadrangle::ClosingError_D(void)
{
//return 0;
double angle[8];
for (int i=0;i<8;i++)
{
angle[i]=Dms_TO_Rad(Angle[i]);
}
double a=sin(angle[0])*sin(angle[6])*sin(angle[3]+angle[4]);
double b=sin(angle[3])*sin(angle[0]+angle[7])*sin(angle[5]);
double Omega_d=(1-a/b);
Omega_d=Omega_d*rho; //用秒存储
return Omega_d;
}
// RS_120_ZQL_EX5_1Dlg.h : 头文件
class CRS_120_ZQL_EX5_1Dlg : public CDialog
{
public:
CString strResult; //显示计算结果
afx_msg void OnBnClickedBtnCal(); //计算
afx_msg void OnBnClickedCancel(); //退出
};
// RS_120_ZQL_EX5_1Dlg.cpp : 实现文件
#include "GeoQuadrangle.h"
void CRS_120_ZQL_EX5_1Dlg::OnBnClickedBtnCal()
{
UpdateData(TRUE);
strResult=_T("");
// TODO: 在此添加控件通知处理程序代码
Point2D A;
A.X=354.87;
A.Y=648.12;
Point2D B;
B.X=1601.23;
B.Y=807.83;
double p[8];
p[0]= 50.2930;
p[1]= 72.2907;
p[2]= 28.0856;
p[3]= 28.5218;
p[4]= 76.1911;
p[5]= 46.3930;
p[6]= 27.3948;
p[7]= 29.2116;
用构造函数初始化
//CGeoQuadrangle GQ(A,B,p);
//用set函数初始化
CGeoQuadrangle GQ;
GQ.SetKnownPointA(A);
GQ.SetKnownPointB(B);
GQ.SetAngle(p);
//求C,D点的坐标
Point2D C,D;
GQ.CAL_CD(C,D);
//求三角形闭合差
double omega1,omega2,omega3;
GQ.ClosingError_A(omega1,omega2,omega3);
//极条件闭合差
double omega_d;
omega_d=GQ.ClosingError_D();
//将计算结果显示在编辑框
strResult.Format(_T("%s%f%s%f\r\n%s%f%s%f\r\n%s%f%s%f%s%f%s\r\n%s%f%s"),
_T("C点坐标:"),C.X,_T(","),C.Y,
_T("D点坐标:"),D.X,_T(","),D.Y,
_T("三角形闭合差:"),omega1,_T("秒,"),omega2,_T("秒,"),omega3,_T("秒"),
_T("极条件闭合差:"),omega_d,_T("秒"));
UpdateData(FALSE);
}
void CRS_120_ZQL_EX5_1Dlg::OnBnClickedCancel()
{
// TODO: 在此添加控件通知处理程序代码
OnCancel();
}
四、运行结果