計(jì)算機(jī)圖形學(xué)畫(huà)多邊形_第1頁(yè)
計(jì)算機(jī)圖形學(xué)畫(huà)多邊形_第2頁(yè)
計(jì)算機(jī)圖形學(xué)畫(huà)多邊形_第3頁(yè)
計(jì)算機(jī)圖形學(xué)畫(huà)多邊形_第4頁(yè)
計(jì)算機(jī)圖形學(xué)畫(huà)多邊形_第5頁(yè)
已閱讀5頁(yè),還剩36頁(yè)未讀 繼續(xù)免費(fèi)閱讀

下載本文檔

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

文檔簡(jiǎn)介

1、基本圖形的生成計(jì)算機(jī)圖形學(xué)已成為計(jì)算機(jī)技術(shù)中發(fā)展最快的領(lǐng)域,計(jì)算機(jī)圖形軟件也相應(yīng)得到快速發(fā)展。計(jì)算機(jī)繪圖顯示有屏幕顯示、打印機(jī)打印圖樣和繪圖機(jī)輸出圖樣等方式,其中用屏幕顯示圖樣是計(jì)算機(jī)繪圖的重要內(nèi)容。計(jì)算機(jī)上常見(jiàn)的顯示器為光柵圖形顯示器,光柵圖形顯示器可以看作像素的矩陣。像素是組成圖形的基本元素,一般稱為“點(diǎn)”。通過(guò)點(diǎn)亮一些像素,滅掉另一些像素,即在屏幕上產(chǎn)生圖形。在光柵顯示器上顯示任何一種圖形必須在顯示器的相應(yīng)像素點(diǎn)上畫(huà)上所需顏色,即具有一種或多種顏色的像素集合構(gòu)成圖形。確定最佳接近圖形的像素集合,并用指定屬性寫(xiě)像素的過(guò)程稱為圖形的掃描轉(zhuǎn)換或光柵化。對(duì)于一維圖形,在不考慮線寬時(shí),用一個(gè)像素寬

2、的直、曲線來(lái)顯示圖形。二維圖形的光柵化必須確定區(qū)域?qū)?yīng)的像素集,并用指定的屬性或圖案進(jìn)行顯示,即區(qū)域填充。復(fù)雜的圖形系統(tǒng),都是由一些最基本的圖形元素組成的。利用計(jì)算機(jī)編制圖形軟件時(shí),編制基本圖形元素是相當(dāng)重要的,也是必需的。點(diǎn)是基本圖形,本章主要講述如何在指定的輸出設(shè)備(如光柵圖形顯示器)上利用點(diǎn)構(gòu)造其他基本二維幾何圖形(如點(diǎn)、直線、圓、橢圓、多邊形域及字符串等)的算法與原理,并利用VisualC+編程實(shí)現(xiàn)這些算法。直線數(shù)學(xué)上,理想的直線是由無(wú)數(shù)個(gè)點(diǎn)構(gòu)成的集合,沒(méi)有寬度。計(jì)算機(jī)繪制直線是在顯示器所給定的有限個(gè)像素組成的矩陣中,確定最佳逼近該直線的一組像素,并且按掃描線順序,對(duì)這些像素進(jìn)行寫(xiě)操作

3、,實(shí)現(xiàn)顯示器繪制直線,即通常所說(shuō)的直線的掃描轉(zhuǎn)換,或稱直線光柵化。由于一圖形中可能包含成千上萬(wàn)條直線,所以要求繪制直線的算法應(yīng)盡可能地快。本節(jié)介紹一個(gè)像素寬直線的常用算法:數(shù)值微分法(DDA)、中點(diǎn)畫(huà)線法、Bresenham算法。DDA(數(shù)值微分)算法圖1-1 DDA方法掃描轉(zhuǎn)換連接兩點(diǎn)DDA算法原理:如圖1-1所示,已知過(guò)端點(diǎn)p0(x0,yo),Pl(x1,y1)的直線段p0P1;直線斜率為,y1一V。k二x1x。,從X的左端點(diǎn)x。開(kāi)始,向X右端點(diǎn)步進(jìn)畫(huà)線,步長(zhǎng)=1(個(gè)像素),計(jì)算相應(yīng)的y坐標(biāo)y-kxB;取像素點(diǎn)X,round(y)作為當(dāng)前點(diǎn)的坐標(biāo)。計(jì)算yi1=kxi1B=kx1Bkx=y1

4、kxx =1, Vi 1 =Vi k,即當(dāng)x每遞增1, y遞增k (即直線圖1-2中點(diǎn)畫(huà)線法每步迭代涉及的像素和中點(diǎn)示意圖斜率)。注意:上述分析的算法僅適用于k0;在直線下方,F(x,y)0。把M代入F(x,y),判斷F的符號(hào),可知Q點(diǎn)在中點(diǎn)M的上方還是下方。為此構(gòu)造判別式d=F(M尸F(xiàn)(xp+1,yp+0.5)=a(xp+1)+b(yp+0.5)+c。當(dāng)d0,L(Q點(diǎn))在M下方,取Pi為下一個(gè)像素。當(dāng)d=0,選Pi或P2均可,取Pi為下一個(gè)像素。其中d是xp,yp的線性函數(shù)。Bresenham算法Bresenham算法是計(jì)算機(jī)圖形學(xué)領(lǐng)域使用最廣泛的直線掃描轉(zhuǎn)換算法。由誤差項(xiàng)符號(hào)決定下一個(gè)像素

5、取右邊點(diǎn)還是右上方點(diǎn)。設(shè)直線從起點(diǎn),y1)到終點(diǎn)(x2,y2)。直線可表示為方程y=mx+b,其中b=y1mx,m=(y2y)/(x2二1)=dy/dx;此處的討論直線方向限于第一象限,如圖1-3所示,當(dāng)直線光柵化時(shí),x每次都增加1個(gè)單元,設(shè)x像素為(xi,yi)o下一圖1-3第一象限直線光柵化個(gè)像素的列坐標(biāo)為K+1,行坐標(biāo)為yi或者遞增1為yi+1,Bresenham算法由y與y及yi+1的距離d1及d2的大小而定。計(jì)算公式為y=m(xi+1)+bd1=y-yid2=yi+1-y如果d1-d20,貝Uyi+1=yi+1,否貝Uyi+1=yi。式(1.1)、(1.2)、(1.3)代入d10,則

6、yi+1=yi+1,否則yi+1=yi。(3)畫(huà)點(diǎn)(xi+1,yi+1)。(4)求下一個(gè)誤差Pi+1,如果Pi0,則Pi+1=Pi+2dyNdx,否則Pi+1=Pi+2dy。(5)i=i+1;如果idx+1則轉(zhuǎn)步驟(2);否則結(jié)束操作。1.1.4程序設(shè)計(jì).程序設(shè)計(jì)功能說(shuō)明為編程實(shí)現(xiàn)上述算法,本程序利用最基本的繪制元素(如點(diǎn)、直線等),繪制圖形。如圖1-4所示,為程序運(yùn)行主界面,通過(guò)選擇菜單及下拉菜單的各功能項(xiàng)分別完成各種對(duì)應(yīng)算法的圖形繪制。圖1-4基本圖形生成的程序運(yùn)行界面.創(chuàng)建工程名稱為“基本圖形的生成”單文檔應(yīng)用程序框架(1)啟動(dòng)VC,選擇“文件”|“新建”菜單命令,并在彈出的新建對(duì)話框中

7、單擊“工程”標(biāo)簽。(2)選擇MFCAppWizard(exe),在“工程名稱”編輯框中輸入“基本圖形的生成”作為工程名稱,單擊“確定”按鈕,出現(xiàn)Step1對(duì)話框。(3)選擇“單個(gè)文檔”選項(xiàng),單擊“下一個(gè)”按鈕,出現(xiàn)Step2對(duì)話框。(4)接受默認(rèn)選項(xiàng),單擊“下一個(gè)”按鈕,在出現(xiàn)的Step3Step5對(duì)話框中,接受默認(rèn)選項(xiàng),單擊“下一個(gè)”按鈕。(5)在Step6對(duì)話框中單擊“完成”按鈕,即完成“基本圖形的生成”應(yīng)用程序的所有選項(xiàng),隨后出現(xiàn)工程信息對(duì)話框(記錄以上步驟各選項(xiàng)選擇情況),如圖1-5所示,單擊“確定”按鈕,完成應(yīng)用程序框架的創(chuàng)建。圖1-5信息程序基本.編輯菜單資源設(shè)計(jì)如圖1-4所示的菜

8、單項(xiàng)。在工作區(qū)的ResourceView標(biāo)簽中,單擊Menu項(xiàng)左邊+,然后雙擊其子項(xiàng)IDR_MAINFRAME,并根據(jù)表1-1中的定義編輯菜單資源。此時(shí)VC已自動(dòng)建好程序框架,如圖1-5所示。表1-1菜單資源表菜單標(biāo)題菜單項(xiàng)標(biāo)題標(biāo)小付ID直線DDA算法生成直線ID_DDALINEBresenham算法生成直線ID_BRESENHAMLINE中點(diǎn)算法生成直線ID_MIDPOINTLINE4.添加消息處理函數(shù)利用ClassWizard(建立類向?qū)В閼?yīng)用程序添加與菜單項(xiàng)相關(guān)的消息處理函數(shù),ClassName欄中選擇CMyView,根據(jù)表1-2建立如下的消息映射函數(shù),ClassWizard會(huì)自動(dòng)完成

9、有關(guān)的函數(shù)聲明。表1-2菜單項(xiàng)的消息處理函數(shù)菜單項(xiàng)ID消息消息處理函數(shù)ID_DDALINECONMMANOnDdalineID_MIDPOINTLINECONMMANOnMidpointlineID_BRESENHAMLINECONMMANOnBresenhamline5.程序結(jié)構(gòu)代碼,在CMyView.cpp文件中相應(yīng)位置添加如下代碼:/DDA算法生成直線voidCMyView:OnDdaline()CDC*pDC=GetDC();/獲得設(shè)備指針intxa=100,ya=300,xb=300,yb=200,c=RGB(255,0,0);定義直線的兩端點(diǎn),直線顏色intx,y;floatdx,

10、dy,k;dx=(float)(xb-xa),dy=(float)(yb-ya);k=dy/dx,y=ya;if(abs(k)1)for(x=xa;xSetPixel(x,int(y+0.5),c);y=y+k;if(abs(k)=1)for(y=ya;ySetPixel(int(x+0.5),y,c);x=x+1/k;ReleaseDC(pDC);說(shuō)明:(1)以上代碼理論上通過(guò)定義直線的兩端點(diǎn),可得到任意端點(diǎn)之間的一直線,但由于x, y值,屏幕坐標(biāo)與窗口坐標(biāo)之間轉(zhuǎn)換一般屏幕坐標(biāo)采用右手系坐標(biāo),屏幕上只有正的知識(shí)請(qǐng)參考第3章。(2)注意上述程序考慮到當(dāng)k1時(shí),y每增加1,x相應(yīng)增加1/ko在這

11、個(gè)算法中,y與k用浮點(diǎn)數(shù)表示,而且每一步都要對(duì)y進(jìn)行四舍五入后取整。中點(diǎn)算法生成直線voidCMyView:OnMidpointline()CDC*pDC=GetDC();intxa=300,ya=200,xb=450,yb=300,c=RGB(0,255,0);floata,b,d1,d2,d,x,y;a=ya-yb,b=xb-xa,d=2*a+b;d1=2*a,d2=2*(a+b);x=xa,y=ya;pDC-SetPixel(x,y,c);while(xxb)if(dSetPixel(x,y,c);ReleaseDC(pDC);說(shuō)明:(1)其中d是Xp,yp的線性函數(shù)。為了提高運(yùn)算效率,

12、程序中采用增量計(jì)算。具體算法如下:若當(dāng)前像素處于d0情況,則取正右方像素P1(Xp+1,yp),判斷下一個(gè)像素點(diǎn)的位置,應(yīng)計(jì)算d1=F(Xp+2,yp+0.5)=a(Xp+2)+b(yp+0.5)=d+a;,其中增量為a。若d=0)s1=1;elses1=-1;if(y2-y1=0)s2=1;elses2=-1;if(deltaydeltax)temp=deltax;deltax=deltay;deltay=temp;interchange=1;elseinterchange=0;f=2*deltay-deltax;pDC-SetPixel(x,y,c);for(i=1;i=0)if(inte

13、rchange=1)x+=s1;elsey+=s2;pDC-SetPixel(x,y,c);f=f-2*deltax;elseif(interchange=1)y+=s2;elsex+=s1;f=f+2*deltay;說(shuō)明:(1)以上程序已經(jīng)考慮到所有象限直線的生成。(2)Bresenham算法的優(yōu)點(diǎn)如下:不必計(jì)算直線的斜率,因此不做除法。不用浮點(diǎn)數(shù),只用整數(shù)。只做整數(shù)加減運(yùn)算和乘2運(yùn)算,而乘2運(yùn)算可以用移位操作實(shí)現(xiàn)。Bresenham算法的運(yùn)算速度很快。1.2圓給出圓心坐標(biāo)(Xc,yc)和半徑r,逐點(diǎn)畫(huà)出一個(gè)圓周的公式有下列兩種。直角坐標(biāo)法直角坐標(biāo)系的圓的方程為由上式導(dǎo)出:.-2-2yyc-

14、r-(x-Xc)當(dāng)Xx從t到r做加1遞增時(shí),就可以求出對(duì)應(yīng)的圓周點(diǎn)的y坐標(biāo)。但是這樣求出的圓周上的點(diǎn)是不均勻的,|x二c|越大,對(duì)應(yīng)生成圓周點(diǎn)之間的圓周距離也就越長(zhǎng)。因此,所生成的圓不美觀。中點(diǎn)畫(huà)圓法如圖1-6所示,函數(shù)為F(xy)=x2+y2R2的構(gòu)造圓,圓上的點(diǎn)為F(x,y)=0,圓外的點(diǎn)F(x,y)0,圓內(nèi)的點(diǎn)F(x,y)0,構(gòu)造判別式:d=F(M)=F(xp+1,yp-0.5)=(xp+1)2+(yp-0.5)2若d0,則應(yīng)取P2為下一像素,而且下一像素的判別式為d=F(xp+2,yp-1.5)=(xp+2)2+(ypT.5)2R2=d+2(xpyp)+5我們討論按順時(shí)針?lè)较蛏傻诙€(gè)

15、八分圓,則第一個(gè)像素是(0,R),判別式d的初始值為do=F(1,R05)=1.25-R圓的Bresenham算法設(shè)圓的半徑為r,先考慮圓心在(0,0),從x=0、y=r開(kāi)始的順時(shí)針?lè)较虻?/8圓周的生成過(guò)程。在這種情況下,x每步增加1,從x=0開(kāi)始,至ijx=y結(jié)束,即有xi+1=xi+1;相應(yīng)的,yi+1則在兩種可能中選擇:yi+產(chǎn)yi或者yi+1=yi-1。選擇的原則是考察精確值y是靠近yi還是靠近yi-1(見(jiàn)圖1-7),計(jì)算式為y2=r2-(xi+1)2d1=yi2-y2=yi2-r2+(xi+1)2d2=y2(yiT)2=r21xi+1)2yi-1)2令pi=d1-d2,并代入drd

16、2,則有圖1-7確定y的位置pi=2(xi+1)2+yi2+(yi-1)2-2r2(1.6)pi稱為誤差。如果piSetPixel(xc+x),(yc+y),c);pDC-SetPixel(xc-x),(yc+y),c);pDC-SetPixel(xc+x),(yc-y),c);pDC-SetPixel(xc-x),(yc-y),c);pDC-SetPixel(xc+y),(yc+x),c);pDC-SetPixel(xc-y),(yc+x),c);pDC-SetPixel(xc+y),(yc-x),c);pDC-SetPixel(xc-y),(yc-x),c);while(x=y)if(dS

17、etPixel(xc+x),(yc+y),c);pDC-SetPixel(xc-x),(yc+y),c);pDC-SetPixel(xc+x),(yc-y),c);pDC-SetPixel(xc-x),(yc-y),c);pDC-SetPixel(xc+y),(yc+x),c);pDC-SetPixel(xc-y),(yc+x),c);pDC-SetPixel(xc+y),(yc-x),c);pDC-SetPixel(xc-y),(yc-x),c);/ Bresenham 算法繪制圓,如圖 1-10 所示圖 1-10 Bresenham 算法繪制圓voidCMyView:OnBresenham

18、circle()CDC*pDC=GetDC();intxc=100,yc=100,radius=50,c=0;intx=0,y=radius,p=3-2*radius;while(xSetPixel(xc+x,yc+y,c);pDC-SetPixel(xc-x,yc+y,c);pDC-SetPixel(xc+x,yc-y,c);pDC-SetPixel(xc-x,yc-y,c);pDC-SetPixel(xc+y,yc+x,c);pDC-SetPixel(xc-y,yc+x,c);pDC-SetPixel(xc+y,yc-x,c);pDC-SetPixel(xc-y,yc-x,c);if(pS

19、etPixel(xc+x,yc+y,c);pDC-SetPixel(xc-x,yc+y,c);pDC-SetPixel(xc+x,yc-y,c);pDC-SetPixel(xc-x,yc-y,c);pDC-SetPixel(xc+y,yc+x,c);pDC-SetPixel(xc-y,yc+x,c);pDC-SetPixel(xc+y,yc-x,c);pDC-SetPixel(xc-y,yc-x,c);橢圓掃描轉(zhuǎn)換中點(diǎn)算法其方程為1-11所示)。下面討論橢圓的掃描轉(zhuǎn)換中點(diǎn)算法,設(shè)橢圓為中心在坐標(biāo)原點(diǎn)的標(biāo)準(zhǔn)橢圓,F(x,y)=b2x2+a2y2-a2b2=0(1)對(duì)于橢圓上的點(diǎn),有F(x,y)=

20、0;(2)對(duì)于橢圓外的點(diǎn),F(xiàn)(x,y)0;(3)對(duì)于橢圓內(nèi)的點(diǎn),F(xiàn)(x,y)0。圖 1-11第一象限的橢圓弧以弧上斜率為-1的點(diǎn)作為分界將第一象限橢圓弧分為上下兩部分(如圖法向量:而在下一個(gè)點(diǎn),不等號(hào)改變方向,則說(shuō)明橢圓弧從上部分轉(zhuǎn)入下部分。與中點(diǎn)繪制圓算法類似,一個(gè)像素確定后,在下面兩個(gè)候選像素點(diǎn)的中點(diǎn)計(jì)算一個(gè)判別式的值,再根據(jù)判別式符號(hào)確定離橢圓最近的點(diǎn)。先看橢圓弧的上半部分,具體算法如下:假設(shè)橫坐標(biāo)為xp的像素中與橢圓最近點(diǎn)為(xp,yp),下一對(duì)候選像素的中點(diǎn)應(yīng)為(xp+1,ypK.5),判別式為diSetPixel(x+300,y+200,c);pDC-SetPixel(-x+300

21、,y+200,c);pDC-SetPixel(x+300,-y+200,c);pDC-SetPixel(-x+300,-y+200,c);while(b*b*(x+1)a*a*(y-0.5)if(d1SetPixel(x+xc,y+yc,c);pDC-SetPixel(-x+xc,y+yc,c);pDC-SetPixel(x+xc,-y+yc,c);pDC-SetPixel(-x+xc,-y+yc,c);d2=sqrt(b*(x+0.5)+a*(y-1)-a*b;while(y0)if(d2SetPixel(x+xc,y+yc,c);pDC-SetPixel(-x+xc,y+yc,c);pDC

22、-SetPixel(x+xc,-y+yc,c);pDC-SetPixel(-x+xc,-y+yc,c);多邊形的掃描轉(zhuǎn)換與區(qū)域填充在計(jì)算機(jī)圖形學(xué)中,多邊形有兩種重要的表示方法:頂點(diǎn)表示和點(diǎn)陣表示。頂點(diǎn)表示是用多邊形的頂點(diǎn)序列來(lái)表示多邊形,特點(diǎn)直觀、幾何意義強(qiáng)、占內(nèi)存少,易于進(jìn)行幾何變換,但由于它沒(méi)有明確指出哪些像素在多邊形內(nèi),故不能直接用于面著色。點(diǎn)陣表示是用位于多邊形內(nèi)的像素集合來(lái)刻畫(huà)多邊形。這種表示丟失了許多幾何信息,但便于幀緩沖器表示圖形,是面著色所需要的圖形表示形式。光柵圖形的一個(gè)基本問(wèn)題是把多邊形的頂點(diǎn)表示轉(zhuǎn)換為點(diǎn)陣表示。這種轉(zhuǎn)換稱為多邊形的掃描轉(zhuǎn)換。多邊形的掃描轉(zhuǎn)換多邊形可分為凸多

23、邊形、凹多邊形、含內(nèi)環(huán)多邊形。(1)凸多邊形:任意兩頂點(diǎn)間的連線均在多邊形內(nèi)。(2)凹多邊形:任意兩頂點(diǎn)間的連線有不在多邊形內(nèi)的部分。(3)含內(nèi)環(huán)多邊形:多邊形內(nèi)包含有封閉多邊形。掃描線多邊形區(qū)域填充算法是按掃描線順序,計(jì)算掃描線與多邊形的相交區(qū)間,再用要求的顏色顯示這些區(qū)間的像素。區(qū)間的端點(diǎn)可以通過(guò)計(jì)算掃描線與多邊形邊界線的交點(diǎn)獲得。對(duì)于一條掃描線,多邊形的填充過(guò)程可以分為4個(gè)步驟。(1)求交:計(jì)算掃描線與多邊形各邊的交點(diǎn)。(2)排序:把所有交點(diǎn)按x值遞增順序排序。(3)配對(duì):第一個(gè)與第二個(gè),第三個(gè)與第四個(gè)等,每對(duì)交點(diǎn)代表掃描線與多邊形的一個(gè)相交區(qū)間。(4)填色:把相交區(qū)間內(nèi)的像素置成多邊形

24、顏色,把相交區(qū)間外的像素置成背景色。具體實(shí)現(xiàn)方法:為多邊形的每一條邊建立一邊表;為了提高效率,在處理一條掃描線時(shí),僅對(duì)與它相交的多邊形的邊進(jìn)行求交運(yùn)算。把與當(dāng)前掃描線相交的邊稱為活性邊,并把它們按與掃描線交點(diǎn)遞增的順序存放在一個(gè)鏈表中,稱此鏈表為活性邊表。另外使用增量法計(jì)算時(shí),需要知道一條邊何時(shí)不再與下一條掃描線相交,以便及時(shí)把它從掃描線循環(huán)中刪除出去。為了方便活性邊表的建立與更新,為每一條掃描線建立一個(gè)新邊表(NET),存放在該掃描線第一次出現(xiàn)的邊。為使程序簡(jiǎn)單、易讀,這里新邊表的結(jié)構(gòu)應(yīng)保存其對(duì)應(yīng)邊如下信息:當(dāng)前邊的邊號(hào)、邊的較低端點(diǎn)(Xmin,ymin)與邊的較高端點(diǎn)(Xmax,ymax)

25、和從當(dāng)前掃描線到下一條掃描線間X的增量AX。相鄰掃描線間X的增量位的計(jì)算,假定當(dāng)前掃描線與多邊形某一條邊的交點(diǎn)的X坐標(biāo)為X,則下一條掃描線與該邊的交點(diǎn)不要重計(jì)算,只要加一個(gè)增量AXo設(shè)該邊的直線方程為aX+by+c=0;若y=yi,X=Xi;貝U當(dāng)y=yi+i時(shí)其中&=4為常數(shù)。掃描線與多邊形頂點(diǎn)相交的處理方法如圖1-14所示。圖1-14掃描線與多邊形相交,(1)掃描線與多邊形相交的邊分別處于掃描線的兩側(cè),特殊情況的處理則記為一個(gè)交點(diǎn),如點(diǎn)P5,P6。(2)掃描線與多邊形相交的邊分別處于掃描線同側(cè),且yiyi1,yiyi.1,yiyi+1,則計(jì)0個(gè)交點(diǎn)(不填色),如P1。(3)掃描線與多邊形邊

26、界重合(當(dāng)要區(qū)分邊界和邊界內(nèi)區(qū)域時(shí)需特殊處理),則計(jì)1個(gè)交點(diǎn)。具體實(shí)現(xiàn)時(shí),只需檢查頂點(diǎn)的兩條邊的另外兩個(gè)端點(diǎn)的y值。按這兩個(gè)y值中大于交點(diǎn)y值的個(gè)數(shù)是0,1,2來(lái)決定。算法步驟如下:(1)初始化:構(gòu)造邊表。(2)對(duì)邊表進(jìn)行排序,構(gòu)造活性邊表。(3)對(duì)每條掃描線對(duì)應(yīng)的活性邊表中求交點(diǎn)。(4)判斷交點(diǎn)類型,并兩兩配對(duì)。(5)對(duì)符合條件的交點(diǎn)之間用畫(huà)線方式填充。(6)下一條掃描線,直至滿足掃描結(jié)束條件。區(qū)域填充算法這里的區(qū)域指已表示成點(diǎn)陣形式的填充圖形,是像素的集合。區(qū)域有兩種表示形式:內(nèi)點(diǎn)表示和邊界表示,如圖1-15所示。內(nèi)點(diǎn)表示,即區(qū)域內(nèi)的所有像素有相同顏色;邊界表示,即區(qū)域的邊界點(diǎn)有相同顏色。

27、區(qū)域填充指先將區(qū)域的一點(diǎn)賦予指定的顏色,然后將該顏色擴(kuò)展到整個(gè)區(qū)域的過(guò)程。區(qū)域填充算法要求區(qū)域是連通的。區(qū)域可分為4向連通區(qū)域和8向連通區(qū)域,如圖1-16所示。4向連通區(qū)域指的是從區(qū)域上一點(diǎn)出發(fā),可通過(guò)四個(gè)方向,即上、下、左、右移動(dòng)的組合,在不越出區(qū)域的前提下,到達(dá)區(qū)域內(nèi)的任意像素;8向連通區(qū)域指的是從區(qū)域內(nèi)每一像素出發(fā),可通過(guò)8個(gè)方向,即上、下、左、右、左上、右上、左下、右下這八個(gè)方向的移動(dòng)的組合來(lái)到達(dá)。圖1-15區(qū)域的內(nèi)點(diǎn)表示和邊界表示圖1-164連通區(qū)域和8連通區(qū)域區(qū)域填充的遞歸算法上面討論的多邊形填充算法是按掃描線順序進(jìn)行的。種子填充算法則是假設(shè)在多邊形內(nèi)有一像素已知,由此出發(fā)利用連通

28、性填充區(qū)域內(nèi)的所有像素。一般采用多次遞歸方式。區(qū)域填充的掃描線算法算法的基本過(guò)程如下:給定種子點(diǎn)(x,y),首先填充種子點(diǎn)所在掃描線上給定區(qū)域的一個(gè)區(qū)段,然后確定與這一區(qū)段相連通的上、下兩條掃描線上位于給定區(qū)域內(nèi)的區(qū)段,并依次保存下來(lái)。反復(fù)這個(gè)過(guò)程,直到填充結(jié)束。區(qū)域填充的掃描線算法可由下列3個(gè)步驟實(shí)現(xiàn)。(1)初始化:確定種子點(diǎn)元素(x,y)。(2)判斷種子點(diǎn)(x,y)是否滿足非邊界、非填充色的條件,若滿足條件,以y作為當(dāng)前掃描線沿當(dāng)前掃描線向左、右兩個(gè)方向填充,直到邊界。(3)確定新的種子點(diǎn):檢查與當(dāng)前掃描線y上、下相鄰的兩條掃描線上的像素。若存在非邊界、未填充的像素,則返回步驟(2)進(jìn)行掃

29、描填充。直至區(qū)域所有元素均為填充色,程序結(jié)束。掃描線填充算法提高了區(qū)域填充的效率。程序設(shè)計(jì)的步驟如下:(1)創(chuàng)建應(yīng)用程序框架,以上述單文檔程序框架為基礎(chǔ),創(chuàng)建如圖1-17所示應(yīng)用程序界面。(2)編輯菜單資源。在工作區(qū)的ResourceView標(biāo)簽中,單擊Menu項(xiàng)左邊“+”,然后雙擊其子項(xiàng)IDR_MAINFRAME,并根據(jù)表1-7中的定義添加編輯菜單資源。此時(shí)建好的菜單如圖1-18所示。圖1-17程序界面表1-7菜單資源表菜單標(biāo)題菜單項(xiàng)標(biāo)題標(biāo)小付ID區(qū)域盛多邊形掃描填充ID_MIDPOINTELLISPE圖1-18程序主菜單(3)添加消息處理函數(shù)。利用ClassWizard(建立類向?qū)?為應(yīng)用

30、程序添加與菜單項(xiàng)相關(guān)的消息處理函數(shù),ClassName欄中選擇CMyView,根據(jù)表1-8建立如下的消息映射函數(shù),ClassWizard會(huì)自動(dòng)完成有關(guān)的函數(shù)聲明。表1-8菜單項(xiàng)的消息處理函數(shù)菜單項(xiàng)ID消息消息處理函數(shù)ID_MIDPOINTELLISPECONMMANOnMidpointellispe(4)添加程序結(jié)構(gòu)代碼。在“基本圖形的生成View.h”適當(dāng)位置添加以下黑體字部分代碼:typedefstruct/建立邊表結(jié)構(gòu)intnum,ymin,ymax;floatxmin,xmax,dx;Edge;classCMyView:publicCViewprotected:/createfroms

31、erializationonlypublic:Cpointptset7;Edgeedge7,edge17,newedge1;在OnDraw()函數(shù)中添加如下黑體字部分代碼。voidCMyView:OnDraw(CDC*pDC)/繪制要填充的多邊形CMyDoc*pDoc=GetDocument();ASSERT_VALID(pDoc);CPennewpen(PS_SOLID,1,RGB(255,0,0);CPen*old=pDC-SelectObject(&newpen);pDC-TextOut(20,20,“雙擊鼠標(biāo)左鍵,出現(xiàn)需填充的多邊形,點(diǎn)擊相關(guān)功能菜單實(shí)現(xiàn)區(qū)域填充”);pDC-TextO

32、ut(20,50,“進(jìn)行種子填充,需用鼠標(biāo)右鍵,單擊多邊形內(nèi)一點(diǎn),作為開(kāi)始填充的種子點(diǎn)”);pDC-SelectObject(old);在菜單項(xiàng)的消息處理函數(shù)實(shí)體中添加以下黑體字部分代碼。voidCMyView:OnScanfill()CDC*pDC=GetDC();/掃描線算法進(jìn)行多邊形區(qū)域填充,如圖1-19所示CPennewpen(PS_SOLID,1,RGB(0,255,0);CPen*old=pDC-SelectObject(&newpen);intj,k,s=0;intp5;/每根掃描線交點(diǎn)intpmin,pmax;for(inti=0;i6;i+)/建立邊表圖1-19掃描線算法區(qū)域

33、填充edgei.dx=(float)(spti+1.x-spti.x)/(spti+1.y-spti.y);if(spti.y=spti+1.y)edgei.num=i;edgei.ymin=spti.y;edgei.ymax=spti+1.y;edgei.xmin=(float)spti.x;edgei.xmax=(float)spti+1.x;pmax=spti+1.y;pmin=spti.y;elseedgei.num=i;edgei.ymin=spti+1.y;edgei.ymax=spti.y;edgei.xmax=(float)spti.x;edgei.xmin=(float)sp

34、ti+1.x;pmax=spti.y;pmin=spti+1.y;for(intr=1;r6;r+)/排序edge(yUpper,xIntersect)for(intq=0;q6-r;q+)if(edgeq.yminpmin+1;scan-)intb=0;k=s;for(j=k;jedgej.ymin)&(scan=edgej.ymax)/判斷與線段相交if(scan=edgej.ymax)if(sptedgej.num+1.yedgej.ymax)b+;pb=(int)edgej.xmax;if(sptedgej.num-1.yedgej.ymin)&(scanLineTo(sptedge0

35、.num.x,sptedge0.num.y);if(scan1)for(intu=1;uMoveTo(pu+3,scan);u+;pDC-LineTo(pu,scan);pDC-SelectObject(old);說(shuō)明:雙擊,出現(xiàn)需填充的多邊形,單擊相關(guān)功能菜單實(shí)現(xiàn)區(qū)域填充。1-20 所示voidCMyView:OnSeedfill()/種子算法進(jìn)行多邊形區(qū)域填充,如圖CWindowDCdc(this);圖 1-20種子算法區(qū)域填充intfill=RGB(0,255,0);intboundary=RGB(255,0,0);CPointpt=s_point;intx,y,p0,pmin,pmax

36、;/求多邊形的最大最小值for(intm=1;m7;m+)for(intn=0;n7-m;n+)if(sptn.ysptn+1.y)p0=sptn.y;sptn=sptn+1;sptn+1=p0;pmax=spt0.y,pmin=spt6.y;x=s_point.x;y=s_point.y;for(;ypmin-2;y-)intcurrent=dc.GetPixel(x,y);while(current!=boundary)&(current!=fill)dc.SetPixel(x,y,fill);x+;current=dc.GetPixel(x,y);x=s_point.x;x-;curre

37、nt=dc.GetPixel(x,y);while(current!=boundary)&(current!=fill)dc.SetPixel(x,y,fill);x-;current=dc.GetPixel(x,y);x=s_point.x;說(shuō)明:(1)雙擊后,出現(xiàn)需填充的多邊形,單擊相關(guān)功能菜單實(shí)現(xiàn)區(qū)域填充。(2)進(jìn)行種子填充,需右擊多邊形內(nèi)一點(diǎn),作為開(kāi)始填充的種子點(diǎn)。voidCMyView:OnLButtonDblClk(UINTnFlags,CPointpoint)RedrawWindow();CDC*pDC=GetDC();CPennewpen(PS_SOLID,1,RGB(255,

38、0,0);CPen*old=pDC-SelectObject(&newpen);spt0=CPoint(100,100);/繪制多邊形區(qū)域spt1=CPoint(300,100);spt2=CPoint(250,250);spt3=CPoint(100,250);spt4=CPoint(150,200);spt5=CPoint(90,180);spt6=CPoint(150,150);spt7=CPoint(100,100);pDC-Polyline(spt,8);pDC-SelectObject(old);ReleaseDC(pDC);CView:OnLButtonDblClk(nFlags

39、,point);voidCMyView:OnRButtonDown(UINTnFlags,CPointpoint)s_point=point;/選擇種子點(diǎn)CView:OnRButtonDown(nFlags,point);1.5字符的生成字符指數(shù)字、字母、漢字等符號(hào)。計(jì)算機(jī)中字符由一個(gè)數(shù)字編碼惟一標(biāo)識(shí)。國(guó)際上最流行的字符集是美國(guó)信息交換用標(biāo)準(zhǔn)代碼集,簡(jiǎn)稱ASCII碼。它是用7位二進(jìn)制數(shù)進(jìn)行編碼表示128個(gè)字符,包括字母、標(biāo)點(diǎn)、運(yùn)算符以及一些特殊符號(hào)。我國(guó)除采用ASCII碼外,還另外制定了漢字編碼的國(guó)家標(biāo)準(zhǔn)字符集GB23121980信息交換用漢字編碼字符集基本集。該字符集分為94個(gè)區(qū),94個(gè)位,

40、每個(gè)符號(hào)由一個(gè)區(qū)碼和一個(gè)位碼共同標(biāo)識(shí)。區(qū)碼和位碼各用一個(gè)字節(jié)表示。為了能夠區(qū)分ASCII碼與漢字編碼,采用字節(jié)的最高位來(lái)標(biāo)識(shí):最高位為0表示ASCII碼;最高位為1表示漢字編碼。為了在顯示器等輸出設(shè)備上輸出字符,系統(tǒng)中必須裝備有相應(yīng)的字庫(kù)。字庫(kù)中存儲(chǔ)了每個(gè)字符的形狀信息,字庫(kù)分為矢量和點(diǎn)陣型兩種形式,如圖1-21所示。(a)點(diǎn)陣字符(b)點(diǎn)陣字庫(kù)中的位圖表示(c)矢量輪廓字符圖1-21字符的種類點(diǎn)陣字符在點(diǎn)陣字符庫(kù)中,每個(gè)字符由一個(gè)位圖表示。該位為1表示字符的筆畫(huà)經(jīng)過(guò)此位,對(duì)應(yīng)于此位的像素應(yīng)置為字符顏色。該位為0表示字符的筆畫(huà)不經(jīng)過(guò)此位,對(duì)應(yīng)于此位的像素應(yīng)置為背景顏色。在實(shí)際應(yīng)用中,有多種字體

41、(如宋體、楷體等),每種字體又有多種大小型號(hào),因此字庫(kù)的存儲(chǔ)空間是很龐大的。解決這個(gè)問(wèn)題一般采用壓縮技術(shù)。如黑白段壓縮、部件壓縮、輪廓字形壓縮等。其中,輪廓字形法壓縮比大,且能保證字符質(zhì)量,是當(dāng)今國(guó)際上最流行的一種方法。輪廓字形法采用直線或二/三次bezier曲線的集合來(lái)描述一個(gè)字符的輪廓線。輪廓線構(gòu)成一個(gè)或若干個(gè)封閉的平面區(qū)域。輪廓線定義加上一些指示橫寬、豎寬、基點(diǎn)、基線等控制信息就構(gòu)成了字符的壓縮數(shù)據(jù)。點(diǎn)陣字符的顯示分為兩步。首先從字庫(kù)中將它的位圖檢索出來(lái)。然后將檢索到的位圖寫(xiě)到幀緩沖器中。矢量字符矢量字符記錄字符的筆畫(huà)信息而不是整個(gè)位圖,具有存儲(chǔ)空間小,美觀、變換方便等優(yōu)點(diǎn)。對(duì)于字符的旋

42、轉(zhuǎn)、縮放等變換,點(diǎn)陣字符的變換需要對(duì)表示字符位圖中的每一像素進(jìn)行;而矢量字符的變換只要對(duì)其筆畫(huà)端點(diǎn)進(jìn)行變換就可以了。矢量字符的顯示也分為兩步。首先從字庫(kù)中找到它的字符信息。然后取出端點(diǎn)坐標(biāo),對(duì)其進(jìn)行適當(dāng)?shù)膸缀巫儞Q,再根據(jù)各端點(diǎn)的標(biāo)志顯示出字符。字符屬性字符屬性一般包括字體、字高、字寬因子(擴(kuò)展/壓縮)、字傾斜角、對(duì)齊方式、字色和寫(xiě)方式等。字符屬性的內(nèi)容如下。1)字體:如仿宋體、楷體、黑體、隸書(shū);2)字傾斜角:如傾斜;3)對(duì)齊:如左對(duì)齊、中心對(duì)齊、右對(duì)齊;4)字色:如紅、綠、藍(lán)色;5)寫(xiě)方式:替換方式時(shí),對(duì)應(yīng)字符掩模中空白區(qū)被置成背景色。寫(xiě)方式時(shí),這部分區(qū)域顏色不受影響。1.6圖形裁剪在使用計(jì)算

43、機(jī)處理圖形信息時(shí),計(jì)算機(jī)內(nèi)部存儲(chǔ)的圖形往往比較大,而屏幕顯示的只是圖的一部分。因此需要確定圖形中哪些部分落在顯示區(qū)之內(nèi),哪些落在顯示區(qū)之外,以便只顯示落在顯示區(qū)內(nèi)的那部分圖形。這個(gè)選擇過(guò)程稱為裁剪。最簡(jiǎn)單的裁剪方法是把各種圖形掃描轉(zhuǎn)換為點(diǎn)之后,再判斷各點(diǎn)是否在窗內(nèi)。但那樣太費(fèi)時(shí),一般不可取。這是因?yàn)橛行﹫D形組成部分全部在窗口外,可以完全排除,不必進(jìn)行掃描轉(zhuǎn)換。所以一般采用先裁剪再掃描轉(zhuǎn)換的方法,多邊形裁剪示意圖,如圖1-22所示。(a)裁剪前(b)裁剪后圖1-22多邊形裁剪示意圖線裁剪1直線和窗口的關(guān)系直線和窗口的關(guān)系如圖1-23所示,可以分為如下3類:1)整條直線在窗口內(nèi)。此時(shí),不需剪裁,顯

44、示整條直線。圖1-23直線與窗口的關(guān)系2)整條直線在窗口外,此時(shí),不需剪裁,不顯示整條直線。3)部分直線在窗口內(nèi),部分直線在窗口外。此時(shí),需要求出直線與窗框的交點(diǎn),并將窗口外的直線部分剪裁掉,顯示窗口內(nèi)的直線部分。直線剪裁算法有兩個(gè)主要步驟。首先將不需剪裁的直線挑出,即刪去在窗外的直線。然后,對(duì)其余直線,逐條與窗框求交點(diǎn),并將窗口外的部分刪去。2Cohen-Sutherland直線剪裁算法以區(qū)域編碼為基礎(chǔ),將窗口及其周圍的8個(gè)方向以4bit的二進(jìn)制數(shù)進(jìn)行編碼。如圖1-24所示的編碼方法將窗口及其鄰域分為5個(gè)區(qū)域。(1)內(nèi)域:區(qū)域(0000)。(2)上域:區(qū)域(1001,1000,1010)。(

45、3)下域:區(qū)域(0101,0100,0110)。(4)左域:區(qū)域(1001,0001,0101)。圖1-24窗口及其鄰域的5個(gè)區(qū)域及與直線的關(guān)系(5)右域:區(qū)域(1010,0010,0110)。當(dāng)線段的兩個(gè)端點(diǎn)的編碼的邏輯“與”非零時(shí),線段顯然為不可見(jiàn)的。對(duì)某線段的兩各端點(diǎn)的區(qū)號(hào)進(jìn)行位與運(yùn)算,可知這兩個(gè)端點(diǎn)是否同在視區(qū)的上、下、左、右。算法的主要思想是,對(duì)每條直線,如P1P2利用以下步驟進(jìn)行判斷:對(duì)直線兩端點(diǎn)Pi、P2編碼分別記為Ci(Pi)=ai,bi,ci,di,C2(P2)=a2,b2,C2,d2其中,ai、bi、g、di取值范圍為1,0,iCi,2。如果ai=b=ci=di=0,則顯示

46、整條直線,取出下一條直線,返回步驟;否則,進(jìn)入步驟。如果|a1a2|=i,則求直線與窗上邊(y=yw-max)的交點(diǎn),并刪去交點(diǎn)以上部分。如果|biHb2|=i,|ci-C2|=1,|diSelectObject(&newpen);pDC-Rectangle(CRect(XL,YT,XR,YB);/剪切窗口,可通過(guò)修改上面的對(duì)應(yīng)數(shù)據(jù)修改裁剪矩形框ptset0=CPoint(320,150);/需要剪切的各種線段,可通過(guò)修改數(shù)據(jù)修改線段(見(jiàn)圖1-30)ptset1=CPoint(370,110);ptset2=CPoint(200,190);ptset3=CPoint(550,150);圖1-3

47、0線段剪切ptset4=CPoint(200,250);ptset5=CPoint(350,230);ptset6=CPoint(400,50);ptset7=CPoint(450,130);pDC-TextOut(0,0,雙擊,出現(xiàn)要剪切的線段);pDC-TextOut(0,0,雙擊鼠標(biāo)右鍵,出現(xiàn)要剪切的多邊形);pDC-SelectObject(old);/處理雙擊左鍵消息函數(shù),得到要進(jìn)行裁剪的直線段voidCMyView:OnLButtonDblClk(UINTnFlags,CPointpoint)CDC*pDC=GetDC();CPennewpen(PS_SOLID,1,RGB(255

48、,0,0);CPen*old=pDC-SelectObject(&newpen);for(inti=0;iMoveTo(ptseti);pDC-LineTo(ptseti+1);i+;CView:OnLButtonDblClk(nFlags,point);voidCMyView:OnClipline()/線段裁剪消息處理函數(shù)CDC*pDC=GetDC();CPennewpen(PS_SOLID,1,RGB(0,255,0);CPen*old=pDC-SelectObject(&newpen);if(flag!=1)MessageBox(“請(qǐng)先雙擊,警告!”);(如圖1-31所示)elseflo

49、atx,y,x1,x2,y1,y2;inti;intcode1,code2;RedrawWindow();/求兩端點(diǎn)所在區(qū)號(hào)codefor(i=0;iN;i+,i+)intc=0;if(ptseti.xXR)c=c|RIGHT;if(ptseti.yYB)c=c|BOTTOM;elseif(ptseti.yYT)c=c|TOP;code1=c;圖 1-31 警告圖示窗圖 1-32 線段剪切結(jié)果c=0;if(ptseti+1.xXR)c=c|RIGHT;if(ptseti+1.yYB)c=c|BOTTOM;elseif(ptseti+1.yMoveTo(ptseti.x,ptseti.y);pD

50、C-LineTo(ptseti+1.x,ptseti+1.y);if(code1=0&code2=0)pDC-MoveTo(ptseti.x,ptseti.y);pDC-LineTo(ptseti+1.x,ptseti+1.y);if(code1=0&code2!=0)pDC-MoveTo(ptset0.x,ptset0.y);if(LEFT&code2)!=0)/線段與左邊界相交x=XL;y=ptseti.y+(ptseti+1.y-ptseti.y)*(XL-ptseti.x)/(ptseti+1.x-ptseti.x);elseif(RIGHT&code2)!=0)/線段與右邊界相交x=

51、XR;y=ptseti.y+(ptseti+1.y-ptseti.y)*(XR-ptseti.x)/(ptseti+1.x-ptseti.x);elseif(BOTTOM&code2)!=0)/線段與下邊界相交y=YB;x=ptseti.x+(ptseti+1.x-ptseti.x)*(YB-ptseti.y)/(ptseti+1.y-ptseti+1.y);elseif(TOP&code2)!=0)/線段與上邊界相交y=YT;x=ptseti.x+(ptseti+1.x-ptseti.x)*(YT-ptseti.y)/(ptseti+1.y-ptseti.y);ptseti+1.x=x;pt

52、seti+1.y=y;pDC-LineTo(ptseti+1.x,ptseti+1.y);if(code1!=0&code2=0)pDC-MoveTo(ptseti+1.x,ptseti+1.y);if(LEFT&code1)!=0)/線段與左邊界相交x=XL;y=ptseti.y+(ptseti+1.y-ptseti.y)*(XL-ptseti.x)/(ptseti+1.x-ptseti.x);elseif(RIGHT&code1)!=0)/線段與右邊界相交x=XR;y=ptseti.y+(ptseti+1.y-ptseti.y)*(XR-ptseti.x)/(ptseti+1.x-ptse

53、ti.x);elseif(BOTTOM&code1)!=0)/線段與下邊界相交y=YB;x=ptseti.x+(ptseti+1.x-ptseti.x)*(YB-ptseti.y)/(ptseti+1.y-ptseti+1.y);elseif(TOP&code1)!=0)/線段與上邊界相交y=YT;x=ptseti.x+(ptseti+1.x-ptseti.x)*(YT-ptseti.y)/(ptseti+1.y-ptseti.y);ptseti.x=x;ptseti.y=y;pDC-LineTo(ptseti.x,ptseti.y);/處理雙擊右鍵出現(xiàn)要裁剪的多邊形(見(jiàn)圖1-33)voidC

54、MyView:OnRButtonDblClk(UINTnFlags,CPointpoint)CDC*pDC=GetDC();CPennewpen(PS_SOLID,1,RGB(255,0,0);CPen*old=pDC-SelectObject(&newpen);pDC-MoveTo(ptset10);for(inti=1;iLineTo(ptset1i);CView:OnRButtonDblClk(nFlags,point);voidCMyView:OnClippolygon()多邊形裁剪(見(jiàn)圖1-34)CDC*pDC=GetDC();CPennewpen(PS_SOLID,1,RGB(0,

55、255,0);CPen*old=pDC-SelectObject(&newpen);if(flag!=1)MessageBox(“請(qǐng)先雙擊鼠標(biāo)右鍵,警告!);(見(jiàn)圖1-35)elseinti,k;intcode1,code2;intM=5;RedrawWindow();/求兩端點(diǎn)所在區(qū)號(hào)codek=0;圖1-33多邊形剪切圖1-34多邊形剪切結(jié)果圖1-35警告提示窗for(i=0;iM;i+)intc=0;if(ptset1i.xXL)c=0;code1=c;c=0;if(ptset1i+1.xXL)c=0;code2=c;if(code1!=0&code2=0)ptk.x=XL;ptk.y=

56、ptset1i.y+(ptset1i+1.y-ptset1i.y)*(XL-ptset1i.x)/(ptset1i+1.x-ptset1i.x);ptk+1.x=ptset1i+1.x;ptk+1.y=ptset1i+1.y;k=k+2;if(code1=0&code2=0)if(k=0)ptk.x=ptset1i.x;ptk.y=ptset1i.y;ptk+1.x=ptset1i+1.x;ptk+1.y=ptset1i+1.y;k=k+2;if(k!=0)ptk.x=ptset1i+1.x;ptk.y=ptset1i+1.y;k=k+1;if(code1=0&code2!=0)ptk.x=X

57、L;ptk.y=ptset1i.y+(ptset1i+1.y-ptset1i.y)*(XL-ptset1i.x)/(ptset1i+1.x-ptset1i.x);k+;)ptk.x=pt0.x;ptk.y=pt0.y;M=k+1;k=0;for(i=0;iM;i+)(intc=0;if(pti.xXR)c=2;code1=c;c=0;if(pti+1.xXR)c=2;code2=c;if(code1=0&code2=0)(if(k=0)(ptsk.x=pti.x;ptsk.y=pti.y;ptsk+1.x=pti+1.x;ptsk+1.y=pti+1.y;k=k+2;)if(k!=0)(pts

58、k.x=pti+1.x;ptsk.y=pti+1.y;k+;)if(code1!=0&code2=0)ptsk.x=XR;ptsk.y=pti.y+(pti+1.y-pti.y)*(XR-pti.x)/(pti+1.x-pti.x);ptsk+1.x=pti+1.x;ptsk+1.y=pti+1.y;k=k+2;)if(code1=0&code2!=0)(ptsk.x=XR;ptsk.y=pti.y+(pti+1.y-pti.y)*(XR-pti.x)/(pti+1.x-pti.x);k=k+1;處理最后一條邊ptsk=pts0;M=k+1;k=0;for(i=0;iYB)c=4;elseif

59、(ptsi.yYB)c=4;elseif(ptsi+1.yYB)c=0;code2=c;if(code1=0&code2=0)(if(k=0)ptsek.x=ptsi.x;ptsek.y=ptsi.y;ptsek+1.x=ptsi+1.x;ptsek+1.y=ptsi+1.y;k=k+2;if(k!=0)ptsek.x=ptsi+1.x;ptsek.y=ptsi+1.y;k=k+1;if(code1!=0&code2=0)ptsek.y=YB;ptsek.x=ptsi.x+(ptsi+1.x-ptsi.x)*(YB-ptsi.y)/(ptsi+1.y-ptsi+1.y);ptsek+1.x=p

60、tsi+1.x;ptsek+1.y=ptsi+1.y;k=k+2;if(code1=0&code2!=0)ptsek.y=YB;ptsek.x=ptsi.x+(ptsi+1.x-ptsi.x)*(YB-ptsi.y)/(ptsi+1.y-ptsi+1.y);k=k+1;ptsek=ptse0;M=k+1;k=0;for(i=0;iYT)c=0;elseif(ptsei.yYT)c=0;elseif(ptsei+1.yMoveTo(p0);for(intj=1;jLineTo(pj);說(shuō)明:為避免上述“圖形裁剪”程序執(zhí)行過(guò)程中,在沒(méi)有雙擊就直接單擊“線段裁剪”或沒(méi)有雙擊就直接單擊“多邊形裁剪”的

溫馨提示

  • 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒(méi)有圖紙預(yù)覽就沒(méi)有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫(kù)網(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)論