测绘程序设计(VS20xx)实验报告--图形程序设计

时间:2024.5.2

《测绘程序设计(VC.net)》

上机实验报告

(Visual C++.Net)

实验6 图形程序设计

班 级:   测 绘0803班         

学 号:   0405080702          

姓 名:    陈 琴 霞             

   序 号:                       

二零一零年四月

实验6 图形程序设计

一、实验目的

·         掌握VC++.net 坐标系和各项设置方法。

·         掌握GDI绘图方法。

·         理解交互式图形程序设计

二、实验内容

1.下列数据为一变形监测点的24期位移监测结果(分别为X,Y,H),编制程序绘制出该点的变形曲线图,每个方向一个位移序列图。

24

32.5801    -52.7876   0.1369

32.5786    -52.7892   0.1380

32.5784    -52.7845   0.1411

32.5812    -52.7852   0.1393

32.5782    -52.7863   0.1394

32.5791    -52.7852   0.1354

32.5788    -52.7841   0.1414

32.5788    -52.7817   0.1375

32.5745    -52.7833   0.1359

32.5815    -52.7854   0.1327

32.5822    -52.7841   0.1358

32.5839    -52.7826   0.1361

32.5820    -52.7852   0.1339

32.5800    -52.7863   0.1325

32.5792    -52.7845   0.1416

32.5807    -52.7834   0.1395

32.5778    -52.7846   0.1412

32.5792    -52.7843   0.1371

32.5794    -52.7833   0.1406

32.5806    -52.7841   0.1411

32.5800    -52.7863   0.1380

32.5785    -52.7840   0.1368

32.5811    -52.7848   0.1412

32.5828    -52.7863   0.1356

设计思路:

1)  自定义绘图的类,包括:逐行分割函数,数据读取函数,绘图的函数

2)  各函数的实现。

数据读取函数:打开观测数据,将三个方向的形变值,分别赋给X,Y,H三个动态数组。

绘图的函数:首先获得绘图区域,按比例绘制坐标网格,绘制坐标网格时,先确定四个顶点的坐标,剩下的就简单了。

            我把三个方向的形变绘在了一个表格中,因此纵坐标有X,Y,H三种刻度,它们的形变曲线分别蓝、绿、红三种颜色表示。

主要代码

     文件一  DrawGraph.h

                #pragma once

class DrawGraph

{

public:

     DrawGraph(void);

     ~DrawGraph(void);

public:

     CString *SplitString(CString str, char split, int& iSubStrs);

     void ReadData(double *&X,double *&Y,double *&H);

     void Draw(CDC* pDC, CRect& rect);

    

};

文件二  DrawGraph.cpp

            #include "StdAfx.h"

#include "DrawGraph.h"

#include <locale.h>

DrawGraph::DrawGraph(void)

{

}

DrawGraph::~DrawGraph(void)

{

}

CString *DrawGraph::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;

}

void DrawGraph::ReadData(double *&X,double *&Y,double *&H)

{

     CFileDialog dlgFile(TRUE,_T("gmss.txt"),NULL,

         OFN_ALLOWMULTISELECT|OFN_EXPLORER,

         _T("(文本文件)|*.txt"));

     if(dlgFile.DoModal()==IDCANCEL) return;

     CString strFileName=dlgFile.GetPathName();

     setlocale(LC_ALL,"");

     CStdioFile sf;

     if(!sf.Open(strFileName, CFile::modeRead)) return;

     CString strLine;

     CString strData;

     strData.Empty();

     BOOL bEOF=sf.ReadString(strLine);

     while(bEOF)

     {

         strData+=strLine;

        

         bEOF=sf.ReadString(strLine);

         if(bEOF) strData+=_T("\r\n");

     }

     sf.Close();

     int iLine;

     //分行并存入字符串数组

     CString *pstrLine=SplitString(strData,'\n',iLine);

     if(iLine<2)

     {

         throw(_T("输入的数据不完整!"));

         return;

     }   

     int iTotalPoint = _ttoi(pstrLine[0]); //测量点数

    

     CString *strTmp=NULL;

     int n;

     X=new double[iTotalPoint];

     Y=new double[iTotalPoint];

     H=new double[iTotalPoint];

     //逐行用Split函数分离,获得三个方向的形变值

     for(int i=0;i<iTotalPoint;i++)

     {

         strTmp = SplitString(pstrLine[i+1], ',',n);

         X[i]=_tstof(strTmp[0]);

         Y[i]=_tstof(strTmp[1]);

         H[i]=_tstof(strTmp[2]);

        

         if(strTmp!=NULL)//释放内存

         {

              delete[] strTmp;

              strTmp=NULL;

         }

     }

     if(strTmp!=NULL)//释放内存

     {

         delete[] strTmp;

         strTmp=NULL;

     }

}

void DrawGraph::Draw(CDC* pDC, CRect& rect)

{

    

      CPen pen(PS_SOLID,2,RGB(0,0,0));

      CPen* pOldPen=pDC->SelectObject(&pen);

      pDC->Rectangle(rect);

      int dOrgX,dOrgY;

      int dEndX,dEndY;

      dOrgX=rect.left+int(0.2*rect.Width());

     dOrgY=rect.bottom-int(0.2*rect.Height());

      dEndX=rect.right-int(0.1*rect.Width());

      dEndY=rect.top+int(0.2*rect.Height());

      pDC->MoveTo(dOrgX,dOrgY);

      pDC->LineTo(dEndX,dOrgY);//横轴

      pDC->MoveTo(dOrgX,dOrgY);

      pDC->LineTo(dOrgX,dEndY);//纵轴

      int dx,dy;

      dy=(dOrgY-dEndY)/3;

      dx=(dEndX-dOrgX)/24;

      //绘制水平线

      for(int i=0;i<3;i++)

      {

          pDC->MoveTo(dOrgX,dEndY+i*dy);

          pDC->LineTo(dEndX,dEndY+i*dy);

      }

      pDC->SelectObject(pOldPen);

      

      LOGFONT lf;

       memset(&lf, 0, sizeof(LOGFONT));

        // request a 16-pixel-height font

        lf.lfHeight = 16;

        // request a face name "Arial".

        _tcsncpy_s(lf.lfFaceName, LF_FACESIZE, _T("宋体"), 4);

      CFont font;//创建字体

     font.CreateFontIndirect(&lf);

      CFont* pOldFont=pDC->SelectObject(&font);

      CString str;

      //绘制时间刻度

      for(int i=1;i<=24;i++)

      {

          pDC->MoveTo(dx*i+dOrgX,dOrgY);

          pDC->LineTo(dx*i+dOrgX,dOrgY - 5);

          str.Format(_T("%d"),i);

          if(i!=0)

              {   

                   pDC->TextOut(dx*i+dOrgX,

                        dOrgY + 10,str);

              }

      }

      pDC->TextOut(dOrgX+400,dOrgY+30,

         _T("时间"));

      pDC->TextOut(dOrgX+300,dEndY-50,

         _T("蓝:X方向 绿:Y方向 红:H方向"));

     pDC->SelectObject(pOldFont);

     font.DeleteObject();

     //绘制坐标X,Y,H刻度

     CFont fontA;//创建坐标字体

     fontA.CreateFontIndirect(&lf);

     //CFont* pOldFont=pDC->SelectObject(&fontA);

    pDC->TextOut(dOrgX-60,dEndY-30,

                       _T("X"),1);

    pDC->TextOut(dOrgX-120,dEndY-30,

                       _T("Y"),1);

         pDC->TextOut(dOrgX-180,dEndY-30,

                       _T("H"),1);

    pDC->SelectObject(pOldFont);

     for(int i=0;i<=3;i++)

     {

         str.Format(_T("%.3f"),32.585-0.005*i);

         pDC->TextOut(dOrgX-60,dEndY+i*dy,

              str);

     }

     for(int i=0;i<=3;i++)

     {

         str.Format(_T("%.3f"),-52.78-0.005*i);

         pDC->TextOut(dOrgX-120,dEndY+i*dy,

              str);

     }

     for(int i=0;i<=3;i++)

     {

         str.Format(_T("%.3f"),0.145-0.005*i);

         pDC->TextOut(dOrgX-180,dEndY+i*dy,

              str);

     }

    

    fontA.DeleteObject();

     //调用数据读取函数,获得形变数据

     double *X=NULL;

     double *Y=NULL;

     double *H=NULL;

     ReadData(X,Y,H);  

     //创建蓝色画笔

     CPen penBlue;     

     penBlue.CreatePen( PS_SOLID, 2, RGB(0,0,255));

     pDC->SelectObject(penBlue);

     POINT ptX[256];   //定义点结构体变量

     for(int i=0;i<24;i++)   //实际坐标与屏幕坐标的转化

     {

         ptX[i].x=dOrgX+i*dx;

         ptX[i].y=dOrgY-int((X[i]-32.57)/0.015*3*dy);

     }

     pDC->Polyline(ptX,24);   //绘制X方向变形曲线

     // 恢复原来绘图属性

     pDC->SelectObject(pOldPen);

     penBlue.DeleteObject();

     //创建绿色画笔绘制Y方向变形曲线

     CPen penGreen;    

     penGreen.CreatePen( PS_SOLID, 2, RGB(0,255,0));

     pDC->SelectObject(penGreen);

     POINT ptY[256];

     for(int i=0;i<24;i++)   

     {

         ptY[i].x=dOrgX+i*dx;

         ptY[i].y=dOrgY-int((Y[i]+52.795)/0.015*3*dy);

     }

     pDC->Polyline(ptY,24);

     // 恢复原来绘图属性

     pDC->SelectObject(pOldPen);

     penGreen.DeleteObject();

     //创建红色画笔绘制H方向变形曲线

     CPen penRed;

     penRed.CreatePen( PS_SOLID, 2, RGB(255,0,0));

     pDC->SelectObject(penRed);

     POINT ptH[256];

     for(int i=0;i<24;i++)

     {

         ptH[i].x=dOrgX+i*dx;

         ptH[i].y=dOrgY-int((H[i]-0.13)/0.015*3*dy);

     }

     pDC->Polyline(ptH,24);

     // 恢复原来绘图属性

     pDC->SelectObject(pOldPen);

     penRed.DeleteObject();

    

        

}

文件三  TranGraphView.cpp

                void CTranGraphView::OnDraw(CDC *pDC)

{

  CTranGraphDoc* pDoc = GetDocument();

  ASSERT_VALID(pDoc);

  if (!pDoc)

       return;

  // TODO: 在此处为本机数据添加绘制代码

  CRect rect;

  GetClientRect(&rect);

  DrawGraph drawGraph;

  drawGraph.Draw(pDC,rect);

}

运行结果:


总  结

这次实验是图形的绘制,比较麻烦,内容很多,既要打开文件读取数据,又要绘制坐标轴,坐标刻度,还要对坐标进行转化。虽然老师都给了我们相关的例题,但将它们完美地融合在一起却不简单。正所谓程序越复杂,实现的方法也就越多,遇到的问题也更加稀奇古怪了。如何更好的实现实验要求也得更加仔细思考了。

本实验需要绘制三个方向的型变量,如何去表示就是一个问题了,首先我是想在视图窗口中并列绘制三个坐标网格,但这样有很麻烦。后来一想干脆画在一个格网中,用三种不同颜色分开表示就好了,各形变之间还可对比。

这已经是第六个实验了,也学了编程的知识,虽然有的函数,代码我知道它是什么功能,我会用,但却不是很理解,将所学进行改编融合这方面我还是很欠缺的。

这个程序虽然是写完了,结果也运行出来了,但我知道它是写的很糟糕的,类只是函数的堆砌,完全算不上真正的类,运行也存在很大的问题。刚开始编译时还有好多错误,多编译几次竟然就通过了,但是通过之后有时是弹出两个或多个打开文件的对话框,有时是一个,往往还伴随着黑屏。我想应该是数据读取的函数调用有问题,具体是什么原因还不是很清楚,明天上午再去请教同学吧。

我害怕一调试就大片错误,因此写一点就调试一下,可这个程序貌似调试挺麻烦的,占用时间很长,而且不知道是怎么回事,一调试通过,电脑就会自动黑屏,几秒钟之后恢复,运行界面也跟着出来了,不知是不是电脑哪部分出故障了呢?

对各函数的功能还是多理解。

更多相关推荐:
C++程序设计实验报告

C++程序设计实验报告学号:姓名:班级:指导老师:实验一、字符和格式的输出实验一,实验目的1、重点把握各种内部数据类型、数值和逻辑运算,各种表达式、函数声明、定义和调用。2、掌握过程控制编程方法,正确编制多重循…

程序设计实验报告模板

C语言程序设计实验报告1实验目的(1)掌握函数的定义方法、调用方法、参数说明以及返回值;(2)掌握实参与形参的对应关系,以及参数之间的值传递的方式;(3)掌握函数的嵌套调用及递归调用的设计方法;(4)在编程过程…

Java程序设计实验报告

学生实验报告册(理工类)课程名称:JAVA程序设计实验专业班级:M11计算机科学与技术II学生学号:学生姓名:所属院部:XX学院指导教师:20XX20XX学年第二学期金陵科技学院教务处制实验报告书写要求实验报告…

程序设计综合实验报告册

西南交通大学程序设计综合实验实验地点实验学期学生班级学生学号学生姓名任课教师龚勋信息科学与技术学院20xx年4月实验一ATM机用户操作界面业务逻辑编写实验目的及内容1根据ATM的工作流程编写用户界面掌握文本用户...

C程序设计实验报告

C语言程序设计实验报告学号不告诉你哦班级信管一班姓名你猜猜哈哈一实验题目一编程实验猜数问题输入两个整数并求这两个整数的和输入所猜的结果如果输入数比正确的结果要大提示猜大了如果输入数比正确的结果要小提示猜小了当猜...

C程序设计实验报告5

工学院工业设计专业10级20xx至20xx学年度第1学期学号2104021638姓名杨芹芹20xx年9月22日第34节综合楼325教室

C程序设计实验报告2

院专业20xx级20xx至20xx学年度第1学期学号姓名20xx年9月22日第34节综合楼325教室

《高级语言程序设计》实验报告(必看)

高级语言程序设计实验报告

c++程序设计实验报告实验一

C实验报告课程名称C程序设计成绩评定实验项目名称几何形体练习1指导教师实验项目编号1实验项目类型实验地点学生姓名学号学院计算机与信息工程学院专业计算机科学与技术实验时间20xx年11月26日一实验目的熟悉掌握类...

C++程序设计实验报告

C实验报告实验一1实验要求1编写一个函数把华氏温度转换为摄氏温度转换公式如下CF32592编写重载函数Max1可分别求两个整数三个整数两个双精度数三个双精度数的最大值3使用系统函数powxy计算xy的值注意包含...

C程序设计实验报告3-

院专业20xx级20xx至20xx学年度第1学期学号姓名20xx年10月8日第34节综合楼325教室

C++描述程序设计实验报告

《程序设计基础》实验报告实验一面向过程的简单程序设计1.实验目的掌握C++语言的数据类型(包括对各种数据类型变量的定义、初始化、赋值等)、运算符和表达式的使用。掌握赋值语句的使用。掌握数据的输入输出方法。2.实…

程序设计实验报告(37篇)