VC中矢量圖形快速重畫的技巧
行業科技
作者:宋菲
【摘要】本文介紹了VC6.0用OnDraw()函數對視圖進行重畫的原理,並提出了一種通過圖形元素的邊界矩形對矢量圖形快速重畫的方法。
【關鍵詞】矢量,邊界矩形,OnDraw()函數
我們用VC6.0開發環境對小型矢量圖形係統進行開發。在圖形放大、縮小、刪除、添加圖形元素、重畫上屏等操作時,要不斷地對圖形進行重畫。雖然計算機運行速度越來越快,但對一個複雜的矢量圖形來說,圖形顯示一次也要花費大量時間。尤其對於繪圖函數,即使是畫一條直線的LineTo函數都要花費大量時間計算出應該顯示的像素位置,才能實現對每個像素的顯示。所以在開發矢量圖形軟件時應盡可能采取好的算法提高圖形的重畫速度。
一、激活視圖重畫的基本方法
所謂圖形重畫,就是把當前視圖屏幕重新繪製一次,也就是讓視圖類的OnDraw(CDC* pDC)函數重新執行一次。OnDraw函數是被Cview類的消息處理函數OnPaint調用的。在MFC中OnPaint函數的實現代碼如下:
void Cview:: OnPaint()
{ CpaintDC dc(this);
OnPrepareDC(&dc);
OnDraw(&dc);
}
OnPaint函數是窗口消息WM_PAINT的消息處理函數,WM_PAINT的消息處理函數是當窗口失效或完整性受到破壞時發出的一個窗口消息。要使視圖屏幕重新繪製就要激活視圖的繪製機製,有兩種方法可實現這個功能:
1、在視圖類函數的實現代碼中,加入以下代碼來激活重畫機製:
CDrawDoc *pDoc=GetDocument();
pDoc->UpdateAllViews(this);
UpdateAllViews函數使屬於當前文檔對象的所有視圖屏幕客戶區失效重畫。如果應用程序采用單文檔結構,此時係統隻有一個視圖,執行此命令時激發視圖類的OnDraw函數重新執行來完成重畫。如果應用程序采用多文檔結構,一個文檔具有多個視圖,UpdateAllViews函數可使屬於當前文檔對象的所有視圖都重新繪製。
2、加入Invalidate()函數使當前視圖屏幕客戶區失效從而激活圖形重畫。Invalidate函數與UpdateAllViews函數的不同點是前者隻能使當前視圖重畫而與其同文檔的其他視圖並不重畫。
二、提高圖形重畫速度的基本算法
因為矢量圖形具有無極放縮的功能,一般情況下並不是所有圖形元素都能夠顯示到屏幕上(除非在顯示全圖狀態),而上述的圖形重畫機製是把所有圖形元素不管在屏幕內還是在屏幕外都進行了繪製。為解決這個問題,一個基本的方法就是在顯示一個圖形前對每個圖形元素進行判斷,看這個圖形元素是否在視圖屏幕中,如果不在當前視圖屏幕中就不對這個圖形元素進行繪製來節省繪製時間。我們通過判斷圖形元素當前視圖屏幕矩形是否相交來判斷圖形元素是否在視圖屏幕中。一般采用這個圖形元素的邊界矩形和視圖屏幕邊界矩形是否相交的方法。
三、提高圖形重畫速度的程序實現
1、得到視圖屏幕邊界矩形坐標
我們為這個應用程序命名為Draw。通過以上分析我們首先要得到視圖屏幕邊界矩形坐標。這裏我們定義四個全局浮點變量xMinScreen,yMixScreen,xMaxScreen,yMaxScreen來傳遞繪製視圖的左下角和右上角的實際坐標。這四個全局變量在每次調用OnDraw函數實現視圖的繪製前被初始化。在繪製函數CDrawView::OnDraw(CDC* pDC)中加入代碼實現在每次繪製前得到視圖屏幕邊界的實際坐標:
void CDrawView::OnDraw(CDC* pDC)
{
CDrawDoc* pDoc = GetDocument();
ASSERT_VALID(pDoc);
xMixScreen=xStart; //(xStart,yStart)為圖形屏幕坐下角點的實際坐標