测绘程序设计基础 实验6 CSU

测绘程序设计基础 实验6 CSU

  • 实验6 图形程序设计
    • 一、 实验目的
    • 二、实验内容与要求
    • 三、设计与实现:
      • 3.1 设计思路:
      • 3.2 界面设计及属性:
      • 3.3主要代码:
      • 3.4运行结果
      • 3.5设计技巧:
      • 代码虽多,不要贪杯~

实验6 图形程序设计

(工具:VS2010)

一、 实验目的

• 掌握VC++.net 坐标系和各项设置方法
• 掌握GDI绘图方法
• 理解交互式图形程序设计

二、实验内容与要求

下列数据为一变形监测点的24期位移监测结果(分别为X,Y,H),编制程序绘制出该点的变形曲线图,每个方向一个位移序列图。要求程序具有通用性,坐标刻度及格网绘制应根据读入数据本身自动标绘。
测绘程序设计基础 实验6 CSU_第1张图片
测绘程序设计基础 实验6 CSU_第2张图片

三、设计与实现:

3.1 设计思路:

测绘程序设计基础 实验6 CSU_第3张图片

3.2 界面设计及属性:

测绘程序设计基础 实验6 CSU_第4张图片

3.3主要代码:

3.3.1文件:<Data.h>  
/***************************************************************************
*  文件名:                                                         *
*                                                                          *
*  描述:用来储存数据                                                       *
*                                                                          *
*  历史:**日期**         **理由**            **签名**                     *
*      2019年5月1日        创建              张                        *
*                                                                          *
*  外部过程:                                                              *
*                                                                          *
/**************************************************************************/
#pragma once
class CData
{
     
public:

	int iID;//时间点 1-24
	int iSum;//仅记录多少点
	double dX;
	double dY;
	double dH;
	CData(void);
	~CData(void);
};

3.3.2文件:<Data.cpp>  
#include "StdAfx.h"
#include "Data.h"
CData::CData(void)
{
     
}
CData::~CData(void)
{
     
}

3.3.3文件:<CSupport.h>  

/***************************************************************************
*  文件名:                                                      *
*                                                                          *
*  描述:封装主要函数的类 ,并用了类CData                                   *
*                                                                          *
*  历史:**日期**         **理由**            **签名**                     *
*      2019年5月1日        创建              张                        *
*                                                                          *
*  外部过程:                                                              *
*                                                                          *
/**************************************************************************/
#pragma once
#include "math.h"
#include "Data.h"
//#include "RS_110_zhang_SY6View.h"
#include <locale.h>
class CSupport
{
     
	public:	
	CSupport(void);
	~CSupport(void);
	CData * read();
	 void Draw(CData *a,CDC *pDC,CRect rect,int B);
private:
	CString * SplitString(CString str, char split, int& iSubStrs);
	CData *a;
};


3.3.4文件:<CSupport.cpp>  
#include "StdAfx.h"
#include "Support.h"


CSupport::CSupport(void)
{
     
}


CSupport::~CSupport(void)
{
     
	delete [] a;//删除 动态数组
}

/***************************************************************************
*  名字:CString * CSupport::SplitString(CString str, char split, int& iSubStrs)*
*                                                                          *
*  描述:字符串分割函数2                                                   *
*                                                                          *
*  历史:**日期**         **理由**            **签名**                     *
*      2019年4月30日       引用该函数          张                      *
*  参数: 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;
}


/***************************************************************************
*  名字:CData * CSupport::read()                                          *
*                                                                          *
*  描述:读取函数                                                          *
*                                                                          *
*  历史:**日期**         **理由**            **签名**                     *
*      2019年4月1日       引用该函数          张                       *
*  参数: 无                                                               *
*  返回值:返回指针   指针带有动态数组的内容                               *
*                                                                          *
*  注:                                                                    *
/**************************************************************************/
CData * CSupport::read()
{
     
	CFileDialog dlgFile(TRUE,_T("txt"),NULL,
	OFN_ALLOWMULTISELECT|OFN_EXPLORER,
	//_T("(文本文件)|*.txt"));
	_T(""));
	if(dlgFile.DoModal()==IDCANCEL) return NULL;
	CString strName=dlgFile.GetPathName();//获取打开文件文件名(路径)
	setlocale(LC_ALL,"");
	CStdioFile sf;
	if(! sf.Open(strName,CFile::modeRead)) return NULL;
	CString strLine;
	CString strContent;//接受内容字符串
	strContent.Empty();
	BOOL bEOF =sf.ReadString (strLine);
	if(!bEOF)
	{
     
		AfxMessageBox(_T("数据有误,请检查数据文件!"));
		return NULL;
	}
	int iPointCount;
	iPointCount=_ttoi(strLine);//读取点数
	a=new CData [iPointCount];//创建动态数组
	a[0].iSum=iPointCount;
	int i=0 ;
	int n=0;//为下文读取做铺垫
	while (bEOF)
	{
     
		//strContent+=strLine;
		bEOF=sf.ReadString(strLine);
		CString *pstrData =SplitString(strLine,',',n);
		if(pstrData==NULL) continue;
		a[i].iID = ++n;
		a[i].dX =_tstof(pstrData[0]);
		a[i].dY =_tstof(pstrData[1]);
		a[i].dH =_tstof(pstrData[2]);
		i++;
		delete [] pstrData;
	    pstrData=NULL;
	}
	sf.Close();
	AfxMessageBox(_T("成功读取数据!"));
	return a;
}

/***************************************************************************
*  名字:void CSupport::Draw(CData *a,CDC *pDC,CRect rect,int B)           *
*                                                                          *
*  描述:画图函数                                                          *
*                                                                          *
*  历史:**日期**         **理由**            **签名**                     *
*      2019年4月1日       引用该函数          张                       *
*  参数: 1.CData *a             //承载着数据                              *
*         2.CDC *pDC             //画图用的指针                            *
*         3.CRect rect          //用来获取窗口大小元素                     *
*         4.int B               //用B 的数值大小0 1 2来表示X Y Z           *
*  返回值:无                                                              *
*                                                                          *
*  注:                                                                    *
/**************************************************************************/
void CSupport::Draw(CData *a,CDC *pDC,CRect rect,int B)
{
     
	double *Data=new double [a[0].iSum];
	for(int i=0;i<a[0].iSum;i++)
	{
     

		if (B==0) Data[i]=a[i].dX;
		if (B==1) Data[i]=a[i].dY;
		if (B==2) Data[i]=a[i].dH;
	
	}
	//绘制坐标轴
	CPen pen(PS_SOLID,1,RGB(0,0,0));
	pDC->Rectangle(rect);

	double X0=rect.left+100;
	double Y0=rect.bottom-100;
	double X1=rect.right-50;
	double Y1=rect.top+50;
	//绘制X轴
	pDC->MoveTo(X0,Y0);
	pDC->LineTo(X1,Y0);
	pDC->MoveTo(X1,Y0);
	pDC->LineTo(X1-10,Y0+10);
	pDC->MoveTo(X1,Y0);
	pDC->LineTo(X1-10,Y0-10);
	CString X;
	X="X";
	pDC->TextOut(X1,Y0+20,X,1);
	//绘制Y轴
	pDC->MoveTo(X0,Y0);
	pDC->LineTo(X0,Y1);
	pDC->MoveTo(X0,Y1);
	pDC->LineTo(X0-10,Y1+10);
	pDC->MoveTo(X0,Y1);
	pDC->LineTo(X0+10,Y1+10);
	CString Y;
	X="Y";
	pDC->TextOut(X0-20,Y1,X,1);

	//绘制X轴平行线
	double ddy=(fabs(Y1-Y0)-100)/10;
	double temp;
	temp=ddy;
	for(int t=0;t<12;t++)
	{
     
	pDC->MoveTo(X0,Y0-temp);
	pDC->LineTo(X1-100+(fabs(X1-X0)-100)/a[0].iSum,Y0-temp);
	temp+=ddy;
	}
	
	//绘制Y轴平行线
	double ddx=(fabs(X1-X0)-100)/a[0].iSum;
	double _temp;
	_temp=ddx;
	for(int t=0;t<a[0].iSum+1;t++)
	{
     
	//pDC->MoveTo(X0+_temp,Y0);
	//pDC->LineTo(X0+_temp,Y1+100-ddy*2);
	pDC->MoveTo(X0+_temp,Y0);
	pDC->LineTo(X0+_temp,Y0-10);
	_temp+=ddx;
	}

	//返回最大值最小值
	double max=Data[0];
	double min=Data[0];
	for (int i = 0; i <a[0].iSum; i++)
	{
     
		if(Data[i]>max)
		{
     
			max=Data[i];
		}
		if(Data[i]<min)
		{
     
			min=Data[i];
		}
	}
	//加刻度
	double ddd=(max-min)*0.1;
	for(int t=0;t<13;t++)
	{
     
		CString str;
		str.Format(_T("%.4f"),(min+ddd*(t-1)));
		int n;
		if(B==0) n=7;
		if(B==1) n=8;
		if(B==2) n=6;
		pDC->TextOut(X0-88,Y0-ddy*t-0.2*ddy,str,n);
	}
	for(int t=0;t<a[0].iSum+2;t++)
	{
     
		CString str;
		str.Format(_T("%d"),t);
		if(t<=9)
		{
     
		pDC->TextOut(X0+ddx*t,Y0+20,str,1);
		}
		else
		{
     
		pDC->TextOut(X0+ddx*t,Y0+20,str,2);
		}
	}
	//加文字
	CString name;
	CFont newFont;
	CFont *oldFont;
	newFont.CreateFont( 22,                                    //   字体的高度   
            13,                                          //   字体的宽度  
            0,                                          //  nEscapement 
            0,                                          //  nOrientation   
            FW_NORMAL,                                  //   nWeight   
            FALSE,                                      //   bItalic   
            FALSE,                                      //   bUnderline   
            0,                                                   //   cStrikeOut   
            ANSI_CHARSET,                             //   nCharSet   
            OUT_DEFAULT_PRECIS,                 //   nOutPrecision   
            CLIP_DEFAULT_PRECIS,               //   nClipPrecision   
            DEFAULT_QUALITY,                       //   nQuality   
            DEFAULT_PITCH   |   FF_SWISS,     //   nPitchAndFamily     
            _T("楷体"));
	oldFont=pDC->SelectObject(&newFont);//选择新字体
    pDC->SetTextColor(RGB(0,255,0));//设置字体颜色
	/*
    pDC->TextOut(10, 10, pDc->text); //输出
    pDC->SelectObject(oldFont);//选择回老字体
    newFont.DeleteObject();//删除新字体*/

	if(B==0) name="沿X方向图           ----张";
	if(B==1) name="沿Y方向图           ----张";
	if(B==2) name="沿H方向图           ----张";
	pDC->TextOut((X0+X1)/2-50,Y1-20,name,23);
	//绘制图像
	//CPen pen(PS_SOLID,2,RGB(0,1,0));
	pen.Detach();
	if(B==0) pen.CreatePen(0,2,RGB(200,0,0));
	if(B==1) pen.CreatePen(0,2,RGB(100,0,200));
	if(B==2) pen.CreatePen(0,2,RGB(100,200,50));
	pDC->SelectObject(&pen);
	for(int i=0;i<a[0].iSum-1;i++)
	{
     
	pDC->MoveTo(X0+ddx*(i+1),Y0-ddy-(Data[i]-min)*10*ddy/(max-min));
	pDC->LineTo(X0+ddx*(i+2),Y0-ddy-(Data[i+1]-min)*10*ddy/(max-min));
	}
	pen.DeleteObject();
	delete [] Data;
}


3.3.5文件: <RS_110_zhang_SY6View.cpp >  (只摘取部分)
/***************************************************************************
*  文件名:                              *
*                                                                          *
*  描述:单文档                                                             *
*                                                                          *
*  历史:**日期**         **理由**            **签名**                     *
*      2019年5月1日        创建              张                        *
*                                                                          *
*  外部过程:                                                              *
*                                                                          *
/**************************************************************************/
//全局
CSupport k;
CData *p;

void CRS_110_zhang_SY6View::OnFileOpen()
{
     
	// TODO: 在此添加命令处理程序代码
	p=k.read();//读取
}


void CRS_110_zhang_SY6View::On32771X()
{
     
	// TODO: 在此添加命令处理程序代码
	RedrawWindow(); //重绘窗口先
	CRect rect;//声明客户区矩形
	GetClientRect(rect);//获得客户区坐标
	k.Draw(p,GetDC(), rect,0); 
}


void CRS_110_zhang_SY6View::On32772Y()
{
     
	// TODO: 在此添加命令处理程序代码
	RedrawWindow(); //重绘窗口先
	CRect rect;//声明客户区矩形
	GetClientRect(rect);//获得客户区坐标
	k.Draw(p,GetDC(), rect,1); 
}


void CRS_110_zhang_SY6View::On32773H()
{
     
	// TODO: 在此添加命令处理程序代码
	RedrawWindow(); //重绘窗口先
	CRect rect;//声明客户区矩形
	GetClientRect(rect);//获得客户区坐标
	k.Draw(p,GetDC(), rect,2); 
}

3.4运行结果

测绘程序设计基础 实验6 CSU_第5张图片
测绘程序设计基础 实验6 CSU_第6张图片
测绘程序设计基础 实验6 CSU_第7张图片
matlab生成随机数的结果80个点考验程序鲁棒性:
测绘程序设计基础 实验6 CSU_第8张图片
测绘程序设计基础 实验6 CSU_第9张图片

3.5设计技巧:

 创建多个类,层次分明。
 使用指针动态开辟数组,较为方便
 使用文件操作
 使用单文档

代码虽多,不要贪杯~

你可能感兴趣的:(#,C++测绘程序设计基础,测绘程序设计基础,图形程序设计,中南大学,CSU,实验)