計算機圖形學第二章_第1頁
計算機圖形學第二章_第2頁
計算機圖形學第二章_第3頁
計算機圖形學第二章_第4頁
計算機圖形學第二章_第5頁
已閱讀5頁,還剩105頁未讀, 繼續(xù)免費閱讀

下載本文檔

版權說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權,請進行舉報或認領

文檔簡介

1、第二章 直線掃描轉(zhuǎn)換算法n1.光柵圖形學n2.逐點畫線算法n3.DDA畫線算法n4.BRESENHAM畫線算法n5.關于線寬線型n6.Visual C+中基本繪圖函數(shù) 2.1 光柵圖形學n計算機圖形學已成為計算機技術中發(fā)展最快的領域,計算機圖形軟件也相應得到快速發(fā)展。計算機繪圖顯示有屏幕顯示、打印機打印圖樣和繪圖機輸出圖樣等方式,其中用屏幕顯示圖樣是計算機繪圖的重要內(nèi)容。n計算機上常見的顯示器為光柵圖形顯示器,光柵圖形顯示器可以看作像素的矩陣。像素是組成圖形的基本元素,一般稱為“點”。通過點亮一些像素,滅掉另一些像素,即在屏幕上產(chǎn)生圖形。在光柵顯示器上顯示任何一種圖形必須在顯示器的相 應像素點

2、上畫上所需顏色,即具有一種或多種顏色的像素集合構成圖形。確定最佳接近圖形的像素集合,并用指定屬性寫像素的過程稱為圖形的掃描轉(zhuǎn)換或光柵化。對于一維圖形,在不考慮線寬時,用一個像素寬的直、曲線來顯示圖形。二維圖形的光柵化必須確定區(qū)域?qū)南袼丶⒂弥付ǖ膶傩曰驁D案進行顯示,即區(qū)域 填充。n什么是光柵圖形學? 光柵顯示器 圖形光柵化、 光柵化圖形的處理n光柵顯示器上顯示的圖形,稱之為光柵圖形。光柵顯示器可以看作是一個象素矩陣,在光柵顯示器上顯示的任何一個圖形,實際上都是一些具有一種或多種顏色和灰度象素的集合。由于對一個具體的光柵顯示器來說,象素個數(shù)是有限的,象素的顏色和灰度等級也是有限的,象素是有

3、大小的,所以光柵圖形只是近似的實際圖形。如何使光柵圖形最完美地逼近實際圖形,便是光柵圖形學要研究的內(nèi)容。以后,我們提到“顯示器”時,如未特別聲明,均指光柵顯示器。 光柵圖形學算法特點n1.要充分考慮屏幕像素,光柵的特性,如何逼近真實圖形,如何減小這個誤差,如何提高圖形處理速度是圖形學算法的追求。n2.編寫計算機圖形學算法,最好還要具備計算方法的基礎知識,了解計算機是如何求解方程,了解求解過程與實際人思維的不同,也就是把人思維的計算方法翻譯到機器,這就是計算方法研究的內(nèi)容。光柵圖形學的研究內(nèi)容直線段的掃描轉(zhuǎn)換算法圓弧的掃描轉(zhuǎn)換算法多邊形的掃描轉(zhuǎn)換與區(qū)域填充字符裁剪反走樣消隱n直線段是最基本的圖形

4、,因此直線段生成的質(zhì)量好壞與速度快慢將直接影響整個圖形生成的質(zhì)量和速度。所以直線段生成算法在圖形軟件設計中起著關鍵的作用。n如果已知屏幕中直線段的二個端點,可以有多種不同的數(shù)學方法來決定應改變在二端點之間的哪些像素的亮度值才能顯示出二點間的直線,生成直線段的算法之間區(qū)別主要是判別和生成x,y增量過程和方法不同,所能適應的設備環(huán)境也不同。下面介紹三種基本的畫線算法。光柵圖形中點的表示(x,y)坐標地址線性表地址線性表1D表示顯示屏幕顯示屏幕2D表示像素由其左下角坐標表示像素由其左下角坐標表示光柵圖形中點的表示xyxmaxxminymaxymin地址地址 = (xmax-xmin) * (y-ym

5、in) + (x-xmin) + 基地址基地址每行像素點數(shù)每行像素點數(shù)行數(shù)行數(shù)行中位置行中位置n在光柵顯示器的熒光屏上生成一個對象,實質(zhì)上是往幀緩存寄存器的相應單元中填入數(shù)據(jù)。畫一條從(x1, y1)到(x2, y2)的直線,實質(zhì)上是一個發(fā)現(xiàn)最佳逼近直線的象素序列,并填入色彩數(shù)據(jù)的過程。這個過程也稱為直線光柵化。 直線掃描轉(zhuǎn)換的本質(zhì)n直線的掃描轉(zhuǎn)換確定最佳逼近于該直線的一組象素按掃描線順序,對這些象素進行寫操作,對一維圖形,不考慮線寬,則用一個像素寬的直線來顯示圖形。任何圖形的光柵化,必須顯示在一個窗口內(nèi),否則不予顯示。即確定一個圖形的哪些部分在窗口內(nèi),哪些在窗口外,即裁剪。n圖形顯示前需要:

6、掃描轉(zhuǎn)換+裁剪n裁剪-掃描轉(zhuǎn)換:最常用,節(jié)約計算時間。n掃描轉(zhuǎn)換-裁剪:算法簡單;2.2 逐點畫線算法n在數(shù)學上,理想的直線是沒有寬度在數(shù)學上,理想的直線是沒有寬度的,由無數(shù)個點構成的集合。當我的,由無數(shù)個點構成的集合。當我們對直線進行光柵化時,只能在顯們對直線進行光柵化時,只能在顯示器所給定的有限個像素中,確定示器所給定的有限個像素中,確定最佳逼近于該直線的一組像素。用最佳逼近于該直線的一組像素。用寫點方式對像素進行寫操作,這就寫點方式對像素進行寫操作,這就是通常所說的用顯示器繪制直線,是通常所說的用顯示器繪制直線,或直線的掃描轉(zhuǎn)換或直線的掃描轉(zhuǎn)換 逐點畫線算法(1/19)n逐點比較法算法的

7、基本思想是:在繪制直線的過程中,每繪制一個點就與原直線進行比較,根據(jù)比較的結(jié)果決定下一步的走向,這樣一步一步逼近直線,逐點比較法的執(zhí)行過程如下:偏差判別開始X方向移動終點判別是結(jié)束偏差計算否Y方向移動逐點畫線算法(2/19)n逐點比較法是針對筆式繪圖機提出的。根據(jù)繪圖機的結(jié)構原理及數(shù)字控制原理, 繪圖機的筆架可能的移動方向(稱為走步方向)有八個:+X、 -X、+Y、-Y、+X+Y、-X+Y、-X-Y、+X-Y。 其中+X、-X、+Y、-Y四個走步方向是一般繪圖機都提供的,稱為基本走步方向??梢?,繪圖機的基本繪圖元素是與走步方向相對應的小直線段。繪圖機所畫的一般直線和曲線,實際上是由許多小直線段

8、所組成的折線來逼近的。逐點畫線算法(3/19) 根據(jù)所畫圖線的已知條件(如直線兩個端點坐標等)計算畫圖所需要的一系列中間點(即折線的端點)的坐標,稱為插補運算。插補運算可用軟件或硬件實現(xiàn),不少繪圖機采用插補器(或稱線發(fā)生器、弧發(fā)生器)來完成插補運算,目的在于提高圖線生成速度。逐點比較法可用于插補運算。 逐點畫線算法(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、的相對位置,引入偏差函數(shù)F(k)。 nF(k)=x(a)y(k)-x(k)y(a)當K在OA上時,F(xiàn)(k)=0; K在OA上方時,F(xiàn)(k)0; K在OA下方時,F(xiàn)(k)0。 逐點畫線算法(6/19)n對第一象限內(nèi)直線的生成規(guī)定如下: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) 根據(jù)新偏差F(k+1)的正、負號再確定繪圖筆的下一步走向,這樣逐步進行,直到繪圖筆到達直線的終點為止。終點判斷可由X及Y向總走步數(shù)J(J=|x(a)|+|y(a)|)來控制,每走一步J減去1,當J=0 時即到達終點。 逐點畫線算法(8/19)n對其他象限內(nèi)直線段生成計算走步方向的規(guī)定如下圖所示。偏

11、差的遞推計算均按以下兩式進行:n 當沿X方向走步時, F(k+1)=F(k)-|y(a)|;n 當沿Y方向走步時,F(xiàn)(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優(yōu)點: 整個算法實現(xiàn)可以使用整數(shù),沒有使用浮點數(shù)運算,沒有乘除運算,所以適合硬件實現(xiàn),大多數(shù)繪圖儀使用這個算法。n缺點: 逐點畫線法一次只能位移一步,所以畫出來的

12、直線粗細不均勻。逐點畫線算法(11/19)n逐點畫線算法VC源代碼(不包含交互內(nèi)容,直接內(nèi)置畫線段的起始點,并且沒有實現(xiàn)F(k)計算的遞推工作)nvoid CMyView:OnPointline() n n CDC *pDC=GetDC();nCOLORREF color=RGB(255,0,0);/ 前面四句就是設備環(huán)境,當然表現(xiàn)形式可以不一樣逐點畫線算法(12/19)n int a1=30;n int b1=30;n int b2=800;n int a2=600; /我們實現(xiàn)最簡單的畫線算法,二點已經(jīng)確定/后面我們再講如何交互n int x1,y1,x2,y2; /起始點坐標n int

13、itype; /畫線不同循環(huán)類型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的工作區(qū)坐標的

14、特性,我們分析以后,畫線存在二個類型,即把理論中的分四個象限畫線情況歸結(jié)為二類,畫線起點和始點我們靈活變化一下,簡化編程。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;逐點畫線

15、算法(17/19)ncase 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注意:從一個理論上的算法提煉到具體一個編譯器可以運行編譯的程序,可能會有多種不同的編寫程序方法,但執(zhí)行效果是一樣的,都能體現(xiàn)算法的精髓。 上面的逐點畫線算法沒有實現(xiàn)計算誤差中 F(K)的遞推工作,效率可能會低點,同學們可以考慮把這個可執(zhí)行無誤算法改進一下。 優(yōu)秀的程序不僅要求無誤執(zhí)行,還要有良

16、好的性能,茁壯性(出錯處理好)等要求。逐點畫線算法(18/19)n 上面這個程序還有些bug,那就是不能繪制水平或豎直的直線,還有未能實現(xiàn)F(k)的遞推工作,這些留給同學們?nèi)プ?,可以在程序中加入一些代碼來解決這個問題。同學們還可以根據(jù)自己對算法的理解重新編寫代碼,不用和我編寫的思路一樣。比如實現(xiàn)四象限方向畫圖,判斷F(k)的正負,如果為正,分四種象限情況走步,如果為負,分四種象限情況走步。逐點畫線算法(19/19)逐點法編程另一個思路n坐標變換的思想 坐標變換的思想對后面的曲線曲面編程很有幫助 根據(jù)一開始上課推導的最簡單的逐點法繪制直線,從第一象限原點出發(fā)到第一象限的一個點得到的算法,利用坐標

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

18、=f+y2; pDC-SetPixel(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; /畫線不同循環(huán)類型 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(

19、a1-a2); y2=abs(b1-b2); 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); br

20、eak;坐標變換映射逐點法繪制源碼 case 2 : 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數(shù)值微分法(Digital Differential Analyzer)是一種基于直線微分方程來生成直線的方法。n回顧一下數(shù)值微分的幾何意義,一階數(shù)值微分反應的是變化率,表達瞬時變化趨勢和快慢的量。2.3 DDA畫線算法 DDA畫

21、線算法(1/14)n已知線段端點:P0(x0,y0), P1(x1,y1)n直線方程 y=kx+b (xi, yi), i=0,.n.n浮點數(shù)取整 : yi=round(yi)=(int)(yi+0.5)用到浮點數(shù)的乘法、加法和取整運算 DDA畫線算法(2/14)n增量算法yi+1=kxi+1+b=k(xi+1)+b=yi+k(xi,yi)(xi+1,yi+k)n缺點:有浮點數(shù)取整運算不利于硬件實現(xiàn)效率低僅適用于k 1的情形:x每增加1,y最多增加1。當 k 1時,必須把x,y互換。 DDA畫線算法(3/14)n思考:如何改進算法更適合于編程實現(xiàn)呢?n基本思想用數(shù)值方法解微分方程 dy/dt

22、= xdy/dt = y xn+1 = xn + 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法不適合硬件實現(xiàn),只適合于軟件處理

23、。 DDA畫線算法(5/14)n【例】用對稱DDA法在起點A(2,1)和終點B(12,7)之間生成一段直線。n 求解的第一步是計算初值x, y, n。這里x=10, y=6, n=4。n 第二步按遞推公式循環(huán)計算點的坐標,并取整顯示。表是本例的循環(huán)計算過程。 圖是其屏幕顯示結(jié)果。DDA畫線算法(6/14)DDA畫線算法(7/14)DDA畫線算法(8/14)AB753124681012 對稱DDA法生成的直線比較精確,像點位置偏離直線不超過半個像素。邏輯上也比較簡單,用 2 的負指數(shù)冪作為,意味著把存放x和y的寄存器通過移位操作就可得到點與點之間的坐標增量x、y,而不用除法計算,計算直線上每一點

24、只用兩次加法即可實現(xiàn)。對稱DDA法適合用硬件來實現(xiàn), 當然也可用軟件來實現(xiàn)。 DDA畫線算法(9/14)DDA畫線算法(10/14)n/簡單的DDA畫線算法,繪制線段的起始點也是內(nèi)置的,沒有加入交互過程。這是DDA的基本算法,希望同學們好好體會算法,從理論上的算法到具體程序的過程。nvoid CMyView:OnDdaline() nnCDC *pDC=GetDC();nCOLORREF color=RGB(255,0,0);n/設備環(huán)境DDA畫線算法(11/14)n int x1=30;n int y1=600;n int x2=180;n int y2=200;n int i;n floa

25、t xincrement,yincrement,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本為浮點數(shù),但后面繪制圖形時候要取整n for (i=0;iSetPixel(int)xx,(int)yy,color);nxx=xx+xincrement;nyy=yy+yincremen

26、t;nnDDA畫線算法(13/14)n 上面是簡單DDA算法的實現(xiàn),如果要改成對稱的DDA算法,只要更改k的取值就好,不過對于k值的選取需要計算一下。同學們?yōu)榱梭w驗算法,可以實現(xiàn)基本的DDA畫線算法,就是前面介紹的增量算法k 1的情形:(xi,yi)(xi+1,yi+k)當 k 1時,必須把x,y互換。DDA畫線算法(14/14)2.4 BRESENHAM畫線算法nBresenhamBresenham算法是計算機圖形學領域中使用算法是計算機圖形學領域中使用最廣泛的直線掃描轉(zhuǎn)換算法。該算法最初最廣泛的直線掃描轉(zhuǎn)換算法。該算法最初是為數(shù)字繪圖儀設計的。由于它也適用于是為數(shù)字繪圖儀設計的。由于它也適

27、用于光柵圖形顯示器,所以后來被廣泛用于直光柵圖形顯示器,所以后來被廣泛用于直線的掃描轉(zhuǎn)換與其他一些應用。為了討論線的掃描轉(zhuǎn)換與其他一些應用。為了討論方便,學習的開始也假定直線的斜率在方便,學習的開始也假定直線的斜率在0 0、l l之間。其他情況可類似處理。之間。其他情況可類似處理。過各行、 各列像素中心構造一組虛擬網(wǎng)格線, 按直線從起點到終點的順序計算直線與各垂直網(wǎng)格線的交點, 然后確定該列像素中與該交點最近的像素。 yyk+1yykxkxk+1xP2P1d2d10BRESENHAM畫線算法(2/16)BRESENHAM畫線算法(3/16)n最大位移方向每次走一步k1時,x為最大位移方向ny方

28、向走步與否取決于誤差e值的大小n誤差計算n初值: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有除法,不宜硬件實現(xiàn)eP1P2PeeP1P2PeBRESENHAM畫線算法(5/16)n如何改進算法,去掉這個除法運算呢?n分析這個像素增量算法,我們發(fā)現(xiàn)每次我們判斷走步的依據(jù)僅僅是e的

29、正負,與e的本身數(shù)值大小沒關系。BRESENHAM畫線算法(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有除法,不宜硬件實現(xià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 s

30、1=-1;nif(y2-y1=0) s2=1; 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/這是一種編程實現(xià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

31、; n f=f+2deltay-2*deltax;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)以上程序已經(jīng)考慮到所有象限直線的生成。n(2)Bresenham算法的優(yōu)點如下:n 不必計算直線的斜率,因此不做除法。n 不用浮點數(shù),只用整數(shù)。n 只做整數(shù)加減運算和乘2運算,而乘2運算可以用移位操作實現(xiàn)。n Bresenham算法的運算速度很快。 2.5 關于線寬線

32、型 前面我們編程實現(xiàn)的畫圖算法都是一個像素寬度的連續(xù)的直線(逐點畫線法畫出來的線粗細步均勻),實際使用中我們經(jīng)常還需要用到各種寬度不同的線,實線,還有虛線來表達不同的含義。常用商業(yè)軟件都提供了類似的功能,比如word,autocad等等軟件。 要產(chǎn)生具有寬度的線,可以順著掃描所生成的單像素線條軌跡, 移動一把具有一定寬度的“刷子”來獲得,“刷子”的形狀可以是一條線段或一個正方形。也可以采用區(qū)域填充的辦法間接地產(chǎn)生有寬度的線(如AutoCAD系統(tǒng)即是)。關于線寬線型(/)(1)垂直線刷子:假設直線斜率在1,1之間,把刷子放置成垂直方向,刷子中點對準直線一端點,然后讓刷子中心往直線的另一端移動,即

33、可“刷出”具有一定寬度的線。關于線寬線型(/)n實現(xiàn)方法:在直線的掃描轉(zhuǎn)換中,計算出與直線最近的像素點后,在繪制點的同時,分別向上和向下多繪制幾個點,即可實現(xiàn)垂直刷的寬度線。關于線寬線型(/)(2)水平線刷子:直)水平線刷子:直線斜率不在線斜率不在1,1之間,可以把刷子之間,可以把刷子放置成水平方向,放置成水平方向,刷子中點對準直刷子中點對準直線線端點并往直線端點并往直線的另一端移動,可的另一端移動,可“刷出刷出”具有一定具有一定寬度的線。寬度的線。 關于線寬線型(/)n實現(xiàn)方法:在直線的掃描轉(zhuǎn)換中,實現(xiàn)方法:在直線的掃描轉(zhuǎn)換中,計算出與直線最近的像素點后,在計算出與直線最近的像素點后,在繪制

34、點的同時,分別向左和向右多繪制點的同時,分別向左和向右多繪制幾個點,即可實現(xiàn)水平刷的寬繪制幾個點,即可實現(xiàn)水平刷的寬度線。度線。 關于線寬線型(/)n(3)方形刷子:把邊寬為指定線寬的正方)方形刷子:把邊寬為指定線寬的正方形的中心沿直線作平行移動,即可獲得具形的中心沿直線作平行移動,即可獲得具有線寬的線條。有線寬的線條。 關于線寬線型(/)n實現(xiàn)正方形刷子最簡單的辦法是,實現(xiàn)正方形刷子最簡單的辦法是,把方形中心對準單像素寬的線條上把方形中心對準單像素寬的線條上各個像素,并把方形內(nèi)的像素全部各個像素,并把方形內(nèi)的像素全部置成線條顏色。這種簡單方法將會置成線條顏色。這種簡單方法將會重復地寫像素。這

35、是因為對應于相重復地寫像素。這是因為對應于相鄰兩像素的方形一般會重疊許多像鄰兩像素的方形一般會重疊許多像素。素。關于線寬線型(/)關于線寬線型(/)n線刷子的優(yōu)缺點: 算法簡單、效率高是線刷子的優(yōu)點。但是,線的始末端總是水平或垂直的。因此,當線寬較大時,看起來很不自然。當比較接近水平的線與比較接近垂直的線匯合時,匯合處外角將有缺口,如圖 所示。n生成具有寬度的線條還可以采用區(qū)域填充的算法。先算出線條各角點,再用直線段把相鄰角點連接起來,最后調(diào)用多邊形填充算法把所得的四邊形進行填色,即得到具有寬度的線條。 用這種方法還可以生成兩端粗細不一樣的線條。關于線寬線型(/) 在繪圖應用中常用到不同線型的

36、線條,以便區(qū)分各種不同的意義。如采用實線表示立體線框圖中可見的輪廓線,用虛線表示不可見的輪廓線, 用點劃線表示中心線等等。關于線寬線型(/) 線型可以用一個布爾值的序列來存放。例如,用一個 32 位整數(shù)可以存放 32 個布爾值。用這樣的整數(shù)存放線型定義時,線型必須以 32 個像素為周期進行重復??砂聪率稣Z句寫像素: if(位串i%32)drawpixel(x, y,color); 其中i為循環(huán)變量,在掃描轉(zhuǎn)換算法的內(nèi)循環(huán)中,每處理一個像素就遞增 1,然后除以 32 取余。 關于線寬線型(/) 用這種簡單辦法實現(xiàn)的線型有個毛病。因為每位對應于算法的一個迭代步驟而不是線條上一個長度單位,因此線型中

37、的筆劃長度與直線長度有關,斜線上的筆劃長度比橫向或豎向上的筆劃更長。對于工程圖,這種變化是不能接受的。這時,每個筆劃應該作為與角度無關的線段進行計算并掃描轉(zhuǎn)換。粗線的線型計算為實的或透明的正方形,其頂點位置根據(jù)線型要求進行準確計算。然后對正方形進行掃描轉(zhuǎn)換,對于垂直或水平的粗線線型,可以用寫方塊的簡單辦法進行。 關于線寬線型(/)n在我們選用的教材上(P32),使用了一種最靈活的方式畫虛線,通過定義實線和虛線的距離來選擇繪圖像素點。n這種方法有個缺點,那就是直線段的總長度可能不是實線部分加上虛線部分距離的整數(shù)倍,可能會造成繪制虛線二頭端點為空的情況。n還有個缺點,那就是大量的除法計算效果不太好

38、。關于線寬線型(/)n實際利用Visual C+中編制圖形程序,可以利用圖形學算法自己動手編制基本圖形程序,作為圖形程序的基類,當然還可利用系統(tǒng)中已提供的圖形基類。下面簡單介紹Visual C+提供的常用繪制圖形函數(shù)。2.6 Visual C+中基本繪圖函數(shù)n1點n畫點是最基本的繪圖操作,在繪圖中,畫點是通過調(diào)用CDC:SetPixel()或CDC SetPixelV()函數(shù)來實現(xiàn)的,原型如:n(1)COLORREF SetPixel(int x, int y, COLORREF crColor);n(2)COLORREF SetPixel(POINT point, COLORREF crCo

39、lor);n(3)BOOL SetPixelV(int x, int y, COLORREF crColor);n(4)BOOL SetPixelV(POINT point, COLORREF crColor);Visual C+中基本繪圖函數(shù)(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_

40、NULL(空筆不畫線);nWidth設置線的寬度,默認值為1(1個像素寬);crColor表示顏色,可用DWOR表示,也可用RGB(r, g, b)表示。Visual C+中基本繪圖函數(shù)(2/18)n3畫刷n用于指定填充的特征,畫刷創(chuàng)建的格式如下:n(1)CBrush CBrush(創(chuàng)建一個空的畫刷對象),可用GreateSolidBrush(),Greateha- tchBrush(),GreatehatchBrushIndrect(),GreatePatternBrush(),GreateDIBPatternBrush()建立畫刷。n(2)CBrush CBrush()建立單一顏色的畫刷,

41、用次畫刷畫出的圖形內(nèi)部將會填充指定顏色。Visual C+中基本繪圖函數(shù)(3/18)n(3)CBrush CBrush(int nIndex, COLORREF crColor);構建名為hatch的畫刷,特點為畫出的多邊形內(nèi)部將填充nrColor指定的線條格式,nrColor有HS_BDIAGONAL(45左下右上的斜線)、HS_CROSS(垂直線和水平線)、HS_DIAGCROSS(45左上右下、左上右下的相交斜線)、HS_HDLAGNAL(45左上右下的斜線)、HS_HORIZONAL(水平線)、HS_VERTICAL(垂直線)。Visual C+中基本繪圖函數(shù)(4/18)n(4)CBr

42、ush CBrush(Cbitmap *pBitmap)中pBitmap指向Cbitmap對象的指針,這一位圖對象包含用做畫刷圖案的位圖,此位圖必須為88大小,否則將對原位圖進行裁剪。n創(chuàng)建畫刷和畫筆后,還要用CDC類選中畫筆和畫刷,用CPaintDC,CClientDC或CWindowDC來選中、繪圖及撤銷對象。Visual C+中基本繪圖函數(shù)(5/18)nCClientDC對象代表客戶程序區(qū)域的繪圖畫面只能在窗口的客戶區(qū)域中畫圖。若需處理整個畫面(包括客戶程序區(qū)域和非客戶程序區(qū))設備上下文的調(diào)用和釋放可用CWindowDC。Visual C+中基本繪圖函數(shù)(6/18)n4繪制直線函數(shù)n(1

43、)MoveTo()函數(shù)用來設置當前的x,y的位置,創(chuàng)建的格式如下:nCPoint MoveTo(int x, int y);nCPoint MoveTo(POINT point);n其中x,y用于定義新位置的坐標,point指定新位置,可為其傳遞一個POINT對象。n功能:將線的起點從當前位置移到新位置(x,y),并且只移動點不畫線。Visual C+中基本繪圖函數(shù)(7/18)n(2)LineTo()用于繪制起點坐標到終點直線,創(chuàng)建的格式如下:nBOOL LineTo(int x, int y);nBOOL LineTo(POINT point);n其中x,y用于定義線的終點坐標,point指

44、定線段端點位置,可為其傳遞一個POINT結(jié)構或POINT對象。n功能:從當前的位置到新位置(x,y)畫線(不包括此端點)。Visual C+中基本繪圖函數(shù)(8/18)n5橢圓函數(shù)n創(chuàng)建的格式如下:nBOOL Ellipse(int x1, int y1 , int x2, int y2);nBOOL Ellipse(LPCRECT lpRect);n說明:x1, y1為限定橢圓范圍的矩形左上角坐標,x2, y2為限定橢圓范圍的矩形右下角坐標。nLpRect指定橢圓的限定矩形,可為其傳遞一個CRect對象。Visual C+中基本繪圖函數(shù)(9/18)n6函數(shù)繪制一段橢圓弧Arc()n創(chuàng)建的格式如

45、下:nBOOL Arc(int x1, int 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+中基本繪圖函數(shù)(10/18)n7矩形函數(shù)n創(chuàng)建的格式如下:nBOOL Rectangle(int x1, int y1, int x2, int y2);nx1, y1為矩形左上角坐標,x2, y2為矩形右下角坐標。n功能:使用當前畫筆畫一矩形。Visual C+中基本繪圖函數(shù)(11/18)n8連續(xù)畫線函數(shù)n創(chuàng)建的格式如下:n(1)BOOL PolyLine(LPPOIN

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
  • 4. 未經(jīng)權益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責。
  • 6. 下載文件中如有侵權或不適當內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論