測繪程序設計基礎 實驗1 CSU
實驗1 控制結構程序設計
(方位角計算、三維地心座標至大地座標轉換)
(工具:VS2010)
一、 實驗目的
• 掌握VC++.net語言的基本語法;
• 理解順序結構、選擇結構和循環結構程序設計的特點及應用;
• 掌握對基於對話框的MFC應用程序設計方法;
• 掌握方位角計算算法、座標轉換算法設計與實現。
二、實驗內容與要求
1.編寫一個方位角計算程序。要求:方位角輸出爲度分秒形式。
2.編寫三維地心座標至大地座標轉換互相轉換程序。
三、設計與實現:
3.1 設計思路:(主要以方位角爲例寫出)
1 在【文件】菜單執行【新建】,選擇【項目】
2 在【項目類型】窗格中,選擇【Visual C++】下的“MFC”項。在【模板】窗格中,選擇“MFC 應用程序”模板,輸入應用名稱“YG1701_10_ZRX_方位角2.0”。按嚮導創建“YG1701_10_ZRX_方位角2.0”的MFC應用程序,應用程序類型爲基於對話框。
3 在窗體上放置6個靜態文本框、5個編輯框、3個命令按鈕。
4 設置控件屬性:
4.1 將5個編輯框依次右擊執行【添加變量】,在彈出的【添加成員變量嚮導】對話框中,【類別】屬性更改爲“Value”型,【變量類型】屬性更改爲“double”型,將【變量名】依次命名爲:X1、Y1、X2、Y2、fwj;
4.2 點擊其中一命令按鈕,將其【Caption】屬性更改爲“計算”。雙擊命令按鈕,進入“void CYG1701_10_ZRX_方位20Dlg::OnBnClickedButton1()”中,添加代碼,在該.cpp文件中依次添加以上三個函數並輔以說明;另一完成歸零功能的命令按鈕操作與上類似。
5 運行和調試程序;
6 保存應用程序。
3.2 界面設計:
3.2.1方位角計算
主要控件屬性:
3.2.2三維地心座標與大地座標轉換相互轉換
主要控件屬性:
3.3主要代碼:
//3.3.1YG1701_10_ZRX_方位角2.0Dlg
/***************************************************************************
* 文件名:<YG1701_10_ZRX_方位角2.0> *
* *
* 描述:方位角計算,調用三個函數Process_Rad Process_D Process_Degree *
* *
* 歷史:**日期** **理由** **簽名** *
* 2019年3月8日 代碼格式修改 張一青 *
* *
* 外部過程: *
* *
/**************************************************************************
/***************************************************************************
* 名字:double Process_Rad(double dx1,double dy1,double dx2,double dy2) *
* *
* 描述:4個座標值--》弧度式方位角 *
* *
* 歷史:**日期** **理由** **簽名** *
* 2019年3月8日 創建該函數 張一青 *
* *
* 參數: 1.double dx1 *
* 2.double dy1 *
* 3.double dx2 *
* 4.double dy2 *
* *
* 返回值:double類型數據 轉換後的rad型方位角 *
* *
* 注:該函數在輸入兩座標值相同時,會有一對話框彈出,且此時返回值爲0 *
/**************************************************************************/
double Process_Rad(double dx1,double dy1,double dx2,double dy2)
{
double dx=dx2-dx1;
double dy=dy2-dy1;
double dRad;
if(dy>0){
if(dx<0){
dRad=atan(dy/dx)+PI;//第二象限
}
else if(dx>0){
dRad=atan(dy/dx);//第一象限
}
else{
dRad=PI/2;//位於Y軸正方向
}
}
else if(dy<0){
if(dx<0){
dRad=atan(dy/dx)+PI;//第三象限
}
else if(dx>0){
dRad=atan(dy/dx)+2*PI;//第四象限
}
else{
dRad=PI*3/2;//位於Y軸負方向
}
}
else{
if(dx>0){
dRad=0;//位於X正半軸
}
else if(dx<0){
dRad=PI;//位於X負半軸
}
else{
AfxMessageBox(_T("您不能輸入相同的座標。"));//(x1,y1)==(x2,y2)的情況
return 0;
}
}
return dRad;
}
/***************************************************************************
* 名字:double Process_D(double dRad1) *
* *
* 描述:弧度式方位角--》十進制的角度值 *
* *
* 歷史:**日期** **理由** **簽名** *
* 2019年3月8日 創建該函數 張一青 *
* *
* 參數: 1.double dRad1 *
* *
* *
* 返回值:double類型數據 dt 返回十進制的角度值 *
* *
* 注: *
/**************************************************************************/
double Process_D(double dRad1)
{
double dt;
dt=dRad1*180/PI;
return dt;
}
/***************************************************************************
* 名字:double Process_Degree(double dD) *
* *
* 描述:十進制的角度值--》度分秒形式 *
* *
* 歷史:**日期** **理由** **簽名** *
* 2019年3月8日 創建該函數 張一青 *
* *
* 參數: 1.double dD *
* *
* *
* 返回值:double類型數據 dDegree 返回度分秒形式 *
* *
* 注: *
/**************************************************************************/
double Process_Degree(double dD)
{
double dDegree;
int iDegree;
int iMin;
double dSec;
double dTmp;
iDegree=int(dD);
dTmp=(dD-iDegree)*60;
iMin=int(dTmp);
dSec=(dTmp-iMin)*60;
dDegree=iDegree+double(iMin)/100+dSec/10000;
return dDegree;
}
//按鈕
void CYG1701_10_ZRX_方位角20Dlg::OnBnClickedButton1()
{
UpdateData(TRUE);
fwj=Process_Degree(Process_D(Process_Rad(X1,Y1,X2,Y2)));// 調用了三次函數 座標值--》弧度式方位角--》十進制的角度值--》度分秒形式
UpdateData(FALSE);
}
3.3.2YG1701_10_ZRX_座標轉換2.0Dlg
/***************************************************************************
* 文件名:<YG1701_10_ZRX_座標轉換2.0> *
* *
* 描述:座標轉換,調用六個函數 *
* *
* 歷史:**日期** **理由** **簽名** *
* 2019年3月8日 代碼格式修改 張一青 *
* *
* 外部過程: *
* *
/**************************************************************************/
/***************************************************************************
* 名字:double Process_Degree(double dD) *
* *
* 描述:十進制的角度值--》度分秒形式 *
* *
* 歷史:**日期** **理由** **簽名** *
* 2019年3月8日 創建該函數 張一青 *
* *
* 參數: 1.double dD *
* *
* *
* 返回值:double類型數據 dDegree 返回度分秒形式 *
* *
* 注: *
/**************************************************************************/
double Process_Degree(double dD)
{
double dDegree;
int iDegree;
int iMin;
double dSec;
double dTmp;
iDegree=int(dD);
dTmp=(dD-iDegree)*60;
iMin=int(dTmp);
dSec=(dTmp-iMin)*60;
dDegree=iDegree+double(iMin)/100+dSec/10000;
return dDegree;
}
/***************************************************************************
* 名字:double Process_D(double dRad1) *
* *
* 描述:弧度式方位角--》十進制的角度值 *
* *
* 歷史:**日期** **理由** **簽名** *
* 2019年3月8日 創建該函數 張一青 *
* *
* 參數: 1.double dRad1 *
* *
* *
* 返回值:double類型數據 dt 返回十進制的角度值 *
* *
* 注: *
/**************************************************************************/
double Process_D(double dRad1)
{
double dt;
dt=dRad1*180/PI;
return dt;
}
/***************************************************************************
* 名字:Process_3DtoGS84() *
* *
* 描述:3維座標向大地座標GS84轉換 以B=0爲始進行迭代 *
* *
* 歷史:**日期** **理由** **簽名** *
* 2019年3月8日 創建該函數 張一青 *
* *
* 參數: 1.double dX *
* 2.double dY *
* 3.double dX *
* 4.double &dLL *
* 5.double &dBB *
* 6.double &dHH *
* *
* *
* 返回值:無 *
* *
* 注:需要調用兩個函數 Process_Degree Process_Degree *
/**************************************************************************/
void Process_3DtoGS84(double dX,double dY,double dZ,double &dLL,double &dBB,double &dHH)
{
const double dS=sqrt(dX*dX+dY*dY);
const double der=2*Alfa-Alfa*Alfa;
double dB;
double dB0=0;
double dH;
double dH0=dS-a;
double db;
double dN=a;
double dW;
//迭代過程
do
{
dB=atan(dZ/(dS*(1-der*dN/(dN+dH0))));
dW=sqrt(1-der*sin(dB)*sin(dB));
dN=a/dW;
dH=dS/cos(dB)-dN;
db=dB-dB0;
dB0=dB;
dH0=dH;
}while(fabs(db)>=0.0001);
//求B
dBB=Process_Degree(Process_D(dB0));
//求H
dHH=dH0;
//進行L的轉換
double L1=atan2(dY,dX)*180/Pi;
L1=Process_Degree(L1);
dLL=L1;
}
/***************************************************************************
* 名字:Process_oppDegree(double dDms) *
* *
* 描述:度分秒形式--》十進制的角度值 *
* *
* 歷史:**日期** **理由** **簽名** *
* 2019年3月8日 創建該函數 張一青 *
* *
* 參數: 1.double dDms *
* *
* *
* 返回值:double類型數據 dDeg 返回十進制的角度值 *
* *
* 注: *
/**************************************************************************/
double Process_oppDegree(double dDms)
{
int iDegree,iMin;
double dSec;
double dDeg;
iDegree=int(dDms);
iMin=int((dDms-iDegree)*100);
dSec=((dDms-iDegree)*100-iMin)*100;
dDeg=iDegree+double(iMin)/60+dSec/3600;
return dDeg;
}
/***************************************************************************
* 名字:double Process_oppD(double dDeg) *
* *
* 描述:十進制的角度值--》弧度式方位角 *
* *
* 歷史:**日期** **理由** **簽名** *
* 2019年3月8日 創建該函數 張一青 *
* *
* 參數: 1.double dDeg*PI/180 *
* *
* *
* 返回值:double類型數據 返回弧度值 *
* *
* 注: *
/**************************************************************************/
double Process_oppD(double dDeg)
{
return dDeg*PI/180;
}
/***************************************************************************
* 名字:Process_GS84to3D() *
* *
* 描述:大地座標GS84轉換向3維座標 *
* *
* 歷史:**日期** **理由** **簽名** *
* 2019年3月8日 創建該函數 張一青 *
* *
* 參數: 1.double &dX *
* 2.double &dY *
* 3.double &dX *
* 4.double dLL *
* 5.double dBB *
* 6.double dHH *
* *
* *
* 返回值:無 *
* *
* 注:需要調用兩個函數 Process_Degree Process_Degree *
/**************************************************************************/
void Process_GS84to3D(double &dX,double &dY,double &dZ,double dLL,double dBB,double dHH)
{
double dNN;
dLL=Process_oppD(Process_oppDegree(dLL));
dBB=Process_oppD(Process_oppDegree(dBB));
dHH=dHH;
double der=2*Alfa-Alfa*Alfa;
dNN=a/sqrt(1-der*sin(dBB)*sin(dBB));
dX=(dNN+dHH)*cos(dBB)*cos(dLL);
dY=(dNN+dHH)*cos(dBB)*sin(dLL);
dZ=(dNN*(1-der)+dHH)*sin(dBB);
}
void CYG1701_10_ZRX_座標轉換20Dlg::OnBnClickedButton2()
{
// TODO: 在此添加控件通知處理程序代碼
UpdateData(TRUE);
Process_GS84to3D(X,Y,Z,L,B,H);
UpdateData(FALSE);
}
3.4運行結果
3.5設計技巧:
一共設計了6個函數,進行了多次調用。程序便於修改。