張亞寧,劉春光,吳詩帆
基于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 小結及展望