計算機(jī)圖形學(xué)教程課后習(xí)題答案_第1頁
計算機(jī)圖形學(xué)教程課后習(xí)題答案_第2頁
計算機(jī)圖形學(xué)教程課后習(xí)題答案_第3頁
計算機(jī)圖形學(xué)教程課后習(xí)題答案_第4頁
計算機(jī)圖形學(xué)教程課后習(xí)題答案_第5頁
已閱讀5頁,還剩44頁未讀, 繼續(xù)免費閱讀

下載本文檔

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

文檔簡介

1、-. z.第一章試述計算機(jī)圖形學(xué)研究的根本容?答:見課本P5-6頁的節(jié)。計算機(jī)圖形學(xué)、圖形處理與模式識別本質(zhì)區(qū)別是什么?請各舉一例說明。答:計算機(jī)圖形學(xué)是研究根據(jù)給定的描述,用計算機(jī)生成相應(yīng)的圖形、圖像,且所生成的圖形、圖像可以顯示屏幕上、硬拷貝輸出或作為數(shù)據(jù)集存在計算機(jī)中的學(xué)科。計算機(jī)圖形學(xué)研究的是從數(shù)據(jù)描述到圖形生成的過程。例如計算機(jī)動畫制作。圖形處理是利用計算機(jī)對原來存在物體的映像進(jìn)展分析處理,然后再現(xiàn)圖像。例如工業(yè)中的射線探傷。模式識別是指計算機(jī)對圖形信息進(jìn)展識別和分析描述,是從圖形圖像到描述的表達(dá)過程。例如分撿設(shè)備掃描信件上手寫的郵政編碼,并將編碼用圖像復(fù)原成數(shù)字。計算機(jī)圖形學(xué)與CA

2、D、CAM技術(shù)關(guān)系如何?答:見課本P4-5頁的節(jié)。舉3個例子說明計算機(jī)圖形學(xué)的應(yīng)用。答:事務(wù)管理中的交互繪圖應(yīng)用圖形學(xué)最多的領(lǐng)域之一是繪制事務(wù)管理中的各種圖形。通過從簡明的形式呈現(xiàn)出數(shù)據(jù)的模型和趨勢以增加對復(fù)雜現(xiàn)象的理解,并促使決策的制定。地理信息系統(tǒng)地理信息系統(tǒng)是建立在地理圖形根底上的信息管理系統(tǒng)。利用計算機(jī)圖形生成技術(shù)可以繪制地理的、地質(zhì)的以及其它自然現(xiàn)象的高精度勘探、測量圖形。計算機(jī)動畫用圖形學(xué)的方法產(chǎn)生動畫片,其形象逼真、生動,輕而易舉地解決了人工繪圖時難以解決的問題,大大提高了工作效率。計算機(jī)繪圖有哪些特點?答:見課本P8頁的節(jié)。計算機(jī)生成圖形的方法有哪些?答:計算機(jī)生成圖形的方法有

3、兩種:矢量法和描點法。矢量法:在顯示屏上先給定一系列坐標(biāo)點,然后控制電子束在屏幕上按一定的順序掃描,逐個點亮臨近兩點間的短矢量,從而得到一條近似的曲線。盡管顯示器產(chǎn)生的只是一些短直線的線段,但當(dāng)直線段很短時,連成的曲線看起來還是光滑的。描點法:把顯示屏幕分成有限個可發(fā)亮的離散點,每個離散點叫做一個像素,屏幕上由像素點組成的陣列稱為光柵,曲線的繪制過程就是將該曲線在光柵上經(jīng)過的那些像素點串接起來,使它們發(fā)亮,所顯示的每一曲線都是由一定大小的像素點組成的。當(dāng)像素點具有多種顏色或多種灰度等級時,就可以顯示彩色圖形或具有不同灰度的圖形。7、當(dāng)前計算機(jī)圖形學(xué)研究的課題有哪些?答:見課本P10-11頁的1

4、.4節(jié)。8、簡述三維圖形生成和輸出的流水線?答:見課本P13頁.節(jié)。9、向量圖形和點陣圖形之間的區(qū)別有哪些? 答:通過矢量法產(chǎn)生的圖形稱為矢量圖形或者向量圖形,用描點法產(chǎn)生的圖形稱為點陣圖形。向量圖形區(qū)別點陣圖形的特點在于描述圖形幾何形狀的數(shù)學(xué)模型及依據(jù)此模型生成幾何圖形的計算機(jī)命令。向量圖形由各個根本圖形構(gòu)成,這就要求各個根本圖形有各自獨立的信息。如果用點陣圖形來表示一個向量圖形,構(gòu)成向量圖形的*個根本圖形(如直線段、圓弧等)的所有點應(yīng)有一個信息。因此,在描述一個根本圖形時,同時要描述其相應(yīng)的信息。向量圖形最根本的優(yōu)點是它本身是由準(zhǔn)確的數(shù)據(jù)給出,所以可以充分利用各種輸出圖形設(shè)備的分辨率盡可能

5、準(zhǔn)確地輸出圖形。也正因為如此,向量圖形的尺寸可以任意變化而不損失圖形顯示的質(zhì)量。但是向量圖形僅適合于描繪簡單圖形,而點陣圖形可以描繪絢爛多彩的復(fù)雜圖形。10、什么是虛擬現(xiàn)實技術(shù)和可視化技術(shù)?答:虛擬現(xiàn)實技術(shù):利用計算機(jī)生成一種模擬環(huán)境,通過多種傳感器和設(shè)備使用戶投入到該環(huán)境中,實現(xiàn)用戶和該環(huán)境直接進(jìn)展交互的技術(shù)。例如模擬飛機(jī)駕駛艙??梢暬夹g(shù):通過對空間數(shù)據(jù)場構(gòu)造中間幾何因素,或用圖形繪制技術(shù)在屏幕上產(chǎn)生二維圖像。例如分子模型構(gòu)造。第二章1、計算機(jī)圖形系統(tǒng)有什么特點?有哪些主要功能?答:課本的圖2.1展示了計算機(jī)圖形系統(tǒng)的組成。計算機(jī)圖形系統(tǒng)是為了支持應(yīng)用程序,便于實現(xiàn)圖形的輸入輸出的硬件和軟

6、件組合體。沒有圖形系統(tǒng)支持,就難以實現(xiàn)應(yīng)用軟件的開發(fā)。主要功能見課本2.1.2節(jié)。2、計算機(jī)圖形系統(tǒng)有哪幾種?各有什么特點?答:一種分類方法:交互式圖形系統(tǒng)允許操作者以*種方式(對話方式或命令方式)來控制和操作圖形生成過程,使得圖形可以邊生成、邊顯示、邊修改,直至符合要求為止。而被動式繪圖系統(tǒng),圖形在生成過程中,操作者無法對圖形進(jìn)展實時操作和控制,不具備交互功能,只提供各種圖形命令或圖形程序庫,通過編程獲得所需圖形。另一種分類方法:見課本節(jié),分為脫機(jī)繪圖系統(tǒng)、聯(lián)機(jī)繪圖系統(tǒng)和交互式繪圖系統(tǒng)。3、陰極射線管由哪些局部組成?它們的功能分別是什么?答:CRT由四局部組成:電子槍、聚焦系統(tǒng)、偏轉(zhuǎn)系統(tǒng)和熒

7、光屏,這四局部都在真空管。電子槍由燈絲、陰極和控制柵極組成。燈絲加熱陰極,陰極外表向外發(fā)射自由電子,控制柵控制自由電子是否向熒光屏發(fā)出,假設(shè)允許電子通過,形成的電子流在到達(dá)屏幕的途中,被聚焦系統(tǒng)電子透鏡聚焦成很窄的電子束,由偏轉(zhuǎn)系統(tǒng)產(chǎn)生電子束的偏轉(zhuǎn)電場或磁場,使電子束左右、上下偏轉(zhuǎn),從而控制熒光屏上光點上下、左右運(yùn)動,使得在指定時刻在屏幕指定位置上產(chǎn)生亮點。4、光柵掃描顯示器由哪些局部組成?它們的功能分別是什么? 答:見課本P21頁圖2.9所展示的組成框圖,其后有各局部的介紹及功能。5、對于分辨率為1024*1024的光柵系統(tǒng),假設(shè)每一像素用8位和12位二進(jìn)制來表示存儲信息,各需多大光柵存儲容

8、量以及顯存?每一屏幕最多能顯示多少顏色?假設(shè)R,G,B灰度都占8位,其顯示顏色的總數(shù)是多少?解:1)每一像素用8位二進(jìn)制來表示存儲信息,所需容量為1024*1024*1=Byte=1MB彩色素:=256(項)2)假設(shè)每一像素用12位二進(jìn)制表示存儲信息,所需容量為:1024*1024*1.5=1.5*(Byte)=1.5MB (由于顯示卡的顯存是按2的指數(shù)次倍增長的,因此所需顯存為2M)彩色素:=4096( 項)3)顏色總數(shù):*=16777216種6、對于19英寸顯示器,假設(shè)*和Y兩方向的分辨率相等,即1024*1024,則每個像素點的直徑是多少?解:=0.33mm或=0.013英寸7、對于分辨

9、率為1024768的光柵系統(tǒng),假設(shè)調(diào)色板設(shè)置為真彩色32位,此時需要顯示一個三維圖形,各需要多大光柵存儲容量以及顯存?答:調(diào)色板為真彩色32位,即意味著像素值的位長為32所需容量為1024*768*32/8*3=9MB 因此所需要的顯存為16M8、GKS有哪三種坐標(biāo)系?它們有什么不同?試寫出它們之間對應(yīng)關(guān)系?答:GKS有3種不同的坐標(biāo)系。第一種是供給用程序使用的實際世界坐標(biāo)系統(tǒng)World Coordinate System,簡稱 WC;第二種是GKS部使用的規(guī)設(shè)備坐標(biāo)系Normalized Device Coordinate,簡稱NDC,它的取值圍為0,1,這是一種既與設(shè)備無關(guān)也與應(yīng)用無關(guān)的坐

10、標(biāo)系;第三種是各工作站物理設(shè)備使用的設(shè)備坐標(biāo)系Device Coordinate System,簡稱DC。GKS只支持二維對象的圖形處理,因此上述3個坐標(biāo)系都是二維坐標(biāo)系。詳見課本圖3.28的描述。9、GKS中輸入設(shè)備有哪6種邏輯功能?請各舉出對應(yīng)的物理設(shè)備。答:見課本.節(jié)。10、當(dāng)前主流的圖形軟件有哪些?答:見課本節(jié)。第三章1、編寫畫一正方形程序,并在其中用不同的顏色畫15個正方形,每一個都比前一個小。#includegraphics.h#includeconio.hvoid main()int i,color=0,ls=0;int j=700;int gdriver=VGA;int gmo

11、de=VGAHI;initgraph(&gdriver,&gmode,);3-1批改說明; 必須至少包含graphics.hinitgraph(&gdriver,&gmode,);必須包含15個正方形,一般用for循環(huán),也可能用到while等。注意查看是否是正方形i, i, j, j即:*2-*1=y2-y1注意查看顏色是否有15種:也就是說gdriver=CGA肯定是錯的,可以為DETECT、VGA、EGA。setbkcolor(15);for(i=0;i225;i=i+15,j=j-30)setcolor(color);bar(i,i,j,j);color+;ls+;getch();clo

12、segraph();2、用不同的線形繪制題1中的圖形#includegraphics.h#includeconio.hvoid main()int i,color=1,ls=0;3-2批改說明; 注意查看3_1局部內(nèi)容setlinestyle(i%4),0,k);k對線寬的設(shè)置。int j=700;int gdriver=VGA;gmode=VGAHI;initgraph(&gdriver,&gmode,);setbkcolor(15);for(i=0;i=225;i=i+15, j=j-30)setcolor(color);/setlinestyle(ls%4,0,1);或者setlines

13、tyle(4,ls,3);rectangle(i,i,j,j);setfillstyle(SOLID_FILL,color);/floodfill(getma*()/2,getma*y()/2,color); 此句會出現(xiàn)最后只用一種顏色填充的情況color+;ls+;getch();closegraph();3、畫一五顏六色的圖(此例為畫一個五顏六色的圓)#includegraphics.h#includeconio.hvoid main()int driver=DETECT,mode=0;int i,start,end;3-3批改說明; 必須至少包含graphics.hinitgraph(&

14、gdriver,&gmode,);如果是這個版本的圖,注意end比start要大。restorecrtmode()可能有人寫成retorecrtmode()initgraph(&driver,&mode,);start=0;end=20;for(i=0;i0;i-,j-)setfillstyle(EMPTY_FILL,0);pieslice(387+j,290,start,end,37);pieslice(525+j,290,start,end,37);start+=40;end+=40;delay(5); /處于運(yùn)動狀態(tài)的自行車車輪的軸線的繪制 putimage(i-1,200,w,COPY

15、_PUT);line(2,327,562,327);delay(10); /自行車行駛動畫的實現(xiàn) for(i=0;iabs(y2-y1)length=abs(*2-*1);elselength=abs(y2-y1);incre*=(*2-*1)/length;increy=(y2-y1)/length;*=*1;y=y1;for(i=1;i1) if(f=0)*1=*1-d*;y1=y1;putpi*el(*1,y1,1);f=f-2*d*(*1-*0)+d*d*; else *1=*1;y1=y1+dy;putpi*el(*1,y1,1);f=f+2*dy*(y1-y0)+dy*dy; 方法

16、2:逆4象限#include graphics.h#include stdlib.h#include conio.hvoid ZDBJ_ARC(float *0,float y0,float *1,float y1,float *2,float y2);void main()int gdriver=CGA,mode=CGAC0;initgraph(&gdriver,&mode, ); ZDBJ_ARC(0,0,0,25,25,0); getch(); closegraph();void ZDBJ_ARC(float *0,float y0,float *1,float y1,float *2,

17、float y2) float f=0.0,F; float d*=1,dy=1; while(abs(y1-y2)1) if(f0)*1=*1;y1=y1-dy;putpi*el(*1,y1,1);f=f-2*dy*abs(y1-y0)+dy*dy; else *1=*1+d*;y1=y1;putpi*el(*1,y1,1);f=f+2*d*abs(*1-*0)+d*d*; 方法3:順1象限#includegraphics.h/省略了圖形初始化的步驟AB#includeconio.h#include math.hvoid main()int *1=5,y1=0,*2=0,y2=5;int *

18、0=0,y0=0;int R=sqrt(*2-*0)* (*2-*0)+(y2-y0)* (y2-y0);int d*=abs(*2-*1);int dy=abs(y2-y1);int n=d*+dy;putpi*el(*2,y2,1);int f;int *=*2,y=y2;for(int i=0;i=0)putpi*el(*,y-,1);elseputpi*el(*+,y,1);getch();closegraph(); /另一種做法是采用課本P97頁表4.2的公式4.編一程序用角度DDA法畫一圓/以圓點為圓心,半徑為20的圓#includegraphics.h/省略了圖形初始化的步驟#i

19、ncludeconio.h#include math.hvoid main()int *0=0,y0=0,R=20;int *1,y1,*i,yi;int N=R*8;float a=2*3.14/N;*1=20,y1=0;for(int i=1;i0;而對于圓的點,F(xiàn)(*, y)0。Y*PPdPuM1/8圓弧PuPdM此處僅考慮如下圖的第一象限*的1/8圓弧,此時中點Bresenham畫圓算法要從(0, R)到()順時針地確定最正確逼近于該圓弧的像素序列。由于最大位移方向為*,因此其根本原理:每次*方向上走一步,而y方向上或減1或減0。假定當(dāng)前與圓弧最近者已確定,為P(*i, yi),則下一

20、候選像素只能是正右方的Pu(*i +1, yi)和右下方的Pd(*i +1, yi-1)。到底選取哪一個候選點依舊用中點進(jìn)展判別。假設(shè)M是Pu和Pd的中點,即有M(*i +1, yi-0.5),則當(dāng)F(*M, yM)0,M在圓外,說明Pd離圓弧更近;當(dāng)F(*M, yM)=0,則約定取Pd。構(gòu)造判別式di=F(*M, yM)= F(*i +1, yi-0.5)=(*i +1)2+(yi-0.5)2- R2(1) 當(dāng)di0,取Pu(*i +1, yi),計算下一步的的判別式di+1=F(*u, yu)= F(*i +2, yi-0.5)= (*i +2)2+(yi-0.5)2- R2= di+2*

21、i+3 所以沿正右方向,di的增量為2*i+3。(2) 當(dāng)di0,取Pd(*i +1, yi+1),計算下一步的的判別式di+1=F(*d, yd)= F(*i +2, yi-1.5)= (*i +2)2+(yi-1.5)2- R2= di+2(*i-yi)+5所以沿右下方向,di的增量為2(*i-yi)+5。顯然,所繪制圓弧段的第一個像素為P0(0, R),因此判別式d0的初始值為1.25-R,可以令d=d-0.25來擺脫小數(shù)運(yùn)算,則判別式di0對應(yīng)于di-0.25,由于d始終是整數(shù),di-0.25等價于dibP=p;m_ma*Inde*=len-1;void Bezier:draw() /

22、通過公有函數(shù)調(diào)用私有函數(shù)drawFrame();drawCurve();void Bezier:drawFrame() /其功能是繪制出多邊形和各個端點setcolor(12);for(int i=0;im_ma*Inde*;i+)line( bPi.*, bPi.y, bPi+1.*, bPi+1.y ); /繪制多邊形circle(bPi.*, bPi.y,5); /繪制各個端點circle(bPm_ma*Inde*.*,bPm_ma*Inde*.y,5);void Bezier:drawCurve() /實現(xiàn)多段Bezier曲線繪制的功能for(int i=0;i=m_ma*Inde*-

23、3;i+=3)drawCurve(i,i+1,i+2,i+3);void Bezier:drawCurve(int p0,int p1,int p2,int p3) /實現(xiàn)繪制*一段Bezier曲線的功能double tmp*=0.0;double tmpy=0.0;double t=0.0;for(;tbP=p;m_ma*Inde*=len;void B_Spline:draw() /通過公有函數(shù)調(diào)用私有函數(shù)drawFrame();drawCurve();void B_Spline:drawFrame() /其功能是繪制出多邊形和各個端點setcolor(12);for(int i=0;im

24、_ma*Inde*-1;i+)line( bPi.*, bPi.y, bPi+1.*, bPi+1.y ); /繪制多邊形circle(bPi.*, bPi.y,5); /繪制多邊形各個端點circle(bPm_ma*Inde*-1.*,bPm_ma*Inde*-1.y,5);void B_Spline:drawCurve() /實現(xiàn)多段B樣條曲線繪制的功能for(int i=0;im_ma*Inde*-2;i+)drawCurve(i,i+1,i+2);void B_Spline:drawCurve(int p0,int p1,int p2) /實現(xiàn)繪制*一段Bezier曲線的功能doubl

25、e tmp*=0.0;double tmpy=0.0;double t=0.0;for(;t=1.0;t+=0.001)tmp*=(0.5*bPp0.*-bPp1.*+0.5*bPp2.*)*t*t+(-bPp0.*+bPp1.*)*t+0.5*bPp0.*+0.5*bPp1.*;tmpy=(0.5*bPp0.y-bPp1.y+0.5*bPp2.y)*t*t+(-bPp0.y+bPp1.y)*t+0.5*bPp0.y+0.5*bPp1.y;putpi*el(tmp*,tmpy,3);void main() /主函數(shù)的實現(xiàn)int graphdriver=DETECT,graphmode;init

26、graph(&graphdriver,&graphmode,); /圖形初始化setbkcolor(15);DPOINT* p;p=new DPOINT4; p0.*=50.0;p0.y=130.0;p1.*=120.0;p1.y=40.0;p2.*=190.0;p2.y=130.0;p3.*=260.0;p3.y=40.0;B_Spline b_sp(p,4);b_sp.draw();delete p;getch();closegraph();11. 簡述NURBS曲線產(chǎn)生的背景和特點?答:NURBS曲線具有局部可調(diào)性、凸包性、幾何和透視投影變換不變性等等,它采用有理參數(shù)多項式可以準(zhǔn)確表示圓

27、錐曲線、二次曲面等,對于幾何造型算法提供了思路。12. 將以下數(shù)據(jù)* 2 6 10 12 14 16Y 3 8 11 13 15 17按最小二乘法曲線擬合,分別求一次和二次多項式曲線,擬合以上數(shù)據(jù)并畫圖表示。解:如下表所示:i1236412816268483628821612963101111010011001000100004121315614418721728207365141521019629402744384166161727225643524096655366067802736105649792136000一次多項式的情形: 6+60=67 =1.4608 60+736=802 =0

28、.9706所求多項式為y=f(*)=1.4608+0.9706*二次多項式的情形: 6+60+736=67 =1.0793 60+736+9792=802 =1.0921 736+9792+136000=10564 =-0.006796213. 設(shè)五邊形的五個頂點坐標(biāo)為(10, 10),(15, 5),(12, 5),(8, 2)和(4, 5),利用多邊形區(qū)域填充算法,編一程序生成一個實心圖。解:假設(shè)以上五個頂點依次對應(yīng)編號A-B-C-D-E,首先計算得到ET表:AEDCB1046/5EA1015-1BA 6-10 5 458-4/3DE584/3DC 3 2 1 0 用于存放AET活動邊表該

29、多邊形的AET指針的容為:1 AET為空58-4/3DE584/3DCAET2DCDEAET5-4/328/3-4/320/353DE-4/316/35-4/332/35DCAET46/5410-4/345DCEAAET5DE4/3125-11510BA1410BAEA6/526/510AET-16BAEA6/532/510AET-113107EA6/538/510AET-11210BA810AET-11110BAEA44/56/591010BAEA6/51010AET-110具體編程實現(xiàn)如下:第1步:(1) 根據(jù)輸入的五個頂點坐標(biāo)找到y(tǒng)值最小的點(例如點D,此時y=2),并找到與D有邊關(guān)系的

30、兩個頂點(此時為E和C),在y=2處建立ET邊表記錄(yma*、*i和m值均可通過頂點坐標(biāo)間的計算得到,例如DE邊的建立,特別注意:當(dāng)D點和E點y坐標(biāo)值一樣時,也即是DE與*軸平行,該邊不能計入ET邊表),之后標(biāo)記D點被訪問過;(2) 排除訪問過的點以及和該點相關(guān)聯(lián)的邊,重復(fù)(1)直至將ET表建立完善。注邊關(guān)系的建立可通過鄰接矩陣的數(shù)據(jù)構(gòu)造實現(xiàn),權(quán)值可以為該矩陣行編號對應(yīng)點的y坐標(biāo)值,ET邊表采用鄰接表的數(shù)據(jù)構(gòu)造第2步:根據(jù)ET表構(gòu)建AET表,并逐行完成多邊形填充,具體的C+代碼如下:(1) 建立頭文件base_class.h,主要是邊表結(jié)點構(gòu)造體和ET邊表類的實現(xiàn)enum ResultCod

31、eSuccess, Failure;template struct EnodeEnode() ne*t=NULL;Enode(T pyma*, float p*i, float pm, Enode *pne*t)yma*=pyma*; *i=p*i;m=pm; ne*t=pne*t;T yma*, *i; /yma*表示最大的y值,*i表示最底端點的*坐標(biāo)值float m; /m表示斜率的倒數(shù)Enode *ne*t; /定義了ET表和AET表中結(jié)點的構(gòu)造體template class ETpublic:ET(int mSize); ET();ResultCode Insert(int u, T

32、 yma*, float *i, float m);int n; /覆蓋該多邊形的掃描線的總數(shù),從0開場計數(shù)Enode *a; /定義了邊表類template ET:ET(int mSize)n=mSize;a=new Enode *n; for(int i=0;in;i+) ai=0; /ET邊表的初始化template ET:ET()Enode *p, *q;delete a0; for(int i=1;ine*t;delete q;q=p;delete a; /析構(gòu)函數(shù)負(fù)責(zé)回收存空間template ResultCode ET:Insert(int u, T yma*, float *i

33、, float m)if(un-1) return Failure;Enode *p=new Enode(yma*, *i, m, au);au=p;return Success; /依次插入結(jié)點構(gòu)建出邊表,其中a1到a10用于構(gòu)建ET邊表 /a0用于構(gòu)建活動AET邊表(2) 填充函數(shù)po_fill的實現(xiàn)和主函數(shù)的實現(xiàn)#include base_class.h#include graphics.h#include void po_fill(ET &etp, int ep, int color) /多邊形填充函數(shù)的實現(xiàn) int i=1; /i作為控制變量標(biāo)識掃描線while(iep-1) if(

34、etp.ai!=NULL)Enode *p,*r;p=etp.ai;r=etp.a0;while(p) Enode *q=new Enode(p-yma*,p-*i,p-m,NULL); if(!etp.a0) etp.a0=q; r=q; else if(r-*i=q-*i) q-ne*t=r-ne*t; r-ne*t=q; r=q; if(r-*iq-*i) etp.a0=q; q-ne*t=r; else while(q-*ir-*i & r-ne*t) r=r-ne*t;if(r-ne*t) q-ne*t=r-ne*t; r-ne*t=q; else r-ne*t=q; q-ne*t=

35、NULL; p=p-ne*t; /按照*i值的大小將當(dāng)前ET表中的記錄放置到AET表中 Enode *f,*g;if(etp.a0)f=etp.a0;while(f-ne*t)g=f;f=f-ne*t;for(int j=g-*i;jne*t-*i;j+)putpi*el(j,i,color); /把一對相鄰結(jié)點的*i區(qū)間圍進(jìn)展填充if(etp.a0!=NULL)Enode *w;int s=1;while(s)Enode *z=NULL;w=etp.a0;s=0;while(w & w-yma*!=i)z=w; w=w-ne*t; if(!w) break;if(z) z-ne*t=w-ne

36、*t;else etp.a0=w-ne*t;delete w;s=1; /刪去AET表中i值已經(jīng)等于yma*的結(jié)點記錄 if(etp.a0)Enode *u,*v;u=etp.a0;while(u)v=u;u=u-ne*t;v-*i=v-*i+v-m; /用*i+m來替代原有的*ii+; /進(jìn)入下一條掃描線 void main() /主函數(shù)的實現(xiàn) int gdriver, gmode; gdriver=DETECT; gmode=VGAHI; initgraph(&gdriver, &gmode,); /圖形系統(tǒng)初始化 int e=11; int color=5; /color用于標(biāo)識填充顏色

37、 ET et(e); et.Insert(2,5,8,4/3); et.Insert(2,5,8,-4/3); et.Insert(5,10,15,-1); et.Insert(5,10,4,6/5); /根據(jù)初始數(shù)據(jù)建立邊表 po_fill(et, e, color); /調(diào)用填充函數(shù)getch(); closegraph();注第2步的實現(xiàn)存在兩個問題:(1) 沒有實現(xiàn)世界坐標(biāo)系統(tǒng)(第1象限)到設(shè)備坐標(biāo)系統(tǒng)的轉(zhuǎn)換,所以顯示出來的圖形是以上所畫圖形的倒置,解決方法就是從世界坐標(biāo)系統(tǒng)的最高y值開場掃描;(2) 由于m的取值為分?jǐn)?shù)(浮點型),這就導(dǎo)致像素點坐標(biāo)值出現(xiàn)浮點型,這樣經(jīng)過取整運(yùn)算,計算

38、出來的像素點坐標(biāo)值將可能與多邊形填充點真實值之間存在偏差,導(dǎo)致所繪制的圖形不完全與實際吻合。14. 多邊形各頂點坐標(biāo)為(2, 2)(2, 4)(8, 6)(12, 2)(8, 1)(6, 2)及(2, 2),在用多邊形區(qū)域填充時,請寫出ET及全部AET容。解:如下圖:P3P1P2P6P5P4則該多邊形的ET表為: 6623P2P3 5 4612-1P4P3420P1P2 3 2284P5P428-2P5P6 1該多邊形的AET指針的容為:(每條掃描線均有3行指針鏈,第1行表示將ET表參加AET中,第2行表示從AET表中刪去yi=yma*,第3行表示*i=*i+1/m后,學(xué)生只要寫出第2行即可)

39、28-2P5P6284P5P4AET1284P5P428-2P5P6AET26-2P5P6AET2124P5P426-2P5P6420P1P2AET22124P5P4612-1P4P3420P1P2AET612-1P4P3AET420P1P2611-1P4P3611-1P4P3420P1P2AET3AET420P1P2611-1P4P3AET420P1P2610-1P4P3610-1P4P3AET623P2P3420P1P24 610-1P4P3623P2P3AET69-1P4P3653P2P3AET653P2P369-1P4P3AET569-1P4P3653P2P3AETAET683P2P3

40、68-1P4P368-1P4P3683P2P3AET6 15. 用掃描線種子填充算法,編寫一個填充多邊形區(qū)域的程序。BDEHFCGA該測試多邊形的各個端點坐標(biāo)分別為:A(50, 150),B(50, 100),C(100, 50),D(250, 50),E(200, 150);F(100, 100),G(100, 75),H(175, 135);/*本程序?qū)崿F(xiàn)區(qū)域填充功能,首先輸入多邊形頂點的個數(shù),回車,然后依次輸入各頂點的坐標(biāo)格式如下:100,123回車一定要在中間用逗號隔開噢,輸完最后一個點后,屏幕上會依次畫出各條邊,最后填充滿程序還不完善,比方顏色值應(yīng)該用變量表示以易于修改,畫多邊形和求

41、種子點應(yīng)該做成獨立的函數(shù)等等,以后再做上吧,這是細(xì)節(jié)的問題掃描的次序:先上后下進(jìn)棧的次序:先右后左測試數(shù)據(jù):第一個多邊形:A(50, 150),B(50, 100),C(100, 50),D(250, 50),E(200, 150);第二個多邊形:F(100, 100),G(100, 75),H(175, 135);*/#include #include #include #include #include /creat a stackstruct stack_node/stack_node() ne*t=NULL; /定義構(gòu)造函數(shù)int *;int y;stack_node *ne*t;ty

42、pedef stack_node stack_list;typedef stack_list *link;/用單鏈表來表示堆棧link stack = 0; /stack標(biāo)識棧頂指針/push an elementvoid push(int *,int yy)stack_list *new_node;new_node=new stack_list();new_node-*=*;new_node-y=yy;new_node-ne*t=stack;stack=new_node;/pop an elementvoid pop(int &*,int &yy)link top;top=stack;*=s

43、tack-*;yy=stack-y;stack=stack-ne*t;delete top;/fill the plotvoid fill(int *,int y)int *0,y0,*l,*r,*lold,*rold;/*0,y0用來標(biāo)記*,y的值,*l記錄*的最左值,*r記錄*的最右值*/int go=0,go2=0;int i=0;push(*,y);/種子像素入棧while(stack!=0)/如果棧不空則循環(huán),stack=0表示??誫o=0; /go只是一個標(biāo)記pop(*,y); /從棧中將棧頂元素彈出putpi*el(*,y,4); /將該點置色*0=*+1;/取種子右邊的像素wh

44、ile(getpi*el(*0,y)!=4)/fill right 填充右邊像素putpi*el(*0,y,4);*0=*0+1;*r=*0-1;/記錄最右值*rold=*r;/再記錄一次最右值,以備后用*0=*-1;/取種子左邊的像素while(getpi*el(*0,y)!=4)/fill left 填充左邊像素putpi*el(*0,y,4);*0=*0-1;*l=*0+1;/記錄最左值*lold=*l;/再記錄一次最左值,以備后用y0=y+1;/go up 向上移一條掃描線go2=0;/go2 也只是一個用來標(biāo)記的變量while(*r*l&go=0)/查找上一條線的最右值,并記錄為*r

45、if(getpi*el(*r,y0)=4)/看看上一條掃描線最右值是否超出了當(dāng)前掃描線的坐標(biāo)圍*r=*r-1; /如果超出,則減1elsego=1;/假設(shè)go=1這句執(zhí)行的話就說明找到了最右值,并在while中的go=0中判斷并退出whilewhile(*l*r&go2=0)/查找上一條線的最左值,并記錄為*lif(getpi*el(*l,y0)=4)/看看上一條掃描線最左值是否超出了當(dāng)前掃描線的坐標(biāo)圍*l=*l+1; /如果超出,則加1elsego2=1;/go2=1這句執(zhí)行就說明找到了最左值,并在此while中的go2=0中退出whileif(go=1&go2=1)/如果找到了最左值和最右

46、值,則執(zhí)行下面的語句push(*r,y0);/先將上一條線上的最右點作為種子點入棧for(i=*l;i*l&go=0)/找下一條掃描線的最右像素if(getpi*el(*r,y0)!=4)go=1;else*r-;while(*l*r&go2=0)/找下一條掃描線的最左像素if(getpi*el(*l,y0)!=4)go2=1;else*l+;if(go=1&go2=1)/如果找到最左和最右,則執(zhí)行push(*r,y0);for(i=*l;i=*r;i+)if(getpi*el(i,y0)!=4)else if(getpi*el(i-1,y0)!=4)push(i-1,y0);void mai

47、n()void fill(int *,int y);int gdriver,gmode;/*顯示模式*/detectgraph(&gdriver,&gmode);initgraph(&gdriver,&gmode,);int i,j;int n,u,p*,py,p*0,py0,p*1,py1;int ya=0,yi=getma*y();printf(pleas input the number of the polygons:);scanf(%d,&u);/看看終究有多少個多邊形(可能多邊形里包含了多邊形)for(int k=0;ku;k+)printf(pleas input the num

48、ber of the top points:);scanf(%d,&n);/看看該多邊形終究有幾個端點for(i=0;in;i+)/從鍵盤承受各頂點的坐標(biāo),依次入棧,并記錄最大Y值和最小Y值printf(please input the coordinate of the points-like:100,200 :);scanf(%d,%d,&p*,&py);if(yapy)yi=py;/yi是最小Y值push(p*,py);setbkcolor(0); /cleardevice(); setcolor(4);pop(p*0,py0);/輸入的最后一個頂點出棧p*=p*0;py=py0;/記錄

49、最后一個頂點/draw the plotwhile(stack != 0)pop(p*1,py1);line(p*0,py0,p*1,py1);p*0=p*1;py0=py1;delay(500);/時延,慢慢畫line(p*0,py0,p*,py);/依次畫線,畫出多邊形/畫完多邊形后,棧為空/find the y valuej=(ya+yi)/2;/找Y的中間值,就是第一個種子點的Y值i=0;n=0;/記錄入棧個數(shù)/find the seed elementwhile(igetma*()&n!=2)/按*值從0到*最大值依次查找,并在入棧個數(shù)為2的時候退出if(getpi*el(i,j)=

50、4)/如果是多邊形上的點,則入棧,用n記錄入棧的個數(shù)push(i,j);n=n+1;i=i+1;/i是記錄當(dāng)前的*值pop(i,j);/第二個交點出棧pop(n,j);/第一個交點出棧,雖然覆蓋了Y值,但這不重要,我們要的是*值i=(i+n)/2;/現(xiàn)在i是我們要找的種子點的*值 /fill the plotfill(i,j);/將種子點作為參數(shù)傳入fill()方法delay(1000);outte*t*y(100,410,the red line was drawing,fill over);getch();closegraph();特別指出:該程序在理論上是沒有問題的,但是由于使用了lin

51、e函數(shù),導(dǎo)致*些多邊形的端點數(shù)據(jù),會出現(xiàn)運(yùn)行未果或者錯誤的問題。出現(xiàn)這種錯誤的原因就是line函數(shù)采用了離散的像素點來取代連續(xù)的邊界點。大家可以試試u=1,n=3,F(xiàn)(100, 100),G(100, 75),H(175, 135),如圖(a)所示;此時的問題在于種子的選取,計算出來的種子y坐標(biāo)為105,沒有問題,此時i從0開場向右搜索,遇到兩個邊界點分別記錄并在第二個邊界點停頓搜索,則記錄的應(yīng)該分別是A點(110, 105)和B點(137.5, 105),然后種子的*坐標(biāo)就應(yīng)該是(110+137.5)/2=123,結(jié)果程序運(yùn)行后居然是(110+111)/2=110,這個結(jié)果說明A點是邊界,A

52、點緊右相鄰的點也是邊界點,看這個圖就知道不可能啊,在理論上是絕不可能。但是看看圖(b)就知道在實際上是可能的而且是經(jīng)常發(fā)生的。如果一旦出現(xiàn)了這種情況,fill()函數(shù)里面的諸多判斷也會出現(xiàn)問題,而且這個問題是隨著多邊形的端點數(shù)據(jù)的變化而難以捕捉。105AB圖(a)圖(b)16. 四邊形各頂點坐標(biāo)為(0, 0),(20, 0),(20, 15)和(0, 15),對此圖形分別進(jìn)展以下比例變換:(1) 使長度方向縮小一半,高度方向增長一倍;(2) 使整個圖形放大一倍。解:如下圖,實線局部為原圖,虛線局部為變換后得到的圖形: Y 30 15 (1) (2)10 20 40 *(1) 原先坐標(biāo) 變換矩陣

53、 變換后坐標(biāo)*=(2) 原先坐標(biāo) 變換矩陣 變換后坐標(biāo)*= 歸一化 17.三角形各頂點坐標(biāo)為10,10,10,30,30,15,試對其進(jìn)展以下變換,寫出變換矩陣,畫出變換后的圖形。沿*向平移20,沿Y向平移15,再繞原點旋轉(zhuǎn)90度繞原點旋轉(zhuǎn),再沿*向平移20,沿Y軸平移15解:1由二維圖形變換相關(guān)知識,可得變換矩陣為1 0 0 cos90 sin 90 0 0 1 00 1 0 -sin90 cos90 0 = -1 0 020 15 1 0 0 1 -15 20 1根據(jù)得出的新坐標(biāo)可畫出圖形圖形略新坐標(biāo)的值為-25, 30-45, 30-30, 502變換矩陣為:10 10 1 0 1 0T

54、= 10 30 1 -1 0 030 15 1 20 15 1 坐標(biāo)數(shù)據(jù)點 變換矩陣10 25 1T= -10 25 15 45 1由得出的新坐標(biāo)畫圖圖形略18.直線方程y=k*+b*/a+y/b=1(a!=0.b!=0)試求出圖形對該直線進(jìn)展對稱變換得變換矩陣解:(1) k*-y+b=0=arctg(-A/B) =arctgk(1) cos2 sin2 0T= sin2 -cos2 0 (2)(Cos2-1)C/A sin2C/A 1將(1)代入(2)式可得變換矩陣,并根據(jù)萬能公式sin2 =2sincos cos2 =cos2-sin2 tg =sin/cos 可得 1-K2/1+K2 2

55、K/1+K2 0T= 2K/1+K2 K2-1/K2+1 0-2bK/1+K2 2b/1+K2 1(2)*/a +y/b =1b*+ay-ab=0所以=arctg(-A/B)=arctg(-b/a).(3)將(3)代入(2)式得 (a2-b2)/(a2+b2) -2ab/(a2+b2) 0T= -2ab/(a2+b2) (b2-a2)/(b2+a2) 0 2ab2/(a2+b2) 2a2b/(a2+b2) 119. 編一程序?qū)崿F(xiàn)直線的編碼裁剪法解:具體源代碼如下所示:#include graphics.h #include conio.h#include math.h#include stdi

56、o.hint w1=90, w2=270, w3=40, w4=160;/定義窗口的幾個關(guān)鍵點坐標(biāo)void clipline(char *a,int &*,int &y,int *1,int y1,int *2,int y2) /求出與區(qū)域中各個方向邊的交點int *t1=0,yt1=0,*t2=0,yt2=0,*t3=0,yt3=0,*t4=0,yt4=0;if(*a=1)yt1=y1+(y2-y1)*(w1-*1)/(*2-*1);*t1=w1; /求左交點if(*(a+1)=1)yt2=y1+(y2-y1)*(w2-*1)/(*2-*1);*t2=w2; /求右交點if(*(a+2)=1

57、)*t3=*1+(*2-*1)*(w3-y1)/(y2-y1);yt3=w3; /求下交點if(*(a+3)=1)*t4=*1+(*2-*1)*(w4-y1)/(y2-y1);yt4=w4; /求上交點/有可能會求出兩個交點,例如左交點和上交點,必然有一個是超出窗口圍的/必須將其排除if(*t1=90 & yt1=40) *=*t1; y=yt1;if(*t2=90 & yt2=40) *=*t2; y=yt2;if(*t3=90 & yt3=40) *=*t3; y=yt3;if(*t4=90 & yt4=40) *=*t4; y=yt4;void code(int *i, int yi,

58、char *a) /四位編碼的實現(xiàn)if(*iw2) *(a+1)=1; /右if(yiw4) *(a+3)=1; /上return;void clipdraw(int *1, int y1, char *a, int *2, int y2, char *b) int *11,y11,*21,y21;int s1=0,s2=0;code(*1,y1,a); /得到直線第一個端點的編碼code(*2,y2,b); /得到直線第二個端點的編碼 if(*a=0 & *b=0 & *(a+1)=0 & *(b+1)=0 & *(a+2)=0 & *(b+2)=0 & *(a+3)=0 & *(b+3)=

59、0)line(*1,y1,*2,y2); /假設(shè)兩個端點的編碼全為0,則直線完全可見else if(a0-48)*(b0-48)+(a1-48)*(b1-48)+(a2-48)*(b2-48)+(a3-48)*(b3-48)=0) /兩端點四位編碼的邏輯乘為0if(!(a0=0&a1=0&a2=0&a3=0) /第一個端點不在窗口,求與窗口交點clipline(a,*11,y11,*1,y1,*2,y2);s1=1;if(!(b0=0&b1=0&b2=0&b3=0) /第二個端點不在窗口,求與窗口交點clipline(b,*21,y21,*1,y1,*2,y2);s2=1;if(s1=1&s2

60、=1) line(*11,y11,*21,y21); /說明兩個端點均不在窗口,直線與窗口有兩個交點if(s1=1&s2=0) line(*11,y11,*2,y2); /說明第一個端點不在窗口,第二個在,直線與窗口有一個交點if(s1=0&s2=1) line(*1,y1,*21,y21); /說明第二個端點不在窗口,第一個在,直線與窗口有一個交點void main()int *1,y1,*2,y2;scanf(%d%d%d%d,&*1,&y1,&*2,&y2);/讀入直線兩個端點的坐標(biāo)char a4=0,0,0,0;char b4=0,0,0,0; /分別初始化兩個端點的編碼數(shù)組int d

溫馨提示

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

評論

0/150

提交評論