




版權說明:本文檔由用戶提供并上傳,收益歸屬內容提供方,若內容存在侵權,請進行舉報或認領
文檔簡介
1、第二章 直線掃描轉換算法n1.光柵圖形學n2.逐點畫線算法n3.DDA畫線算法n4.BRESENHAM畫線算法n5.關于線寬線型n6.Visual C+中基本繪圖函數 2.1 光柵圖形學n計算機圖形學已成為計算機技術中發展最快的領域,計算機圖形軟件也相應得到快速發展。計算機繪圖顯示有屏幕顯示、打印機打印圖樣和繪圖機輸出圖樣等方式,其中用屏幕顯示圖樣是計算機繪圖的重要內容。n計算機上常見的顯示器為光柵圖形顯示器,光柵圖形顯示器可以看作像素的矩陣。像素是組成圖形的基本元素,一般稱為“點”。通過點亮一些像素,滅掉另一些像素,即在屏幕上產生圖形。在光柵顯示器上顯示任何一種圖形必須在顯示器的相 應像素點
2、上畫上所需顏色,即具有一種或多種顏色的像素集合構成圖形。確定最佳接近圖形的像素集合,并用指定屬性寫像素的過程稱為圖形的掃描轉換或光柵化。對于一維圖形,在不考慮線寬時,用一個像素寬的直、曲線來顯示圖形。二維圖形的光柵化必須確定區域對應的像素集,并用指定的屬性或圖案進行顯示,即區域 填充。n什么是光柵圖形學? 光柵顯示器 圖形光柵化、 光柵化圖形的處理n光柵顯示器上顯示的圖形,稱之為光柵圖形。光柵顯示器可以看作是一個象素矩陣,在光柵顯示器上顯示的任何一個圖形,實際上都是一些具有一種或多種顏色和灰度象素的集合。由于對一個具體的光柵顯示器來說,象素個數是有限的,象素的顏色和灰度等級也是有限的,象素是有
3、大小的,所以光柵圖形只是近似的實際圖形。如何使光柵圖形最完美地逼近實際圖形,便是光柵圖形學要研究的內容。以后,我們提到“顯示器”時,如未特別聲明,均指光柵顯示器。 光柵圖形學算法特點n1.要充分考慮屏幕像素,光柵的特性,如何逼近真實圖形,如何減小這個誤差,如何提高圖形處理速度是圖形學算法的追求。n2.編寫計算機圖形學算法,最好還要具備計算方法的基礎知識,了解計算機是如何求解方程,了解求解過程與實際人思維的不同,也就是把人思維的計算方法翻譯到機器,這就是計算方法研究的內容。光柵圖形學的研究內容直線段的掃描轉換算法圓弧的掃描轉換算法多邊形的掃描轉換與區域填充字符裁剪反走樣消隱n直線段是最基本的圖形
4、,因此直線段生成的質量好壞與速度快慢將直接影響整個圖形生成的質量和速度。所以直線段生成算法在圖形軟件設計中起著關鍵的作用。n如果已知屏幕中直線段的二個端點,可以有多種不同的數學方法來決定應改變在二端點之間的哪些像素的亮度值才能顯示出二點間的直線,生成直線段的算法之間區別主要是判別和生成x,y增量過程和方法不同,所能適應的設備環境也不同。下面介紹三種基本的畫線算法。光柵圖形中點的表示(x,y)坐標地址線性表地址線性表1D表示顯示屏幕顯示屏幕2D表示像素由其左下角坐標表示像素由其左下角坐標表示光柵圖形中點的表示xyxmaxxminymaxymin地址地址 = (xmax-xmin) * (y-ym
5、in) + (x-xmin) + 基地址基地址每行像素點數每行像素點數行數行數行中位置行中位置n在光柵顯示器的熒光屏上生成一個對象,實質上是往幀緩存寄存器的相應單元中填入數據。畫一條從(x1, y1)到(x2, y2)的直線,實質上是一個發現最佳逼近直線的象素序列,并填入色彩數據的過程。這個過程也稱為直線光柵化。 直線掃描轉換的本質n直線的掃描轉換確定最佳逼近于該直線的一組象素按掃描線順序,對這些象素進行寫操作,對一維圖形,不考慮線寬,則用一個像素寬的直線來顯示圖形。任何圖形的光柵化,必須顯示在一個窗口內,否則不予顯示。即確定一個圖形的哪些部分在窗口內,哪些在窗口外,即裁剪。n圖形顯示前需要:
6、掃描轉換+裁剪n裁剪-掃描轉換:最常用,節約計算時間。n掃描轉換-裁剪:算法簡單;2.2 逐點畫線算法n在數學上,理想的直線是沒有寬度在數學上,理想的直線是沒有寬度的,由無數個點構成的集合。當我的,由無數個點構成的集合。當我們對直線進行光柵化時,只能在顯們對直線進行光柵化時,只能在顯示器所給定的有限個像素中,確定示器所給定的有限個像素中,確定最佳逼近于該直線的一組像素。用最佳逼近于該直線的一組像素。用寫點方式對像素進行寫操作,這就寫點方式對像素進行寫操作,這就是通常所說的用顯示器繪制直線,是通常所說的用顯示器繪制直線,或直線的掃描轉換或直線的掃描轉換 逐點畫線算法(1/19)n逐點比較法算法的
7、基本思想是:在繪制直線的過程中,每繪制一個點就與原直線進行比較,根據比較的結果決定下一步的走向,這樣一步一步逼近直線,逐點比較法的執行過程如下:偏差判別開始X方向移動終點判別是結束偏差計算否Y方向移動逐點畫線算法(2/19)n逐點比較法是針對筆式繪圖機提出的。根據繪圖機的結構原理及數字控制原理, 繪圖機的筆架可能的移動方向(稱為走步方向)有八個:+X、 -X、+Y、-Y、+X+Y、-X+Y、-X-Y、+X-Y。 其中+X、-X、+Y、-Y四個走步方向是一般繪圖機都提供的,稱為基本走步方向。可見,繪圖機的基本繪圖元素是與走步方向相對應的小直線段。繪圖機所畫的一般直線和曲線,實際上是由許多小直線段
8、所組成的折線來逼近的。逐點畫線算法(3/19) 根據所畫圖線的已知條件(如直線兩個端點坐標等)計算畫圖所需要的一系列中間點(即折線的端點)的坐標,稱為插補運算。插補運算可用軟件或硬件實現,不少繪圖機采用插補器(或稱線發生器、弧發生器)來完成插補運算,目的在于提高圖線生成速度。逐點比較法可用于插補運算。 逐點畫線算法(4/19)逐點畫線算法(5/19)n若畫第一象限的直線OA,如上頁圖所示,起點為O(0,0), 終點為A(xa, ya),設繪圖筆當前的位置為K(xk,yk),這里坐標均為局部坐標。點K相對于直線OA的位置有三種情況:點K在OA上方,點K在OA上以及點K在OA下方。為判斷點K與OA
9、的相對位置,引入偏差函數F(k)。 nF(k)=x(a)y(k)-x(k)y(a)當K在OA上時,F(k)=0; K在OA上方時,F(k)0; K在OA下方時,F(k)0。 逐點畫線算法(6/19)n對第一象限內直線的生成規定如下:n 當F(k)0時,繪圖筆從當前位置沿+X方向走一步,記作+x; 當F(k)0時,繪圖筆從當前位置沿+Y方向走一步,記作+y;在繪圖筆到達新的位置時,應計算出新位置的偏差,為判斷繪圖筆下一步走向作準備。n 繪圖筆走+x時,新點坐標為nX(k+1)=x(k)+1, y(k+1)=y(k)n這時新點偏差為nF(k+1)=x(a)y(k+1)-x(k+1)y(a)=x(a
10、)y(k)-x(k)y(a)-y(a)=F(k)-y(a)逐點畫線算法(7/19)n繪圖筆走+y時,新點坐標為nX(k+1)=xk, y(k+1)=y(k)+1n這時新點偏差為nF(k+1)=x(a)y(k+1)-x(k+1)y(a)=x(a)y(k)+x(a)-x(k)y(a)=F(k)+x(a) 根據新偏差F(k+1)的正、負號再確定繪圖筆的下一步走向,這樣逐步進行,直到繪圖筆到達直線的終點為止。終點判斷可由X及Y向總走步數J(J=|x(a)|+|y(a)|)來控制,每走一步J減去1,當J=0 時即到達終點。 逐點畫線算法(8/19)n對其他象限內直線段生成計算走步方向的規定如下圖所示。偏
11、差的遞推計算均按以下兩式進行:n 當沿X方向走步時, F(k+1)=F(k)-|y(a)|;n 當沿Y方向走步時,F(k+1)=F(k)+|x(a)|。 XYFk0Fk0Fk0Fk0Fk0Fk0Fk0Fk0O逐點畫線算法(9/19)01234512LINE(0,0)TO(5,2) 畫點 (0,0)F(0)=0 (1,0)F(1)0 (2,1)F(3)0 (3,1)F(4)0 (4,2)F(6)0 (5,2)逐點畫線算法(10/19)n優點: 整個算法實現可以使用整數,沒有使用浮點數運算,沒有乘除運算,所以適合硬件實現,大多數繪圖儀使用這個算法。n缺點: 逐點畫線法一次只能位移一步,所以畫出來的
12、直線粗細不均勻。逐點畫線算法(11/19)n逐點畫線算法VC源代碼(不包含交互內容,直接內置畫線段的起始點,并且沒有實現F(k)計算的遞推工作)nvoid CMyView:OnPointline() n n CDC *pDC=GetDC();nCOLORREF color=RGB(255,0,0);/ 前面四句就是設備環境,當然表現形式可以不一樣逐點畫線算法(12/19)n int a1=30;n int b1=30;n int b2=800;n int a2=600; /我們實現最簡單的畫線算法,二點已經確定/后面我們再講如何交互n int x1,y1,x2,y2; /起始點坐標n int
13、itype; /畫線不同循環類型n int i;n int xx,yy;逐點畫線算法(13/19)nif (a1a2&b1a2&b1b2)n n n x1=a2;n y1=b2;n x2=a1;n y2=b1;n itype=1;n 逐點畫線算法(14/19)nif (a1b2)n n x1=a1;n y1=b1;n x2=a2;n y2=b2;n itype=2;n n if (a1a2&b1b2)n n x1=a2;n y1=b2;n x2=a1;n y2=b1;n itype=2;n 逐點畫線算法(15/19)n/前面的代碼具有我自己的風格,因為VC的工作區坐標的特性,我們分析以后,畫線
14、存在二個類型,即把理論中的分四個象限畫線情況歸結為二類,畫線起點和始點我們靈活變化一下,簡化編程。nint k=abs(x2-x1)+abs(y2-y1); / 書上的終點判別不是這么求的 xx=x1; n yy=y1; n switch (itype)n 逐點畫線算法(16/19)ncase 1 :n n xx=x1; n yy=y1; n for (i=0;iSetPixel(xx,yy,color); n if (x2-x1)*(yy-y1)-(xx-x1)*(y2-y1)=0)n xx=xx+1; n elsen yy=yy+1; n n return;逐點畫線算法(17/19)nca
15、se 2 :n nxx=x1; n yy=y1; nfor (i=0;iSetPixel(xx,yy,color);n if (x2-x1)*(y1-yy)-(xx-x1)*(y1-y2)=0)n xx=xx+1; n elsen yy=yy-1; n nnreturn; n nn注意:從一個理論上的算法提煉到具體一個編譯器可以運行編譯的程序,可能會有多種不同的編寫程序方法,但執行效果是一樣的,都能體現算法的精髓。 上面的逐點畫線算法沒有實現計算誤差中 F(K)的遞推工作,效率可能會低點,同學們可以考慮把這個可執行無誤算法改進一下。 優秀的程序不僅要求無誤執行,還要有良好的性能,茁壯性(出錯處
16、理好)等要求。逐點畫線算法(18/19)n 上面這個程序還有些bug,那就是不能繪制水平或豎直的直線,還有未能實現F(k)的遞推工作,這些留給同學們去做,可以在程序中加入一些代碼來解決這個問題。同學們還可以根據自己對算法的理解重新編寫代碼,不用和我編寫的思路一樣。比如實現四象限方向畫圖,判斷F(k)的正負,如果為正,分四種象限情況走步,如果為負,分四種象限情況走步。逐點畫線算法(19/19)逐點法編程另一個思路n坐標變換的思想 坐標變換的思想對后面的曲線曲面編程很有幫助 根據一開始上課推導的最簡單的逐點法繪制直線,從第一象限原點出發到第一象限的一個點得到的算法,利用坐標變換來把其他的相當于其他
17、象限的直線繪制映射到第一象限的最簡直線繪制中來。void CMyView:OnLine1() CDC *pDC=GetDC();COLORREF color=RGB(255,0,0);int x1=0,y1=0;int x2=500,y2=200;int i;int f=0; int x=x1,y=y1;最簡第一象限逐點法繪制源碼 pDC-SetPixel(x1,y1,color); int k=abs(x2-x1)+abs(y2-y1); for (i=0;i0) y=y+1; f=f-x2; pDC-SetPixel(x,y,color);else x=x+1; f=f+y2; pDC-S
18、etPixel(x,y,color); 最簡第一象限逐點法繪制源碼 CDC *pDC=GetDC(); COLORREF color=RGB(255,0,0); int a1=3; int b1=3; int b2=800; int a2=600; int x1,y1,x2,y2; /起始點坐標 int itype; /畫線不同循環類型 int i; int f1=0; int f2=0; int k=abs(a2-a1)+abs(b2-b1);坐標變換映射逐點法繪制源碼 if (a1a2&b1a2&b1b2) x1=a1; y1=b1; x2=abs(a1-a2); y2=abs(b1-b2
19、); itype=1; 坐標變換映射逐點法繪制源碼 if (a1b2) x1=a1; y1=b1; x2=abs(a1-a2); y2=abs(b1-b2); itype=2; if (a1a2&b1SetPixel(x1,y1,color);坐標變換映射逐點法繪制源碼 switch (itype) case 1 : for (i=0;i0) y=y+1; f1=f1-x2; pDC-SetPixel(x1-x,y1-y,color); else x=x+1; f1=f1+y2; pDC-SetPixel(x1-x,y1-y,color); break;坐標變換映射逐點法繪制源碼 case 2
20、 : for (i=0;i0) yy=yy+1; f2=f2-x2; pDC-SetPixel(x1+xx,y1-yy,color); else xx=xx+1; f2=f2+y2; pDC-SetPixel(x1+xx,y1-yy,color); return; (本程序也沒考慮水平豎直線)坐標變換映射逐點法繪制源碼n數值微分法(Digital Differential Analyzer)是一種基于直線微分方程來生成直線的方法。n回顧一下數值微分的幾何意義,一階數值微分反應的是變化率,表達瞬時變化趨勢和快慢的量。2.3 DDA畫線算法 DDA畫線算法(1/14)n已知線段端點:P0(x0,y
21、0), P1(x1,y1)n直線方程 y=kx+b (xi, yi), i=0,.n.n浮點數取整 : yi=round(yi)=(int)(yi+0.5)用到浮點數的乘法、加法和取整運算 DDA畫線算法(2/14)n增量算法yi+1=kxi+1+b=k(xi+1)+b=yi+k(xi,yi)(xi+1,yi+k)n缺點:有浮點數取整運算不利于硬件實現效率低僅適用于k 1的情形:x每增加1,y最多增加1。當 k 1時,必須把x,y互換。 DDA畫線算法(3/14)n思考:如何改進算法更適合于編程實現呢?n基本思想用數值方法解微分方程 dy/dt = xdy/dt = y xn+1 = xn +
22、 x yn+1 = yn + y 如何選取如何選?。?DDA畫線算法(4/14)n對稱的DDA取=2-n使 2n-1max(|x |,|y|)2nn簡單的DDA取= 1/max(|x |,|y|)使 |x |, |y|中必有一個是單位步長x為最大時, x =1, x =ky為最大時, y =1, y =1/k 簡單DDA法是按x, y絕對值較大的方向走步的,在這個方向上,每步走一個像素,然后再確定另一個方向的走步。 簡單DDA法生成直線的精度同對稱DDA法,但它在求一個點時要做兩次除法以決定坐標增量值。簡單DDA法不適合硬件實現,只適合于軟件處理。 DDA畫線算法(5/14)n【例】用對稱DD
23、A法在起點A(2,1)和終點B(12,7)之間生成一段直線。n 求解的第一步是計算初值x, y, n。這里x=10, y=6, n=4。n 第二步按遞推公式循環計算點的坐標,并取整顯示。表是本例的循環計算過程。 圖是其屏幕顯示結果。DDA畫線算法(6/14)DDA畫線算法(7/14)DDA畫線算法(8/14)AB753124681012 對稱DDA法生成的直線比較精確,像點位置偏離直線不超過半個像素。邏輯上也比較簡單,用 2 的負指數冪作為,意味著把存放x和y的寄存器通過移位操作就可得到點與點之間的坐標增量x、y,而不用除法計算,計算直線上每一點只用兩次加法即可實現。對稱DDA法適合用硬件來實
24、現, 當然也可用軟件來實現。 DDA畫線算法(9/14)DDA畫線算法(10/14)n/簡單的DDA畫線算法,繪制線段的起始點也是內置的,沒有加入交互過程。這是DDA的基本算法,希望同學們好好體會算法,從理論上的算法到具體程序的過程。nvoid CMyView:OnDdaline() nnCDC *pDC=GetDC();nCOLORREF color=RGB(255,0,0);n/設備環境DDA畫線算法(11/14)n int x1=30;n int y1=600;n int x2=180;n int y2=200;n int i;n float xincrement,yincrement,
25、xx,yy;n int k=abs(x2-x1);n if(abs(y2-y1)k) k=abs(y2-y1);n xincrement=(float)(x2-x1)/k;n yincrement=(float)(y2-y1)/k;DDA畫線算法(12/14)n xx=(x1+0.5);n yy=(y1+0.5);n/為什么加0.5?因為我們對像素要取整,xx本為浮點數,但后面繪制圖形時候要取整n for (i=0;iSetPixel(int)xx,(int)yy,color);nxx=xx+xincrement;nyy=yy+yincrement;nnDDA畫線算法(13/14)n 上面是簡
26、單DDA算法的實現,如果要改成對稱的DDA算法,只要更改k的取值就好,不過對于k值的選取需要計算一下。同學們為了體驗算法,可以實現基本的DDA畫線算法,就是前面介紹的增量算法k 1的情形:(xi,yi)(xi+1,yi+k)當 k 1時,必須把x,y互換。DDA畫線算法(14/14)2.4 BRESENHAM畫線算法nBresenhamBresenham算法是計算機圖形學領域中使用算法是計算機圖形學領域中使用最廣泛的直線掃描轉換算法。該算法最初最廣泛的直線掃描轉換算法。該算法最初是為數字繪圖儀設計的。由于它也適用于是為數字繪圖儀設計的。由于它也適用于光柵圖形顯示器,所以后來被廣泛用于直光柵圖形
27、顯示器,所以后來被廣泛用于直線的掃描轉換與其他一些應用。為了討論線的掃描轉換與其他一些應用。為了討論方便,學習的開始也假定直線的斜率在方便,學習的開始也假定直線的斜率在0 0、l l之間。其他情況可類似處理。之間。其他情況可類似處理。過各行、 各列像素中心構造一組虛擬網格線, 按直線從起點到終點的順序計算直線與各垂直網格線的交點, 然后確定該列像素中與該交點最近的像素。 yyk+1yykxkxk+1xP2P1d2d10BRESENHAM畫線算法(2/16)BRESENHAM畫線算法(3/16)n最大位移方向每次走一步k1時,x為最大位移方向ny方向走步與否取決于誤差e值的大小n誤差計算n初值:
28、e0= y/ xn當e0.5時,最接近P2(xi+1,yi+1)y方向走一步n當e0.5時,最接近P1(xi+1,yi)y方向不走步eP1P2PeeP1P2PeBRESENHAM畫線算法(4/16)n為方便與0比較,設e=e-0.5ne0=y/ x-0.5n當e0時,最接近P2(xi+1,yi+1)y方向走一步n當e0時,最接近P1(xi+1,yi)y方向不走步n有除法,不宜硬件實現eP1P2PeeP1P2PeBRESENHAM畫線算法(5/16)n如何改進算法,去掉這個除法運算呢?n分析這個像素增量算法,我們發現每次我們判斷走步的依據僅僅是e的正負,與e的本身數值大小沒關系。BRESENHA
29、M畫線算法(6/16)n設e=e2xne0=2y - x n當e0時,最接近P2(xi+1,yi+1)y方向走一步n當e0時,最接近P1(xi+1,yi)y方向不走步n分析這個新算法,其實并沒有改變什么ne0=y/ x-0.5n當e0時,最接近P2(xi+1,yi+1)y方向走一步n當e0時,最接近P1(xi+1,yi)y方向不走步n有除法,不宜硬件實現BRESENHAM畫線算法(7/16)n下一步誤差的計算n當e0時,y方向走一步e=2y/ x - 1 =e + y/ x - 1 e=e + 2y - 2xn當e=0) s1=1; else s1=-1;nif(y2-y1=0) s2=1;
30、else s2=-1;n/考慮到八個方向問題BRESENHAM畫線算法(13/16)nif(deltaydeltax)nn temp=deltax;n deltax=deltay;n deltay=temp;n interchange=1;nn else interchange=0;n/考慮到是否斜率大于1交換x,y問題n/這是一種編程實現上的技巧BRESENHAM畫線算法(14/16)n int f=2*deltay-deltax; n for(i=0;iSetPixel(x,y,color);n if(f=0)nn x+=s1;n y+=s2; n f=f+2deltay-2*deltax
31、;n BRESENHAM畫線算法(15/16)n elsenn if(interchange=1) y+=s2;n else x+=s1;n pDC-SetPixel(x,y,200);n f=f+2*deltay;nn nBRESENHAM畫線算法(16/16)n程序說明:n(1)以上程序已經考慮到所有象限直線的生成。n(2)Bresenham算法的優點如下:n 不必計算直線的斜率,因此不做除法。n 不用浮點數,只用整數。n 只做整數加減運算和乘2運算,而乘2運算可以用移位操作實現。n Bresenham算法的運算速度很快。 2.5 關于線寬線型 前面我們編程實現的畫圖算法都是一個像素寬度的
32、連續的直線(逐點畫線法畫出來的線粗細步均勻),實際使用中我們經常還需要用到各種寬度不同的線,實線,還有虛線來表達不同的含義。常用商業軟件都提供了類似的功能,比如word,autocad等等軟件。 要產生具有寬度的線,可以順著掃描所生成的單像素線條軌跡, 移動一把具有一定寬度的“刷子”來獲得,“刷子”的形狀可以是一條線段或一個正方形。也可以采用區域填充的辦法間接地產生有寬度的線(如AutoCAD系統即是)。關于線寬線型(/)(1)垂直線刷子:假設直線斜率在1,1之間,把刷子放置成垂直方向,刷子中點對準直線一端點,然后讓刷子中心往直線的另一端移動,即可“刷出”具有一定寬度的線。關于線寬線型(/)n
33、實現方法:在直線的掃描轉換中,計算出與直線最近的像素點后,在繪制點的同時,分別向上和向下多繪制幾個點,即可實現垂直刷的寬度線。關于線寬線型(/)(2)水平線刷子:直)水平線刷子:直線斜率不在線斜率不在1,1之間,可以把刷子之間,可以把刷子放置成水平方向,放置成水平方向,刷子中點對準直刷子中點對準直線線端點并往直線端點并往直線的另一端移動,可的另一端移動,可“刷出刷出”具有一定具有一定寬度的線。寬度的線。 關于線寬線型(/)n實現方法:在直線的掃描轉換中,實現方法:在直線的掃描轉換中,計算出與直線最近的像素點后,在計算出與直線最近的像素點后,在繪制點的同時,分別向左和向右多繪制點的同時,分別向左
34、和向右多繪制幾個點,即可實現水平刷的寬繪制幾個點,即可實現水平刷的寬度線。度線。 關于線寬線型(/)n(3)方形刷子:把邊寬為指定線寬的正方)方形刷子:把邊寬為指定線寬的正方形的中心沿直線作平行移動,即可獲得具形的中心沿直線作平行移動,即可獲得具有線寬的線條。有線寬的線條。 關于線寬線型(/)n實現正方形刷子最簡單的辦法是,實現正方形刷子最簡單的辦法是,把方形中心對準單像素寬的線條上把方形中心對準單像素寬的線條上各個像素,并把方形內的像素全部各個像素,并把方形內的像素全部置成線條顏色。這種簡單方法將會置成線條顏色。這種簡單方法將會重復地寫像素。這是因為對應于相重復地寫像素。這是因為對應于相鄰兩
35、像素的方形一般會重疊許多像鄰兩像素的方形一般會重疊許多像素。素。關于線寬線型(/)關于線寬線型(/)n線刷子的優缺點: 算法簡單、效率高是線刷子的優點。但是,線的始末端總是水平或垂直的。因此,當線寬較大時,看起來很不自然。當比較接近水平的線與比較接近垂直的線匯合時,匯合處外角將有缺口,如圖 所示。n生成具有寬度的線條還可以采用區域填充的算法。先算出線條各角點,再用直線段把相鄰角點連接起來,最后調用多邊形填充算法把所得的四邊形進行填色,即得到具有寬度的線條。 用這種方法還可以生成兩端粗細不一樣的線條。關于線寬線型(/) 在繪圖應用中常用到不同線型的線條,以便區分各種不同的意義。如采用實線表示立體
36、線框圖中可見的輪廓線,用虛線表示不可見的輪廓線, 用點劃線表示中心線等等。關于線寬線型(/) 線型可以用一個布爾值的序列來存放。例如,用一個 32 位整數可以存放 32 個布爾值。用這樣的整數存放線型定義時,線型必須以 32 個像素為周期進行重復。可按下述語句寫像素: if(位串i%32)drawpixel(x, y,color); 其中i為循環變量,在掃描轉換算法的內循環中,每處理一個像素就遞增 1,然后除以 32 取余。 關于線寬線型(/) 用這種簡單辦法實現的線型有個毛病。因為每位對應于算法的一個迭代步驟而不是線條上一個長度單位,因此線型中的筆劃長度與直線長度有關,斜線上的筆劃長度比橫向
37、或豎向上的筆劃更長。對于工程圖,這種變化是不能接受的。這時,每個筆劃應該作為與角度無關的線段進行計算并掃描轉換。粗線的線型計算為實的或透明的正方形,其頂點位置根據線型要求進行準確計算。然后對正方形進行掃描轉換,對于垂直或水平的粗線線型,可以用寫方塊的簡單辦法進行。 關于線寬線型(/)n在我們選用的教材上(P32),使用了一種最靈活的方式畫虛線,通過定義實線和虛線的距離來選擇繪圖像素點。n這種方法有個缺點,那就是直線段的總長度可能不是實線部分加上虛線部分距離的整數倍,可能會造成繪制虛線二頭端點為空的情況。n還有個缺點,那就是大量的除法計算效果不太好。關于線寬線型(/)n實際利用Visual C+
38、中編制圖形程序,可以利用圖形學算法自己動手編制基本圖形程序,作為圖形程序的基類,當然還可利用系統中已提供的圖形基類。下面簡單介紹Visual C+提供的常用繪制圖形函數。2.6 Visual C+中基本繪圖函數n1點n畫點是最基本的繪圖操作,在繪圖中,畫點是通過調用CDC:SetPixel()或CDC SetPixelV()函數來實現的,原型如:n(1)COLORREF SetPixel(int x, int y, COLORREF crColor);n(2)COLORREF SetPixel(POINT point, COLORREF crColor);n(3)BOOL SetPixelV(
39、int x, int y, COLORREF crColor);n(4)BOOL SetPixelV(POINT point, COLORREF crColor);Visual C+中基本繪圖函數(1/18)n2畫筆n一般格式:Cpen( ) Cpen(int nPenStyle, int nWidth, CORLORREF crColor);n各屬性意義:nPenStyle設置畫筆的式樣,式樣有:PS_SOLID(實線),PS_DASH(虛線)、PS_DASHDOT(點劃線)、PS_DASHDOTDOT(雙點劃線)、PS_DOT(點線)、PS_NULL(空筆不畫線);nWidth設置線的寬度
40、,默認值為1(1個像素寬);crColor表示顏色,可用DWOR表示,也可用RGB(r, g, b)表示。Visual C+中基本繪圖函數(2/18)n3畫刷n用于指定填充的特征,畫刷創建的格式如下:n(1)CBrush CBrush(創建一個空的畫刷對象),可用GreateSolidBrush(),Greateha- tchBrush(),GreatehatchBrushIndrect(),GreatePatternBrush(),GreateDIBPatternBrush()建立畫刷。n(2)CBrush CBrush()建立單一顏色的畫刷,用次畫刷畫出的圖形內部將會填充指定顏色。Visu
41、al C+中基本繪圖函數(3/18)n(3)CBrush CBrush(int nIndex, COLORREF crColor);構建名為hatch的畫刷,特點為畫出的多邊形內部將填充nrColor指定的線條格式,nrColor有HS_BDIAGONAL(45左下右上的斜線)、HS_CROSS(垂直線和水平線)、HS_DIAGCROSS(45左上右下、左上右下的相交斜線)、HS_HDLAGNAL(45左上右下的斜線)、HS_HORIZONAL(水平線)、HS_VERTICAL(垂直線)。Visual C+中基本繪圖函數(4/18)n(4)CBrush CBrush(Cbitmap *pBit
42、map)中pBitmap指向Cbitmap對象的指針,這一位圖對象包含用做畫刷圖案的位圖,此位圖必須為88大小,否則將對原位圖進行裁剪。n創建畫刷和畫筆后,還要用CDC類選中畫筆和畫刷,用CPaintDC,CClientDC或CWindowDC來選中、繪圖及撤銷對象。Visual C+中基本繪圖函數(5/18)nCClientDC對象代表客戶程序區域的繪圖畫面只能在窗口的客戶區域中畫圖。若需處理整個畫面(包括客戶程序區域和非客戶程序區)設備上下文的調用和釋放可用CWindowDC。Visual C+中基本繪圖函數(6/18)n4繪制直線函數n(1)MoveTo()函數用來設置當前的x,y的位置
43、,創建的格式如下:nCPoint MoveTo(int x, int y);nCPoint MoveTo(POINT point);n其中x,y用于定義新位置的坐標,point指定新位置,可為其傳遞一個POINT對象。n功能:將線的起點從當前位置移到新位置(x,y),并且只移動點不畫線。Visual C+中基本繪圖函數(7/18)n(2)LineTo()用于繪制起點坐標到終點直線,創建的格式如下:nBOOL LineTo(int x, int y);nBOOL LineTo(POINT point);n其中x,y用于定義線的終點坐標,point指定線段端點位置,可為其傳遞一個POINT結構或P
44、OINT對象。n功能:從當前的位置到新位置(x,y)畫線(不包括此端點)。Visual C+中基本繪圖函數(8/18)n5橢圓函數n創建的格式如下:nBOOL Ellipse(int x1, int y1 , int x2, int y2);nBOOL Ellipse(LPCRECT lpRect);n說明:x1, y1為限定橢圓范圍的矩形左上角坐標,x2, y2為限定橢圓范圍的矩形右下角坐標。nLpRect指定橢圓的限定矩形,可為其傳遞一個CRect對象。Visual C+中基本繪圖函數(9/18)n6函數繪制一段橢圓弧Arc()n創建的格式如下:nBOOL Arc(int x1, int
45、y1 , int x2, int y2, int x3, int y3 , int x4, int y4);nBOOL Ellipse(LPCRECT lpRect);nx1, y1為限定橢圓弧范圍的矩形左上角坐標;x2, y2為限定橢圓弧范圍的矩形右下角坐標。x3, y3為起點坐標;x4, y4為終點坐標。 Visual C+中基本繪圖函數(10/18)n7矩形函數n創建的格式如下:nBOOL Rectangle(int x1, int y1, int x2, int y2);nx1, y1為矩形左上角坐標,x2, y2為矩形右下角坐標。n功能:使用當前畫筆畫一矩形。Visual C+中基本繪圖函數(11/18)n8連續畫線函數n創建的格式如下:n(1)BOOL PolyLine(LPPOINT
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯系上傳者。文件的所有權益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網頁內容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
- 4. 未經權益所有人同意不得將文件中的內容挪作商業或盈利用途。
- 5. 人人文庫網僅提供信息存儲空間,僅對用戶上傳內容的表現方式做保護處理,對用戶上傳分享的文檔內容本身不做任何修改或編輯,并不能對任何下載內容負責。
- 6. 下載文件中如有侵權或不適當內容,請與我們聯系,我們立即糾正。
- 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 培訓總結與計劃指南
- 棗強中學高一上學期第一次月考物理試題
- 家裝公司活動流程
- 消防法律法規培訓
- 2025電競館合作合同標準模板
- 民政局安全培訓大綱
- 2025小型工程合同樣本范本
- 2025年上海市的簡易勞動合同范本
- 監獄警察一日行為規范
- 2025年高考歷史總復習高中歷史必修二全冊復習匯編
- 2025年注冊會計師(專業階段)題庫完美版帶答案分析
- 云南師大附中2025屆高三下學期第六次檢測物理試卷含解析
- 市政排水移交協議書
- 廣西壯族自治區馬山縣實驗高中-雙休背后:從“要我學”到“我要學”的轉變-高三家長會【課件】
- 2024年中小學教師資格考試復習資料
- 名企2025匯能控股集團有限公司人才招聘151人筆試參考題庫附帶答案詳解
- 全媒體內容創作技能試題及答案
- 蛋雞155標準化立體養殖模式
- 血氨正常值和臨床意義
- 浙江省湖州市德清縣2025年中考語文模擬考試試卷(附答案)
- 2025年無錫南洋職業技術學院單招職業技能測試題庫帶答案
評論
0/150
提交評論