张亚宁,刘春光,吴诗帆
基于VC++的二维绘图程序设计
张亚宁,刘春光,吴诗帆
(91550部队,辽宁 大连 116023)
对工程数据进行绘图是数据分析中的一项重要内容,基于VC++开发环境从数据读取、选定坐标范围、绘制数据曲线等方面对二维数据绘图程序设计流程进行了详细描述,通过绘图实验验证了程序的正确性和科学性,具有一定的工程意义。
VC++;二维数据;测量设备;绘图软件
在工程实践中,对测量设备或传感器采集的数据进行实时显示、事后分析等工作较为普遍[1]。通过计算机绘制出的数据曲线走势对数据分析具有重要的意义。当前使用较广泛的绘图软件有AutoCAD、Solidworks、MATLAB、OriginPro等,经过多年的发展,以上绘图软件的功能较完善。在实际工程中,有时需要对数据进行较快速度的处理,或者需要与计算机硬件接口进行信息互换,此时,利用上述绘图软件处理不方便。Visual Studio C++是Microsoft公司推出的一款基于Windows平台、可视化的集成开发环境,在其平台下开发的程序具有效率高、占用内存低、与硬件接口衔接方便等特点[2-4]。基于此,本文利用VC++平台开发了二维数据绘图程序,并进行了数据绘图实验,实验证明了程序的可行性和科学性,具有一定的工程意义。
程序设计主要分为4部分,分别是:①获取数据;②选定坐标范围;③绘制坐标刻度及标注;④绘制数据曲线。程序各模块代码的实现如下。
获取数据是程序处理的源头,在工程中数据获取分为实时获取和事后获取。实时获取主要从计算机硬件接口获取,而事后获取可以从文本、表格等文件中获取。本文以从TXT文本文件获取数据为例进行程序设计:
因不同文件数据的行数列数一般不同,所以在定义数据存储数组前,需要先编写程序获取数据的行数和列数。同时,因为数组的维数一般用常量来定义,本程序选择动态分配空间的方式定义存储数据数组[*]。数据获取之后,通过循环语句按照行或列拆分数组,具体如下:
科学、合理地选择坐标范围具有重要的意义,数据范围过大或过小都将导致看图不便。本文根据数据(数据同理)的最大、最小值确定坐标范围,以数据为例程序处理如下:
x_max=max_double(x,N);//计算x的最大值x_max
x_min=min_double(x,N);//计算x的最小值x_min
x_abs_max=abs_max_double(x_max,x_min);//计算x绝对值的最大值
int x_power;//x_power为x的指数,例如:10^2
int xd_start;// xd_start为x轴的左侧
int xd_end;// xd_end为x轴的右侧
x_power=e_pow_double(xx_abs_max);//计算数值的10的幂次
xd_start=xx_min/pow(10,xx_power)-1;//左侧边界减少1
xd_end =xx_max/pow(10,xx_power)+1;//右侧边界增加1
坐标轴的范围确定之后,需要确定坐标轴在屏幕上的位置,即:
const int psc_left=400;//绘图左侧边界
const int psc_right=1000; //绘图右侧边界
const int psc_up=100; //绘图上侧边界
const int psc_down=400; //绘图下侧边界
确定完屏幕范围后,需要计算坐标范围和屏幕范围之间的变换系数,即单位长度的数据在屏幕上的长度,计算公式为=(psc_right-psc_left)/(xd_end-xd_start)//变换系数,=(psc_down-psc_up)/((-yd_start)-(-yd_end))//变换系数。
此处需要注意屏幕横向是从左向右,纵向是从上向下,所以在计算和两个变换系数时有所差异。
绘制坐标轴首先需要计算出原点(0,0)在屏幕上的位置(0,0),根据比例关系得到的公式为:
定好原点(0,0)后,调用MFC中的类CPen,进行画图,主要程序代码如下:
CPen zpen,cpen; //坐标轴zpen,坐标刻度cpen
zpen.CreatePen(PS_SOLID,3,RGB(0,0,0));
cpen.CreatePen(PS_SOLID,2,RGB(0,0,0));
pDC->SetViewportOrg(x0,y0);// 确定原点
pDC->SelectObject(&zpen);//pDC指向zpen,开始画坐标轴
pDC->MoveTo(xd_start*pow(10,x_power)*ex,0);
pDC->LineTo((xd_end)*pow(10,x_power)*ex,0);
pDC->MoveTo(0,-(yd_end)*pow(10,y_power)*ey);
pDC->LineTo(0,-yd_start*pow(10,y_power)*ey);
pDC->SelectObject(&cpen);//pDC指向cpen,开始画坐标刻度
CString sTemp;
for (i=xd_start;i<=xd_end;i++){//划大刻度
pDC->MoveTo(int(i*pow(10,x_power)*ex),0);
pDC->LineTo(int(i*pow(10,x_power)*ex),-8);
for (int j=1;(j<=4)&&(i pDC->MoveTo(int((i+j*0.2)*pow(10,x_power)*ex),0); pDC->LineTo(int((i+j*0.2)*pow(10,x_power)*ex),-4);} sTemp.Format("%d",i);//将数字“i”转换成字符“sTemp” pDC->TextOut(int(i*pow(10,xx_power)*ex-4),5,sTemp);} 轴刻度的画法与轴相同,此处不再赘述。 坐标轴和坐标刻度绘制完毕之后,最后对数据进行绘制,此处需要强调的是坐标轴的变换系数和数据的变换系数必须一致,即数据的变换系数也是,。 主要程序代码如下: CPen pen;定义数据曲线pen画笔 pen.CreatePen(PS_SOLID,3,RGB(255,0,0));//数据曲线特征 pDC->SelectObject(&pen);//pDC指向pen,开始画数据曲线 for( i=0;i<=N-1;i++){ pDC->MoveTo(int(x[i]*ex),int(-y[i]*ey)); pDC->LineTo(int(x[i]*ex),int(-y[i]*ey));} cpen.DeleteObject();//删除刻度画笔 zpen.DeleteObject(); //删除坐标画笔 pen.DeleteObject(); //删除数据画笔 程序完成后,选取两组工程数据依次在VC++和OriginPro环境下进行绘图实验,结果如图1和图2所示。 图1 数据曲线(VC++环境) 图2 数据曲线(OriginPro环境) 通过对比可以发现,本文设计的二维数据绘图程序绘图结果与OriginPro环境下的绘图结果是一致的,证明了本文设计程序的正确性。 本文通过在VC++环境下设计绘图程序,实现了高效、准确地对事后数据进行绘图处理,下一步将针对网络发送的实时数据进行实时绘图显示。 [1] 李杨,徐洁,王春海,等.VC++高效无闪烁绘制大数据量图形[J].电脑编程技巧与维护,2014(2):19-26 . [2]贾振华.VC++程序设计项目实践[M].北京:清华大学出版社,2010:36-128. [3]和清芳.计算机图形学原理及算法教程(Visual C++版)[M].2版.北京:清华大学出版社,2010:39-58. [4]王振武.计算机图形学基础[M].北京:清华大学出版社,2011:31-77. TP311 A 10.15913/j.cnki.kjycx.2019.17.020 2095-6835(2019)17-0048-02 张亚宁(1988—),男,硕士研究生,助理工程师,研究方向为数据融合及目标安全控制。 〔编辑:张思楠〕2.4 绘制数据曲线
3 实验验证
4 小结及展望