測繪程序設計基礎 實驗7 CSU

實驗7 常用測量程序設計

(工具:VS2010)

一、 實驗目的

• 鞏固類的創建與使用
• 掌握數組參數的傳遞
• 掌握常用測繪程序設計的被巧

二、實驗內容與要求

設計一個無定向導線簡易計算的程序,
要求自己定義文件格式,把下圖中數據編寫至文件中,然後通過讀取文件
的形式獲取所有數據,計算結果也寫入結果文件中
在這裏插入圖片描述
無定向導線基本步驟:
在這裏插入圖片描述

三、設計與實現:

3.1 設計思路:

在這裏插入圖片描述

3.2 界面設計及屬性:

在這裏插入圖片描述

3.3主要代碼:

3.3.1文件:<Angle.h>  
#pragma once
enum AngleStyle
{
	DEG,
	DMS,
	RAD
};
class Angle
{
public:
	Angle(double value=0,AngleStyle style=DMS);
	~Angle(void);
	private:
		double dValue;//角度值
		AngleStyle  nCurStyle;//當前角度值類型
private:
	//設置常成員函數的作用:1.類成員不會被改變
	//2.可以被常類變量調用
	double Deg(double dDms) const;
	double Dms(double dDeg) const;
	
public:
	//獲取指定的類型獲取角度值,
    //由於返回的是dValue的引用,所以該值大小可以改變,即可以進行賦值
	double& operator() (AngleStyle style);

	//重載,獲取指定的類型獲取角度值,該值不可改變,const CAngle類型變量調用
	double operator() (AngleStyle style) const;
	//重載運算符+/-
    friend Angle operator + (const Angle& m1,const Angle& m2);
	friend Angle operator - (const Angle& m1,const Angle& m2);
};


3.3.2文件:< Angle.cpp>  
#include "StdAfx.h"
#include "Angle.h"
#include "math.h"
const double EPSILON=1.0E-12;
const double PI=4.0*atan(1.0);

//重載構造函數,有缺省值
Angle::Angle(double value,AngleStyle style)
{
	dValue=value;
	nCurStyle=style;
}

Angle::~Angle(void)
{
}
//重載()函數
double& Angle::operator() (AngleStyle style) //指定的類型獲取角度值
{
	//double dAngleValue;
    if(style==DMS)
	{
		if(nCurStyle==DEG)
		{
            dValue=Dms(dValue);
		}
		else if(nCurStyle==RAD)
		{
			dValue=Dms(dValue*180.0/PI);
		}
		nCurStyle=DMS;
        		
	}
	else if(style==DEG)
	{
	    if(nCurStyle==DMS)
		{
            dValue=Deg(dValue);
		}
		else if(nCurStyle==RAD)
		{
			dValue=dValue*180.0/PI;
		}
       nCurStyle=DEG;
	}
	else
	{
       if(nCurStyle==DMS)
		{
            dValue=Deg(dValue)*PI/180;
		}
		else if(nCurStyle==DEG)
		{
			dValue=dValue*PI/180;
		}
        nCurStyle=RAD;
	}
	return dValue;
}
//重載()函數,該函數是常函數,只能被常CAngle對象使用
double Angle::operator() (AngleStyle style) const //指定的類型獲取角度值
{
	double dAngleValue;
    if(style==DMS)
	{
		if(nCurStyle==DEG)
		{
            dAngleValue=Dms(dValue);
		}
		else if(nCurStyle==RAD)
		{
			dAngleValue=Dms(dValue*180.0/PI);
		}
		else
		{
			dAngleValue=dValue;
		}
        		
	}
	else if(style==DEG)
	{
	    if(nCurStyle==DMS)
		{
            dAngleValue=Deg(dValue);
		}
		else if(nCurStyle==RAD)
		{
			dAngleValue=dValue*180.0/PI;
		}
       else
		{
			dAngleValue=dValue;
		}
	}
	else
	{
       if(nCurStyle==DMS)
		{
            dAngleValue=Deg(dValue)*PI/180;
		}
		else if(nCurStyle==DEG)
		{
			dAngleValue=dValue*PI/180;
		}
        else
		{
			dAngleValue=dValue;
		}
	}
	return dAngleValue;
}


//私有成員,度分秒向十進制度轉換
double Angle::Deg(double dDms) const
{
	int iDeg,iMin;
	double dSec;

	iDeg = int(dDms + EPSILON);//度//加一個很小的數,以防止取整時的出錯
	iMin = int((dDms - iDeg) * 100+ EPSILON);//分
	dSec = ((dDms - iDeg) * 100 - iMin) * 100 ;//秒

	return iDeg + (double)iMin / 60 + dSec / 3600;
}

//私有成員,十進制度向度分秒轉換
double Angle::Dms(double dDeg) const
{
	int iDeg,iMin;
	double dSec;
	double dTmp;

	iDeg = int(dDeg + EPSILON);//整數部分度
	dTmp = (dDeg - iDeg) * 60;//小數部分轉換成分
	iMin = int(dTmp+ EPSILON);//取分的整數部分
	dSec = (dTmp - iMin) * 60;//截取秒

	return iDeg + (double)iMin / 100 + dSec / 10000;
}

//友元重載+函數
Angle operator + (const Angle& m1,const Angle& m2)
{
       Angle addAngle(0,RAD);
	   addAngle(RAD)=m1(RAD)+m2(RAD);
	   return addAngle;
}
//友元重載-函數
Angle operator - (const Angle& m1,const Angle& m2)
{
       Angle subAngle(0,RAD);
	   subAngle(RAD)=m1(RAD)-m2(RAD);
	   return subAngle;
}

3.3.3文件:<CData.h>  
/***************************************************************************
*  文件名:<Data.h>                                                         *
*                                                                          *
*  描述:用來儲存數據    使用了角度輔助類:Angle                            *
*                                                                          *
*  歷史:**日期**         **理由**            **簽名**                     *
*      2019年5月5日        創建              ***                      *
*                                                                          *
*  外部過程:                                                              *
*                                                                          *
/**************************************************************************/

#pragma once
#include"Angle.h"
class CData
{
public:
	CData(void);
	~CData(void);
	//未修正------------------------------------------未修正
	Angle p;//儲存角度
          double s;//邊長
	Angle _a;//儲存方位角
	double _dx;//儲存座標X增量
	double _dy;//儲存座標Y增量
	double _X;//儲存未修正原始X
	double _Y;//儲存未修正原始Y

	//修正------------------------------------------修正
	Angle a;//儲存改正後方位角
	double X;//儲存修正後X
	double Y;//儲存修正後Y
	//------------------------------------------數據僅僅儲存至開頭元素 即P[0]中
	Angle Sum_a;//總方位角
	Angle _Sum_a;//假定總方位角
	Angle alfa;// 總方位角-假定總方位角

	double S;//總長度
	double _S;//觀測值總長度
	double k;//  總長度/觀測值總長度
	int iSum;
};


3.3.4文件:<CData.cpp>  
#include "StdAfx.h"
#include "Data.h"


CData::CData(void)
{
}


CData::~CData(void)
{
}

3.3.5文件:<CSupport.h>  
/***************************************************************************
*  文件名:<CSupport.h>                                                     *
*                                                                          *
*  描述:操縱主要函數     使用了類CData                                     *
*                                                                          *
*  歷史:**日期**         **理由**            **簽名**                     *
*      2019年5月5日        創建              ***                        *
*                                                                          *
*  外部過程:                                                              *
*                                                                          *
/**************************************************************************/
#pragma once
#include"Data.h"
#include <locale.h>
#include"math.h"
class CSupport
{
public:
	CSupport(void);
	~CSupport(void);
	void main();//主要函數
CString * SplitString(CString str, char split, int& iSubStrs);//字符串分割函數
private:
	double Process_Rad(double dx1,double dy1,double dx2,double dy2);//角度轉換
	double length(double x1,double y1,double x2,double y2);//求距離
	void read();//讀取函數
	void Pocess();//過程函數
	void Out();//輸出函數
private:
	CData *P;
};

3.3.6文件:<CSupport.cpp>  
#include "StdAfx.h"
#include "Support.h"
#define PI 4.0*atan(1.0)

CSupport::CSupport(void)
{
}


CSupport::~CSupport(void)
{
	delete [] P;
}


/***************************************************************************
*  名字:CString * CSupport::SplitString(CString str, char split, int& iSubStrs)*
*                                                                          *
*  描述:字符串分割函數2                                                   *
*                                                                          *
*  歷史:**日期**         **理由**            **簽名**                     *
*      2019年5月5日       引用該函數          ***                      *
*  參數: 1.CString str                                                    *
*         2.char split                                                     *
*         3.int& iSubStrs                                                  *
*  返回值:返回指針   指針帶有動態數組的內容                               *
*                                                                          *
*  注:                                                                    *
/**************************************************************************/
CString * CSupport::SplitString(CString str, char split, int& iSubStrs)
{
    int iPos = 0; //分割符位置
    int iNums = 0; //分割符的總數
    CString strTemp = str;
    CString strRight;
    //先計算子字符串的數量
    while (iPos != -1)
    {
        iPos = strTemp.Find(split);
        if (iPos == -1)
        {
            break;
        }
        strRight = strTemp.Mid(iPos + 1, str.GetLength());
        strTemp = strRight;
        iNums++;
    }
    if (iNums == 0) //沒有找到分割符
    {
        //子字符串數就是字符串本身
        iSubStrs = 1; 
        return NULL;
    }
    //子字符串數組
    iSubStrs = iNums + 1; //子串的數量 = 分割符數量 + 1
    CString* pStrSplit;
    pStrSplit = new CString[iSubStrs];
    strTemp = str;
    CString strLeft;
    for (int i = 0; i < iNums; i++)
    {
        iPos = strTemp.Find(split);
        //左子串
        strLeft = strTemp.Left(iPos);
        //右子串
        strRight = strTemp.Mid(iPos + 1, strTemp.GetLength());
        strTemp = strRight;
        pStrSplit[i] = strLeft;
    }
    pStrSplit[iNums] = strTemp;
    return pStrSplit;
}


/***************************************************************************
*  名字:double Process_Rad(double dx1,double dy1,double dx2,double dy2)   *
*                                                                          *
*  描述:4個座標值--》弧度式方位角                                         *
*                                                                          *
*  歷史:**日期**         **理由**            **簽名**                     *
*      2019年3月8日       創建該函數          ***                       *
*      2019年5月5日       引用該函數          ***                       *
*                                                                          *
*  參數: 1.double dx1                                                     *
*         2.double dy1                                                     *
*		 3.double dx2                                                      * 
*		 4.double dy2                                                      * 
*                                                                          *
*  返回值:double類型數據   轉換後的rad型方位角                            *
*                                                                          *
*  注:該函數在輸入兩座標值相同時,會有一對話框彈出,且此時返回值爲0       *
/**************************************************************************/
double CSupport::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 length(double x1,double y1,double x2,double y2)            *
*                                                                          *
*  描述:由(x1,y1)和(x2,y2)計算兩點之間距離 長度                         *
*                                                                          *
*  歷史:**日期**         **理由**            **簽名**                     *
*      2019年3月20日       創建該函數          ***                    *
*      2019年5月5日        引用該函數          ***                    *
*  參數: 1.double x1                                                      *
*         2.double y1                                                      *
*         3.double x2                                                      *
*         4.double y2                                                      *
*  返回值:double類型數據 返回距離                                         *
*                                                                          *
*  注:                                                                    *
/**************************************************************************/
double CSupport::length(double x1,double y1,double x2,double y2)
{
	double tmp=((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2));
	return sqrt(tmp);
}

/***************************************************************************
*  名字:void CSupport::read()                                             *
*                                                                          *
*  描述:讀取函數        調用函數SplitString 開闢動態數組P                *
*                                                                          *
*  歷史:**日期**         **理由**            **簽名**                     *
*      2019年5月5日        創建該函數          ***                   *
*  參數: 1.                                                               *
*  返回值:無                                                              *
*                                                                          *
*  注:                                                                    *
/**************************************************************************/
void CSupport::read()
{
	CFileDialog dlgFile(TRUE,_T("txt"),NULL,
	OFN_ALLOWMULTISELECT|OFN_EXPLORER,
	//_T("(文本文件)|*.txt"));
	_T(""));
	if(dlgFile.DoModal()==IDCANCEL) return ;
	CString strName=dlgFile.GetPathName();//獲取打開文件文件名(路徑)
	setlocale(LC_ALL,"");
	CStdioFile sf;
	if(! sf.Open(strName,CFile::modeRead)) return ;
	CString strLine;
	CString strContent;//接受內容字符串
	strContent.Empty();
	BOOL bEOF =sf.ReadString (strLine);
	bEOF =sf.ReadString (strLine);//運行兩次
	if(!bEOF)
	{
		AfxMessageBox(_T("數據有誤,請檢查數據文件!"));
		return ;
	}
	int iPointCount;
	iPointCount=_ttoi(strLine);//讀取點數
	P=new CData [iPointCount+1];//創建動態數組
	P[0].iSum=iPointCount;
	int i1=0;
	int i2=0;
	int i3=0;
	int n=0;//爲下文讀取做鋪墊
	int counter=0;
	
	while (counter<2*P[0].iSum+1)
	{
		bEOF=sf.ReadString(strLine);
		CString *pstrData =SplitString(strLine,',',n);
		//if(pstrData==NULL) continue;
		if(counter<P[0].iSum)
		{
			P[i1].s = _tstof(pstrData[2]);
			i1++;
		}
		else if(counter<(2*P[0].iSum-1))
		{
			P[i2].p=Angle(_tstof(strLine),DMS);
			i2++;
		}
		else
		{
			if(i3==0)
			{
			P[0].X = _tstof(pstrData[0]);
			P[0].Y = _tstof(pstrData[1]);
			}
			if(i3!=0)
			{
				i3=P[0].iSum;
				P[i3].X = _tstof(pstrData[0]);
				P[i3].Y = _tstof(pstrData[1]);
				
			}
			i3++;
		}
		counter++;
	}
	sf.Close();
	//AfxMessageBox(_T("成功讀取數據!"));
}

/***************************************************************************
*  名字:void CSupport::Pocess()                                           *
*                                                                          *
*  描述:過程函數 調用函數length()、Process_Rad()函數  加工數組P中元素   *
*                                                                          *
*  歷史:**日期**         **理由**            **簽名**                     *
*      2019年5月5日        創建該函數          ***                    *
*  參數:                                                                  *
*  返回值:無                                                              *
*                                                                          *
*  注:                                                                    *
/**************************************************************************/
void CSupport::Pocess()
{
	//----------------------------------------------------------------------未修正----------------------------------------------------------------------
	//計算方位角
	P[0]._a=Angle(87.0053,DMS);
	for(int i=1;i<P[0].iSum;i++)
	{                                                                                                                                                                                                                                                
		P[i]._a=Angle(P[i-1]._a(DEG)+P[i-1].p(DEG)-180,DEG);
	}
	//計算座標增量
	for(int i=0;i<P[0].iSum;i++)
	{
		P[i]._dx=P[i].s*cos(P[i]._a(RAD));
		P[i]._dy=P[i].s*sin(P[i]._a(RAD));
	}
	//計算假定座標
	P[0]._X=0;
	P[0]._Y=0;
	for(int i=1;i<P[0].iSum+1;i++)
	{
		P[i]._X=P[i-1]._X+P[i-1]._dx;
		P[i]._Y=P[i-1]._Y+P[i-1]._dy;
	}
	//---------------------------------------------------------------------修正過程----------------------------------------------------------------------
	//計算角度偏移狀況
	
	P[0]._Sum_a=Angle(Process_Rad(P[0]._X,P[0]._Y,P[P[0].iSum]._X,P[P[0].iSum]._Y),RAD);
	P[0].Sum_a=Angle(Process_Rad(P[0].X,P[0].Y,P[P[0].iSum].X,P[P[0].iSum].Y),RAD);
	P[0].alfa=Angle(P[0].Sum_a(DEG)-P[0]._Sum_a(DEG),DEG);
	//長度縮放狀況
	P[0]._S=length(P[0]._X,P[0]._Y,P[P[0].iSum]._X,P[P[0].iSum]._Y);
	P[0].S=length(P[0].X,P[0].Y,P[P[0].iSum].X,P[P[0].iSum].Y);
	P[0].k=P[0].S/P[0]._S;

	for(int i=0;i<P[0].iSum;i++)
	{
		P[i].a=Angle(P[i]._a(DMS)+P[0].alfa(DMS),DMS);
	}
	for(int i=0;i<P[0].iSum+1;i++)
	{
		P[i].X=P[0].X+P[0].k*(P[i]._X*cos(P[0].alfa(RAD))-P[i]._Y*sin(P[0].alfa(RAD)));
		P[i].Y=P[0].Y+P[0].k*(P[i]._X*sin(P[0].alfa(RAD))+P[i]._Y*cos(P[0].alfa(RAD)));
	}
}

/***************************************************************************
*  名字:void CSupport::Out()                                              *
*                                                                          *
*  描述:輸出函數  將P中元素輸出                                           *
*                                                                          *
*  歷史:**日期**         **理由**            **簽名**                     *
*      2019年5月5日        創建該函數          ***                      *
*  參數:                                                                  *
*  返回值:無                                                              *
*                                                                          *
*  注:                                                                    *
/**************************************************************************/
void CSupport::Out()
{
	CStdioFile SF;
	CString Result;
	CString strOut;
	setlocale(LC_ALL,""); 
	if(!SF.Open(_T("Result.txt"), CFile::modeCreate|CFile::modeWrite)) return;

	Result.Format(_T("%s\r\n%s\r\n"),
			_T("----------------------------原始數據----------------------------"),
			_T("---------- 邊長")
			);
	strOut+=Result;
	
	for(int i=0;i<P[0].iSum;i++)
	{
		Result.Format(_T("%.4f\r\n"),
		P[i].s
		);
		strOut+=Result;
	}

	Result.Format(_T("%s\r\n"),
			_T("---------- 角度")
			);
	strOut+=Result;
	
	for(int i=0;i<P[0].iSum-1;i++)
	{
		Result.Format(_T("%f\r\n"),
		P[i].p(DMS)
		);
		strOut+=Result;
	}

	Result.Format(_T("%s\r\n"),
			_T("---------- 假定方位角,座標增量dx,dy")
			);
	strOut+=Result;

	for(int i=0;i<P[0].iSum;i++)
	{
		Result.Format(_T("%f,%f,%f\r\n"),
		P[i]._a(DMS),P[i]._dx,P[i]._dy
		);
		strOut+=Result;
	}

	Result.Format(_T("%s\r\n"),
			_T("---------- 假定座標")
			);
	strOut+=Result;

	for(int i=0;i<P[0].iSum+1;i++)
	{
		Result.Format(_T("%f,%f\r\n"),
		P[i]._X,P[i]._Y
		);
		strOut+=Result;
	}

	Result.Format(_T("%s\r\n%s%f\r\n%s%f\r\n%s%f\r\n"),
		    _T("----------------------------修正過程----------------------------"),
		    _T("---------- 導線總假設方位角 "),P[0]._Sum_a(DMS),
			_T("---------- 導線總真方位角 "),P[0].Sum_a(DMS),
			_T("---------- 角度閉合差 "),P[0].alfa(DMS)
			);
	strOut+=Result;
	
   Result.Format(_T("%s%f\r\n%s%f\r\n%s%f\r\n"),
		    _T("----------  導線總長"),P[0].S,
			_T("---------- 觀測值總長度"),P[0]._S,
			_T("---------- 閉合邊長度比:導線總長/觀測值總長度 "),P[0].k
			);
	strOut+=Result;
	Result.Format(_T("%s\r\n"),
			_T("---------- 修正後方位角")
			);
	strOut+=Result;

	for(int i=0;i<P[0].iSum;i++)
	{
		Result.Format(_T("%f\r\n"),
		P[i].a
		);
		strOut+=Result;
	}


	Result.Format(_T("%s\r\n"),
			_T("---------- 修正後坐標")
			);
	strOut+=Result;

	for(int i=0;i<P[0].iSum+1;i++)
	{
		Result.Format(_T("%f,%f\r\n"),
		P[i].X,P[i].Y
		);
		strOut+=Result;
	}
	SF.WriteString(strOut);
	SF.Close();
	AfxMessageBox(_T("成功!已輸入至“Result.txt”中"));
}


/***************************************************************************
*  名字:void CSupport::main()                                             *
*                                                                          *
*  描述:main函數  調用函數read()、Pocess()、Out()函數                     *
*                                                                          *
*  歷史:**日期**         **理由**            **簽名**                     *
*      2019年5月5日        創建該函數          ***                      *
*  參數:                                                                  *
*  返回值:無                                                              *
*                                                                          *
*  注:                                                                    *
/**************************************************************************/
void CSupport::main()
{
	CSupport temp;
	temp.read();
	temp.Pocess();
	temp.Out();
}


	
3.3.7文件: < RS_110_zhangruixiang_SY7Dlg.cpp >  (只摘取部分)
/***************************************************************************
*  文件名:<RS_110_zhangruixiang_SY7Dlg.cpp>                                *
*                                                                          *
*  描述:對話框                                                             *
*                                                                          *
*  歷史:**日期**         **理由**            **簽名**                     *
*      2019年5月5日        創建              ***                      *
*                                                                          *
*  外部過程:                                                              *
*                                                                          *
/**************************************************************************/



void CRS_110_zhangruixiang_SY7Dlg::OnBnClickedOk()
{
	// TODO: 在此添加控件通知處理程序代碼
	//CDialogEx::OnOK();
	CSupport k;
	k.main();
}


3.4運行結果

在這裏插入圖片描述
在這裏插入圖片描述
在這裏插入圖片描述
在這裏插入圖片描述

3.5設計技巧:

 創建多個類,層次分明。
 調用角度Angle類,省了較多力氣
 使用指針動態開闢數組,較爲方便
 使用文件操作輸入與輸出

代碼雖多,不要貪杯~

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章