基本光柵圖形生成技術(shù)_第1頁
基本光柵圖形生成技術(shù)_第2頁
基本光柵圖形生成技術(shù)_第3頁
基本光柵圖形生成技術(shù)_第4頁
基本光柵圖形生成技術(shù)_第5頁
已閱讀5頁,還剩54頁未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡介

1、第3章 基本光柵圖形生成技術(shù)顯示器是由離散像素組成的矩陣,在繪制具有連續(xù)性質(zhì)的直線、曲線或區(qū)域等基本圖形時(shí),需要確定最佳逼近它們的像素,這個(gè)過程稱為光柵化。當(dāng)光柵化按照掃描線的順序進(jìn)行時(shí),它被稱為掃描轉(zhuǎn)換。對(duì)于一維圖形,在不考慮線寬時(shí),用一個(gè)像素寬的直、曲線來顯示圖形。二維圖形的光柵化必須確定區(qū)域?qū)?yīng)的像素集,并用指定的屬性或圖案顯示之,即區(qū)域填充。光柵化和掃描轉(zhuǎn)換是光柵圖形學(xué)的基本問題,其算法的好壞對(duì)系統(tǒng)的效率有直接的關(guān)系。1雖然幾乎所有的程序設(shè)計(jì)語言都提供了線、圓弧、填充等的繪制函數(shù),但只有學(xué)習(xí)了基本圖形的生成原理和算法,才能超越具體程序設(shè)計(jì)語言的限制,滿足用戶的特殊繪圖要求。假定,編程語

2、言提供了一個(gè)顯示像素函數(shù):SetPixel(x,y,color);其中,x和y為像素的位置坐標(biāo),color為像素的顏色。23.2 線的生成算法3.2.1 直線的生成算法在數(shù)學(xué)上,直線是沒有寬度的、由無數(shù)個(gè)點(diǎn)構(gòu)成的集合。對(duì)直線進(jìn)行光柵化就是在顯示器所給定的有限個(gè)像素矩陣中,確定最佳逼近于該直線的一組像素。然后按照掃描線順序,對(duì)這些像素進(jìn)行寫操作,這就是直線的掃描轉(zhuǎn)換。對(duì)于水平線、垂直線和45線,選擇哪些光柵元素是顯而易見的,而對(duì)于其它方向的直線,像素的選擇較為困難。 33.2 線的生成算法3.2.1 直線的生成算法斜率截距直線方程:k表示斜率,b是y軸截距。給定兩個(gè)端點(diǎn)P0(x0,y0)和P1(

3、x1,y1),線段的斜率k和截距b為:從起點(diǎn)到終點(diǎn),x每次增加(或減少)1,用直線方程計(jì)算對(duì)應(yīng)的y值,再用SetPixel(x, int(y+0.5),color)輸出該像素。復(fù)雜度:乘法+加法+取整43.2 線的生成算法3.2.1 直線的生成算法上述方法稱為直線繪制基本算法,缺點(diǎn):每步都需要一個(gè)浮點(diǎn)乘法運(yùn)算和一個(gè)四舍五入運(yùn)算,所以效率太低。由于一個(gè)圖中可以包含成千上萬條直線,所以要求繪制算法應(yīng)盡可能的快。5數(shù)值微分(DDA)法 給定兩個(gè)端點(diǎn)P0(x0,y0)和P1(x1,y1),線段的斜率k和截距b為:畫線過程從x的左端點(diǎn)x0開始,向x右端點(diǎn)步進(jìn),步長=1(個(gè)像素),計(jì)算相應(yīng)的y坐標(biāo):y=k

4、x+b,取像素點(diǎn)(x, round(y)作為當(dāng)前點(diǎn)的坐標(biāo)。計(jì)算 yi+1= kxi+1 + b = k(xi+ x) + b = kxi + b + kx = yi + kx 當(dāng)x =1時(shí) yi+1 = yi + k 即:當(dāng)x每遞增1, y遞增k(即直線斜率)。 圖3-1 DDA算法基本原理 復(fù)雜度:加法+取整6數(shù)值微分(DDA)法 上述采用的增量計(jì)算方法稱為數(shù)值微分算法(Digital Differential Analyzer,簡稱DDA)。數(shù)值微分法的本質(zhì),是用數(shù)值方法解微分方程,通過同時(shí)對(duì)x和y各增加一個(gè)小增量,計(jì)算下一步的x、y值。圖3-1 DDA算法基本原理 7void DDALi

5、ne(int x0, int y0, int x1, int y1, int color) int i; float dx, dy, length, x, y; if (fabs(x1-x0) = fabs(y1-y0) length = fabs(x1-x0); else length = fabs(y1-y0); dx = (x1-x0)/length; dy = (y1-y0)/length;8 i = 1; x = x0; y = y0; while(i = length) SetPixel(int(x+0.5), int(y+0.5), color); x = x+dx; y = y

6、+dy; i+; 9x int(y+0.5) y+0.50 0 0+0.51 0 0.4+0.52 1 0.8+0.53 1 1.2+0.54 2 1.6+0.55 2 2.0+0.5圖3-2 直線段的DDA掃描轉(zhuǎn)換 舉例: 線段P0(0,0)和P1(5,2)的DDA方法掃描轉(zhuǎn)換DDA算法與基本算法相比,減少了浮點(diǎn)乘法,提高了效率。但是x與dx、y與dy用浮點(diǎn)數(shù)表示,每一步要進(jìn)行四舍五入后取整,不利于硬件實(shí)現(xiàn),因而效率仍有待提高。 10 Bresenham算法Bresenham算法是1965年提出的,基本原理是:借助于一個(gè)誤差量(直線與當(dāng)前實(shí)際繪制像素點(diǎn)的距離),來確定下一個(gè)像素點(diǎn)的位置。算法

7、的巧妙之處在于采用增量計(jì)算,使得對(duì)于每一列,只要檢查誤差量的符號(hào),就可以確定該下一列的像素位置。 圖3-3 根據(jù)誤差量來確定理想的像素點(diǎn) 假設(shè)當(dāng)前直線上的像素坐標(biāo)為(xi, yi),那么下一步需要在列xi+1上確定掃描線y的值。y值要么不變,要么遞增1,可通過比較d1和d2來決定。 如圖3-3所示,對(duì)于直線斜率k在01之間的情況,從給定線段的左端點(diǎn)P0(x0, y0)開始,逐步處理每個(gè)后續(xù)列(x位置),并在掃描線y值最接近線段的像素上繪出一點(diǎn)。yi +1yyixixi+1d2d111根據(jù)誤差項(xiàng)d的值來決定是否增1的過程如下:設(shè)y=y1y0, x=x1x0,則k=y/x,代入上式,得: 是常量,

8、與像素位置無關(guān)。其中yi +1yyixixi+1d2d112則ei的計(jì)算僅包括整數(shù)運(yùn)算,其符號(hào)與(d1-d2)的符號(hào)相同。當(dāng)ei 0時(shí),直線上理想位置與像素(xi1,yi1)更接近,應(yīng)取右上方像素;(3) 當(dāng)ei = 0時(shí),兩個(gè)像素與直線上理想位置一樣接近,可約定取(xi1,yi1)。13對(duì)于第i+1步,誤差參數(shù)為:此時(shí)參數(shù)c已經(jīng)消去,且xi+1=xi+1,得:14如果選擇右上方像素,即 ,則:如果選擇右方像素,即 ,則:對(duì)于每個(gè)整數(shù)x,從線段的坐標(biāo)端點(diǎn)開始,循環(huán)的進(jìn)行誤差量的計(jì)算。起始像素(x0,y0)的誤差參數(shù)為:15void Bresenham_Line (int x0, int y0,

9、 int x1, int y1, int color) int dx = x1-x0, dy = y1- y0, e = 2*dy-dx; int x = x0, y = y0; for (int i = 0; i = 0) y+; e = e+2*dy-2*dx; else e = e+2*dy; 當(dāng)0k1時(shí),y總是增加1,再用Bresenham誤差量判別式可以確定x是否增加1。當(dāng)k 0,點(diǎn)在圓外;F(x,y) 0,點(diǎn)在圓內(nèi);設(shè)M為P1和P2的中點(diǎn),即M為(xp+1, yp-0.5)若F(M) 0,M在圓外,說明P2點(diǎn)離圓弧更近,則取P2為下一個(gè)像素;若F(M) = 0,M在圓上,P1、P2

10、可任取其一,這里約定取P2。22中點(diǎn)畫圓法根據(jù)上述原理,構(gòu)造判別式dp = F(M) = F(xp+1, yp-0.5) = (xp+1)2 + (yp-0.5)2 - R2若dp = 0,應(yīng)則取P2為下一個(gè)像素,且判別式變?yōu)椋篸p+1 = F(xp+2, yp-1.5) = (xp+2)2 + (yp-1.5)2 - R2 = dp + 2(xp - yp) + 5這里,我們?nèi)?0, R)為第一個(gè)像素,判別式的初值為:d0 = F(1, R-0.5) = 1.25 - R23中點(diǎn)畫圓法為了避免浮點(diǎn)數(shù)運(yùn)算,可令e = d-0.25,此時(shí)初始化運(yùn)算d = 1.25-R對(duì)應(yīng)于e = 1-R,判別式

11、d 0對(duì)應(yīng)于e -0.25。又由于e的初值為整數(shù),且運(yùn)算過程中增量也是整數(shù),所以e始終是整數(shù),可以用e 0代替e -0.25。最后將1/8圓弧做對(duì)稱處理就能夠得到完整的圓。24void CirclePoints(int x, int y, int color) SetPixel(x, y, color); SetPixel(y, x, color); SetPixel(-x, y, color); SetPixel(y, -x, color); SetPixel(x, -y, color); SetPixel(-y, x, color); SetPixel(-x, -y, color); Se

12、tPixel(-y, -x, color);25MidPointCircle(int r, int color) int x = 0, y = r; int e = 1-r; CirclePoints (x,y,color); / 做對(duì)稱處理 while(x = y) if(e i結(jié)點(diǎn)的x值遞增x; 若允許多邊形的邊自相交,則用冒泡排序法對(duì)AET表重新排序; 多邊形填充的算法流程32 掃描線與多邊形頂點(diǎn)相交時(shí),必須正確的進(jìn)行交點(diǎn)個(gè)數(shù)的計(jì)算,否則,在進(jìn)行填充時(shí)會(huì)出現(xiàn)錯(cuò)誤。用來計(jì)算掃描線與多邊形頂點(diǎn)的相交點(diǎn)數(shù)目的三條規(guī)律。掃描線與多邊形相交的邊分處掃描線的兩側(cè),則計(jì)一個(gè)交點(diǎn),如點(diǎn)P5,P6。掃描線

13、與多邊形相交的邊分處掃描線同側(cè),且yiyi-1,yiyi-1,yiyi+1,則計(jì)0個(gè)交點(diǎn)(不填色),如P1。掃描線與多邊形邊界重合 (當(dāng)要區(qū)分邊界和邊界內(nèi)區(qū)域時(shí)需特殊處理),則計(jì)1個(gè)交點(diǎn)。33邊界標(biāo)志算法基本思想是:在幀緩沖器中對(duì)多邊形的每條邊進(jìn)行直線掃描轉(zhuǎn)換,亦即對(duì)多邊形邊界所經(jīng)過的像素打上標(biāo)志。然后再采用和掃描線算法類似的方法將位于多邊形內(nèi)的各個(gè)區(qū)段著上所需顏色。對(duì)每條與多邊形相交的掃描線依從左到右的順序,逐個(gè)訪問該掃描線上的像素。使用一個(gè)布爾量inside來指示當(dāng)前點(diǎn)是否在多邊形內(nèi)的狀態(tài)。Inside的初值為假,每當(dāng)當(dāng)前訪問的像素為被打上邊標(biāo)志的點(diǎn),就把inside取反。對(duì)未打標(biāo)志的像素

14、,inside不變。若訪問當(dāng)前像素時(shí),inside為真,說明該像素在多邊形內(nèi),則把該像素置為填充顏色。用軟件實(shí)現(xiàn)時(shí),掃描線算法與邊界標(biāo)志算法的執(zhí)行速度幾乎相同,但由于邊界標(biāo)志算法不必建立維護(hù)邊表以及對(duì)它進(jìn)行排序,所以邊界標(biāo)志算法更適合硬件實(shí)現(xiàn),這時(shí)它的執(zhí)行速度比有序邊表算法快一至兩個(gè)數(shù)量級(jí)。 343.3.2 種子填充算法區(qū)域:用點(diǎn)陣形式表示的填充圖形,是像素的集合。區(qū)域可采用內(nèi)點(diǎn)表示和邊界表示兩種表示形式。內(nèi)點(diǎn)表示法,指區(qū)域內(nèi)的所有像素著同一顏色;邊界表示法,則是指區(qū)域的邊界點(diǎn)著同一顏色。35區(qū)域填充算法要求區(qū)域是連通的,因?yàn)橹挥性谶B通區(qū)域中,才可能將種子點(diǎn)的顏色擴(kuò)展到區(qū)域內(nèi)的其它點(diǎn)。區(qū)域可分

15、為4向連通區(qū)域和8向連通區(qū)域。4向連通區(qū)域指的是從區(qū)域上一點(diǎn)出發(fā),可通過四個(gè)方向,即上、下、左、右移動(dòng)的組合,在不越出區(qū)域的前提下,到達(dá)區(qū)域內(nèi)的任意像素;8向連通區(qū)域指的是從區(qū)域內(nèi)每一像素出發(fā),可通過八個(gè)方向,即上、下、左、右、左上、右上、左下、右下這八個(gè)方向的移動(dòng)的組合來到達(dá)。 四個(gè)方向運(yùn)動(dòng) 八個(gè)方向運(yùn)動(dòng) 四連通區(qū)域 八連通區(qū)域36void FloodFill4(int x,int y,int oldcolor,int newcolor) if(GetPixel(x,y)=oldcolor) SetPixel(x,y,newcolor); FloodFill4(x,y+1,oldcolor,

16、newcolor); FloodFill4(x,y-1,oldcolor,newcolor); FloodFill4(x-1,y,oldcolor,newcolor); FloodFill4(x+1,y,oldcolor,newcolor); 設(shè)(x,y)為內(nèi)點(diǎn)表示的4連通區(qū)域內(nèi)的一點(diǎn),oldcolor為區(qū)域的原色,要將整個(gè)區(qū)域填充為新的顏色newcolor。內(nèi)點(diǎn)表示的4連通區(qū)域的遞歸填充算法: 簡單的種子填充算法37void BoundaryFill4(int x,int y,int boundarycolor,int newcolor) int color;if(color!=newcol

17、or & color!=boundarycolor) SetPixel(x,y,newcolor); BoundaryFill4 (x,y+1, boundarycolor,newcolor); BoundaryFill4 (x,y-1, boundarycolor,newcolor); BoundaryFill4 (x-1,y, boundarycolor,newcolor); BoundaryFill4 (x+1,y, boundarycolor,newcolor); 邊界表示的4連通區(qū)域的遞歸填充算法: 38 掃描線種子填充算法簡單種子填充算法原理和程序都很簡單,但由于多次遞歸,費(fèi)時(shí)、費(fèi)

18、內(nèi)存,效率不高。為了減少遞歸次數(shù),提高效率可以采用掃描線種子填充算法。算法的基本過程如下:當(dāng)給定種子點(diǎn)(x,y)時(shí),首先填充種子點(diǎn)所在掃描線上的位于給定區(qū)域的一個(gè)區(qū)段,然后確定與這一區(qū)段相連通的上、下兩條掃描線上位于給定區(qū)域內(nèi)的區(qū)段,并依次保存下來。反復(fù)這個(gè)過程,直到填充結(jié)束。區(qū)域填充的掃描線算法可由下列四個(gè)步驟實(shí)現(xiàn):(1)初始化:堆棧置空。將種子點(diǎn)(x,y)入棧。(2)出棧:若??談t結(jié)束。否則取棧頂元素(x,y),以y作為當(dāng)前掃描線。(3)填充并確定種子點(diǎn)所在區(qū)段:從種子點(diǎn)(x,y)出發(fā),沿當(dāng)前掃描線向左、右兩個(gè)方向填充,直到邊界。分別標(biāo)記區(qū)段的左、右端點(diǎn)坐標(biāo)為xl和xr。 (4)并確定新的

19、種子點(diǎn):在區(qū)間xl,xr中檢查與當(dāng)前掃描線y上、下相鄰的兩條掃描線上的像素。若存在非邊界、未填充的像素,則把每一區(qū)間的最右像素作為種子點(diǎn)壓入堆棧,返回第(2)步。 393.4 文字的生成字符指數(shù)字、字母、漢字等符號(hào)。計(jì)算機(jī)中字符由一個(gè)數(shù)字編碼唯一標(biāo)識(shí)。國際上最流行的字符集是“美國信息交換用標(biāo)準(zhǔn)代碼集”簡稱ASCII碼。它是用7位二進(jìn)制數(shù)進(jìn)行編碼表示128個(gè)字符,包括字母、標(biāo)點(diǎn)、運(yùn)算符以及一些特殊符號(hào)。我國除采用ASCII碼外,還另外制定了漢字編碼的國家標(biāo)準(zhǔn)字符集GB231280。該字符集分為94個(gè)區(qū)、94個(gè)位,每個(gè)符號(hào)由一個(gè)區(qū)碼和一個(gè)位碼共同標(biāo)識(shí)。區(qū)碼和位碼各用一個(gè)字節(jié)表示。為了能夠區(qū)分ASC

20、II碼與漢字編碼,采用字節(jié)的最高位來標(biāo)識(shí):最高位為0表示ASCII碼;最高位為1表示漢字編碼。為了在顯示器等輸出設(shè)備上輸出字符,系統(tǒng)中必須裝備有相應(yīng)的字庫。字庫中存儲(chǔ)了每個(gè)字符的形狀信息,字庫分為矢量和點(diǎn)陣型兩種。 403.4.1 點(diǎn)陣字符 (a)點(diǎn)陣字符 (b)點(diǎn)陣字庫中的位圖表示 (c)矢量輪廓字符在點(diǎn)陣字符庫中,每個(gè)字符由一個(gè)位圖表示。1表示字符的筆畫經(jīng)過此位,對(duì)應(yīng)的像素置為字符顏色。0表示字符的筆畫不經(jīng)過此位,對(duì)應(yīng)于的像素置為背景顏色。在實(shí)際應(yīng)用中,有多種字體(如宋體、楷體等),每種字體又有多種大小型號(hào),因此字庫的存儲(chǔ)空間是很龐大的。解決這個(gè)問題一般采用壓縮技術(shù)。如: 黑白段壓縮;部件

21、壓縮;輪廓字形壓縮等。其中,輪廓字形法壓縮比大,且能保證字符質(zhì)量,是當(dāng)今國際上最流行的一種方法。輪廓字形法采用直線或二/三次bezier曲線的集合來描述一個(gè)字符的輪廓線。輪廓線構(gòu)成一個(gè)或若干個(gè)封閉的平面區(qū)域。輪廓線定義加上一些指示橫寬、豎寬、基點(diǎn)、基線等等控制信息就構(gòu)成了字符的壓縮數(shù)據(jù)。 413.4.2 矢量字符矢量字符記錄字符的筆畫信息而不是整個(gè)位圖,具有存儲(chǔ)空間小,美觀、變換方便等優(yōu)點(diǎn)。對(duì)于字符的旋轉(zhuǎn)、縮放等變換,點(diǎn)陣字符的變換需要對(duì)表示字符位圖中的每一像素進(jìn)行;而矢量字符的變換只要對(duì)其筆畫端點(diǎn)進(jìn)行變換就可以了。矢量字符的顯示也分為兩步。首先從字庫中將它的字符信息檢索出來,然后取出端點(diǎn)坐標(biāo)

22、,對(duì)其進(jìn)行適當(dāng)?shù)膸缀巫儞Q,再根據(jù)各端點(diǎn)的標(biāo)志顯示出字符。 423.5 用Visual C+生成基本圖形 VC+程序需要在屏幕或打印機(jī)上繪圖時(shí),都要調(diào)用GDI(圖形設(shè)備接口)函數(shù)。 3.5.1 圖形設(shè)備接口(GDI)GDI的工作原理大致如下:首先,Windows提供各種顯示卡及打印機(jī)的驅(qū)動(dòng)程序;其次,各種GDI函數(shù)會(huì)自動(dòng)參考被稱為設(shè)備環(huán)境的數(shù)據(jù)結(jié)構(gòu),而Windows則自動(dòng)將設(shè)備環(huán)境結(jié)構(gòu)映射到相應(yīng)的物理設(shè)備,并且提供正確的輸入/輸出指令。GDI在處理速度上幾乎和直接進(jìn)行視頻訪問一樣快,并且它還允許Windows的不同應(yīng)用程序共享顯示器。GDI包含了可用于繪制點(diǎn)、線、矩形、多邊形、橢圓、位圖以及文本

23、的功能函數(shù)。為了方便使用,在VC+中對(duì)其進(jìn)行了封裝,形成了GDI對(duì)象類。 43所有GDI對(duì)象類的抽象基類都是CGdiObject,而所有實(shí)際使用的GDI對(duì)象則是從CGdiObject派生出來的,以下是GDI派生類的列表: nCBitmap位圖,它是一種位圖矩陣,每一個(gè)顯示像素都對(duì)應(yīng)于其中的一個(gè)或多個(gè)位。位圖可以用來表示圖像,也可以用來創(chuàng)建刷子。n CBrush畫刷,通過定義一種位圖矩陣,用它可以對(duì)區(qū)域內(nèi)部進(jìn)行填充。n CPen畫筆,它是用來畫線和繪制有形邊框的。具體使用時(shí),可以指定其顏色和寬度,也可以指定其線型,例如:實(shí)線、虛線或點(diǎn)線。n CFont字體,它是一種具有某種風(fēng)格和尺寸的所有字符的

24、完整集合,常常被當(dāng)作資源存于磁盤中,其中有一些還要依賴某種設(shè)備。n CPalette調(diào)色板,它是一種顏色映射接口,允許一個(gè)應(yīng)用程序在不干擾其他應(yīng)用程序的前提下,充分利用輸出設(shè)備的顏色繪制能力。注意:調(diào)色板一般只在顏色數(shù)為256種或更少的情況下才使用。n CRgn區(qū)域,它是由多邊形、橢圓或者二者組合形成的一種范圍,可以利用它來進(jìn)行填充、裁剪以及鼠標(biāo)點(diǎn)中測試。 443.5.2 VC+繪圖方法用計(jì)算機(jī)繪圖與普通的手工繪圖類似,在OnDraw等函數(shù)中繪制圖形時(shí),必須首先選擇好畫筆和畫刷等繪圖工具,確定好繪圖坐標(biāo)及比例尺,然后根據(jù)需要選用適當(dāng)?shù)睦L圖函數(shù)繪出圖形。因此,與繪圖有關(guān)的圖形程序庫可以分為以下五

25、類:繪圖工具選擇函數(shù)、坐標(biāo)系統(tǒng)設(shè)置與轉(zhuǎn)換函數(shù)、繪圖模式與背景設(shè)置函數(shù)、繪圖函數(shù)和區(qū)域填充函數(shù)。45宏代碼庫存對(duì)象宏代碼庫存對(duì)象BLACK_BRUSH黑色畫刷NULL_BRUSH空畫刷(內(nèi)部不填充)DKGRAY_BRUSH深灰色畫刷WHITE_BRUSH白色畫刷GRAY_BRUSH灰色畫刷BLACK_PEN黑色畫刷HOLLOW_BRUSH透明窗口畫刷NULL_PEN空畫筆(什么也不畫)LTGRAY_BRUSH淺灰色畫刷WHITE_PEN白色畫筆表31 畫刷和畫筆的顏色代碼 函數(shù)原型是:virtual CGdiObject* SelectStockObject(int nIndex);nIndex

26、是所要選入設(shè)備文本對(duì)象的庫存對(duì)象代碼,對(duì)于畫刷和畫筆,其值如表31所示。例如,可以使用以下代碼選擇白色畫筆和黑色畫刷:pDC-SelectStockObject(WHITE_PEN); pDC-SelectStockObject(BLACK_BRUSH); 選擇庫存繪圖工具46畫筆風(fēng)格含義畫筆風(fēng)格含義PS_DASH劃線,即為虛線PS_INSIDEFRAME在邊界區(qū)域內(nèi)實(shí)筆畫線PS_DASHDOT點(diǎn)劃線PS_NULL空畫筆PS_DASHDOTDOT雙點(diǎn)劃線PS_SOLID實(shí)線PS_DOT點(diǎn)線表32 畫筆風(fēng)格與含義 函數(shù)原型為:BOOL CreatePen(int nPenStyle,int nW

27、idth,COLORREF crColor);其中,nPenStyle為畫筆風(fēng)格,其值如表32。nWidth為畫筆的寬度(邏輯單位),crColor用于制定畫筆的顏色。 畫筆對(duì)象初始化后,就可以調(diào)用CDC的成員函數(shù)SelectObject將畫筆選入設(shè)備文本對(duì)象。對(duì)于畫筆,SelectObject的原型為:CPen* SelectObject(CPen* pPen);其中,參數(shù)pPen是指向畫筆對(duì)象的指針。 定制畫筆47畫刷的初始化主要有以下幾種: (1) 純色填充圖形的內(nèi)部。函數(shù)原型為:BOOL CreateSolidBrush(COLORREF crColor);/crColor畫刷顏色(2

28、) 影線模式來填充圖形的內(nèi)部。函數(shù)原型為BOOL CreateHatchBrush (int nIndex,COLORREF crColor);其中,參數(shù)nIndex用于指定影線模式,其值如表33。陰影模式含義陰影模式含義HS_BDIAGONAL反斜線HS_FDIAGONAL斜線HS_CROSS十字線HS_HORIZONAL水平線HS_DIAGCROSS斜十字線HS_VERTICAL豎線表33 影線模式 定制畫刷48(3) 圖案模式來填充圖形的內(nèi)部。函數(shù)原型為: BOOL CreatePatternBrush (CBitmap* pBitmap);其中,參數(shù)pBitmap是指向位圖對(duì)象的指針。

29、當(dāng)用畫刷填充圖形時(shí),圖形內(nèi)部將用位圖一個(gè)接一個(gè)地填充。初始化完畫刷對(duì)象之后,就可以調(diào)用CDC的成員函數(shù)SelectObject將畫刷選入設(shè)備文本對(duì)象。對(duì)于畫刷,SelectObject的原型為: CBrush* SelectObject(CBrush* pBrush);其中,參數(shù)pBrush是指向畫刷對(duì)象的指針。SelectObject返回一個(gè)指向原先已選入設(shè)備文本對(duì)象的畫刷對(duì)象的指針。如果在此之前沒有選擇過畫刷對(duì)象,則使用缺省畫刷。 49邏輯坐標(biāo)是指用戶使用CDC繪圖函數(shù)繪制圖形的坐標(biāo);設(shè)備坐標(biāo)是指計(jì)算機(jī)系統(tǒng)使用輸出設(shè)備(顯示器或打印機(jī))來繪出圖形的坐標(biāo)。設(shè)備坐標(biāo)是用戶不能改變的。設(shè)備坐標(biāo)的

30、原點(diǎn)總是在左上角。改變邏輯坐標(biāo)與設(shè)備坐標(biāo)的關(guān)系使用CDC的映射模式設(shè)置函數(shù)。 映射模式映射模式用于定義邏輯坐標(biāo)的單位與設(shè)備坐標(biāo)間的關(guān)系。在缺省的映射模式下,邏輯坐標(biāo)與設(shè)備坐標(biāo)相同,坐標(biāo)原點(diǎn)也在窗口左上角,以像素為單位,橫坐標(biāo)隨光標(biāo)向右移動(dòng)而增加,縱坐標(biāo)隨光標(biāo)向下移動(dòng)而增加。Windows包含八種不同的映射模式(見表34),每種映射模式在應(yīng)用程序中都有特定的用途。映射模式可細(xì)分為約束映射模式(又稱固定比例映射模式)和非約束映射模式(又稱可變映射模式)。 50映射模式邏輯單位設(shè)備單位軸向MM_HIENGLISH10001英寸X軸向右,Y軸向上MM_HIMETRIC1001毫米MM_LOENGLIS

31、H1001英寸MM_LOMETRIC101毫米MM_TWIPS14401英寸MM_TEXT1設(shè)備像素X軸向右,Y軸向下MM_ANISOTROPICX和Y的比例可以不一致MM_ISOTROPICX和Y的比例一致表34 Windows包含的八種映射模式 51函數(shù)原型為:virtual int SetMapMode(int nMapMode);參數(shù)nMapMode為前面列出的八種映射模式之一。 設(shè)置映射模式設(shè)備坐標(biāo)轉(zhuǎn)換為邏輯坐標(biāo),函數(shù)原型為:void DPtoLP(LPPOINT lpPoints, int nCount = 1);void DPtoLP(LPRECT lpRect);void DP

32、toLP(LPSIZE lpsize);參數(shù)lpPoints是指向POINT結(jié)構(gòu)或CPoint對(duì)象的數(shù)組,nCount表示數(shù)組中的點(diǎn)數(shù)。lpRect指向RECT結(jié)構(gòu)或CRect對(duì)象,使用這個(gè)參數(shù)表示將矩形區(qū)域的設(shè)備點(diǎn)轉(zhuǎn)換為邏輯點(diǎn)。lpsize指向SIZE結(jié)構(gòu)或CSize對(duì)象。邏輯坐標(biāo)轉(zhuǎn)換為設(shè)備坐標(biāo),函數(shù)原型為:void LPtoDP(LPPOINT lpPoints, int nCount = 1);void LPtoDP(LPRECT lpRect);void LPtoDP(LPSIZE lpsize);52 設(shè)置繪圖模式繪 圖描 述R2_BLACK 像素總為黑色R2_WHITE 像素總為白

33、色R2_NOP 像素保持不變R2_NOT 像素為顯示顏色的反轉(zhuǎn)色R2_COPYPEN 缺省繪圖模式,像素為畫筆顏色R2_NOTCOPYPEN 像素為畫筆顏色的反轉(zhuǎn)色R2_MASKPEN 像素為顯示顏色與畫筆顏色的公共顏色的組合R2_NOTMASKPEN 像素為R2_MASKPEN顏色反轉(zhuǎn)色R2_XORPEN 像素為畫筆顏色與顯示顏色的組合,但不同時(shí)為這兩種顏色R2_NOTXOPEN 像素為R2_XORPEN顏色反轉(zhuǎn)色改變繪圖模式的函數(shù)原型為:int SetROP2(int nDrawMode);參數(shù)nDrawMode指定所要求的繪圖模式,其值如下表: 53 背景顏色設(shè)置函數(shù)原型為:virtua

34、l COLORREF SetBkColor(COLORREF crColor); 背景模式設(shè)置指定顯示時(shí)采用透明方式還是不透明方式。函數(shù)原型為:int SetBkMode(int nBkMode);參數(shù)nBkMode指定背景模式,其值可以為OPAQUE或TRANSPARENT。 繪圖函數(shù)(1)設(shè)置像素(畫點(diǎn))函數(shù)原型為:COLORREF SetPixel(int x,int y, COLORREF,crColor);COLORREF SetPixel(POINT point, COLORREF,crColor);像素點(diǎn)的位置由參數(shù)x和y或者point指定,crColor指定顏色。畫出一個(gè)半徑為

35、5像素的圓并以黑色填充之,得到一個(gè)比較大的點(diǎn):void CDrowDotView:OnDraw(CDC* pDC) pDC-SelectStockObject(BLACK_BRUSH); /畫出的點(diǎn)為黑色 pDC-Ellipse(CRect(5,10,10,15); / 畫一個(gè)小圓54(2)畫直線MoveTo函數(shù)的原型為:CPoint MoveTo(int x,int y);/當(dāng)前位置由參數(shù)x和y指定CPoint MoveTo(POINT point);/當(dāng)前位置由point指定繪制直線函數(shù)原型為:BOOL LineTo(int x,int y);BOOL LineTo(POINT point

36、);可以調(diào)用Polyline函數(shù)畫一系列直線。函數(shù)原型為:BOOL Polyline(LPPOINT lpPoints,int nCount);lpPoints指定包含線段頂點(diǎn)的POINT結(jié)構(gòu)數(shù)組,nCount指定數(shù)組中的點(diǎn)數(shù)。畫一條從(5,5)到(50,50)的直線,則程序代碼如下:void CDrawLineView: OnDraw(CDC* pDC) pDC-MoveTo(5,5); pDC-LineTo(50,50);55(3) 畫矩形畫矩形有兩個(gè)CDC 成員函數(shù):Rectangle和RoundRect。函數(shù)Rectangle畫的是方角矩形,而函數(shù)RoundRect畫的是圓角矩形。函數(shù)

37、Rectangle的原型為:BOOL Rectangle(int x1,int y1,int x2,int y2);BOOL Rectangle(LPCRECT lpRect);矩形區(qū)域由參數(shù)(x1,y1)和(x2,y2)或者lpRect指定。左上角坐標(biāo)為(x1,y1),右下角坐標(biāo)為(x2,y2)。函數(shù)RoundRect的原型為:BOOL RoundRect(int x1,int y1,int x2,int y2,intx3,int y3 );BOOL RoundRect(LPCRECT lpRect,POINT point);矩形區(qū)域由參數(shù)(x1,y1)和(x2,y2)或者lpRect指定。左上角坐標(biāo)為(x1,y1),右下角坐標(biāo)為(x2,y2)。矩形區(qū)域的圓角由(x3,y3)或者point確定,x3和y3分別指定圓角曲線的寬度和高度。 56(4) 畫弧畫弧函數(shù)用邊界矩形來定義弧的大小。邊界矩形是隱藏的,用于描述

溫馨提示

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

評(píng)論

0/150

提交評(píng)論