一、程式内容
設計一個大地四邊形類,注意大地四邊形的基本屬性,功能上隻要求能夠設定和傳回已知點坐标、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();
}
四、運作結果