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

下載本文檔

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

文檔簡介

第一章1、試述計算機(jī)圖形學(xué)研究的基本內(nèi)容?答:見課本P5-6頁的L1.4節(jié)。2、計算機(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ù)字。3、計算機(jī)圖形學(xué)與CAD、CAM技術(shù)關(guān)系如何?答:見課本P4-5頁的LL3節(jié)。4、舉3個例子說明計算機(jī)圖形學(xué)的應(yīng)用。答:①事務(wù)管理中的交互繪圖應(yīng)用圖形學(xué)最多的領(lǐng)域之一是繪制事務(wù)管理中的各種圖形。通過從簡明的形式呈現(xiàn)出數(shù)據(jù)的模型和趨勢以增加對復(fù)雜現(xiàn)象的理解,并促使決策的制定。②地理信息系統(tǒng)地理信息系統(tǒng)是建立在地理圖形基礎(chǔ)上的信息管理系統(tǒng)。利用計算機(jī)圖形生成技術(shù)可以繪制地理的、地質(zhì)的以及其它自然現(xiàn)象的高精度勘探、測量圖形。③計算機(jī)動畫用圖形學(xué)的方法產(chǎn)生動畫片,其形象逼真、生動,輕而易舉地解決了人工繪圖時難以解決的問題,大大提高了工作效率。5、計算機(jī)繪圖有哪些特點?答:見課本P8頁的1.3.1節(jié)。6、計算機(jī)生成圖形的方法有哪些?答:計算機(jī)生成圖形的方法有兩種:矢量法和描點法。①矢量法:在顯示屏上先給定一系列坐標(biāo)點,然后控制電子束在屏幕上按一定的順序掃描,逐個“點亮”臨近兩點間的短矢量,從而得到一條近似的曲線。盡管顯示器產(chǎn)生的只是一些短直線的線段,但當(dāng)直線段很短時,連成的曲線看起來還是光滑的。②描點法:把顯示屏幕分成有限個可發(fā)亮的離散點,每個離散點叫做一個像素,屏幕上由像素點組成的陣列稱為光柵,曲線的繪制過程就是將該曲線在光柵上經(jīng)過的那些像素點串接起來,使它們發(fā)亮,所顯示的每一曲線都是由一定大小的像素點組成的。當(dāng)像素點具有多種顏色或多種灰度等級時,就可以顯示彩色圖形或具有不同灰度的圖形。7、當(dāng)前計算機(jī)圖形學(xué)研究的課題有哪些?答:見課本P10T1頁的1.4節(jié)。8、簡述三維圖形生成和輸出的流水線?答:見課本P13頁1.5.6.節(jié)。9、向量圖形和點陣圖形之間的區(qū)別有哪些?答:通過矢量法產(chǎn)生的圖形稱為矢量圖形或者向量圖形,用描點法產(chǎn)生的圖形稱為點陣圖形。向量圖形區(qū)別點陣圖形的特點在于描述圖形幾何形狀的數(shù)學(xué)模型及依據(jù)此模型生成幾何圖形的計算機(jī)命令。向量圖形由各個基本圖形構(gòu)成,這就要求各個基本圖形有各自獨(dú)立的信息。如果用點陣圖形來表示一個向量圖形,構(gòu)成向量圖形的某個基本圖形(如直線段、圓弧等)的所有點應(yīng)有一個信息。因此,在描述一個基本圖形時,同時要描述其相應(yīng)的信息。向量圖形最基本的優(yōu)點是它本身是由精確的數(shù)據(jù)給出,所以可以充分利用各種輸出圖形設(shè)備的分辨率盡可能精確地輸出圖形。也正因為如此,向量圖形的尺寸可以任意變化而不損失圖形顯示的質(zhì)量。但是向量圖形僅適合于描繪簡單圖形,而點陣圖形可以描繪絢爛多彩的復(fù)雜圖形。10、什么是虛擬現(xiàn)實技術(shù)和可視化技術(shù)?答:虛擬現(xiàn)實技術(shù):利用計算機(jī)生成一種模擬環(huán)境,通過多種傳感器和設(shè)備使用戶“投入”到該環(huán)境中,實現(xiàn)用戶和該環(huán)境直接進(jìn)行交互的技術(shù)。例如模擬飛機(jī)駕駛艙。可視化技術(shù):通過對空間數(shù)據(jù)場構(gòu)造中間幾何因素,或用圖形繪制技術(shù)在屏幕上產(chǎn)生二維圖像。例如分子模型構(gòu)造。第一草1、計算機(jī)圖形系統(tǒng)有什么特點?有哪些主要功能?答:課本2.1.1的圖22、計算機(jī)圖形系統(tǒng)有哪幾種?各有什么特點?答:一種分類方法:交互式圖形系統(tǒng)允許操作者以某種方式(對話方式或命令方式)來控制和操作圖形生成過程,使得圖形可以邊生成、邊顯示、邊修改,直至符合要求為止。而被動式繪圖系統(tǒng),圖形在生成過程中,操作者無法對圖形進(jìn)行實時操作和控制,不具備交互功能,只提供各種圖形命令或圖形程序庫,通過編程獲得所需圖形。另一種分類方法:見課本2.L3節(jié),分為脫機(jī)繪圖系統(tǒng)、聯(lián)機(jī)繪圖系統(tǒng)和交互式繪圖系統(tǒng)。3、陰極射線管由哪些部分組成?它們的功能分別是什么?答:CRT由四部分組成:電子槍、聚焦系統(tǒng)、偏轉(zhuǎn)系統(tǒng)和熒光屏,這四部分都在真空管內(nèi)。電子槍由燈絲、陰極和控制柵極組成。燈絲加熱陰極,陰極表面向外發(fā)射自由電子,控制柵控制自由電子是否向熒光屏發(fā)出,若允許電子通過,形成的電子流在到達(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),若每一像素用8位和12位二進(jìn)制來表示存儲信息,各需多大光柵存儲容量以及顯存?每一屏幕最多能顯示多少顏色?若R,G,B灰度都占8位,其顯示顏色的總數(shù)是多少?解:1)每一像素用8位二進(jìn)制來表示存儲信息,所需容量為1024*1024*1=22。(Byte)=1MB彩色素:28=256(項)2)若每一像素用12位二進(jìn)制表示存儲信息,所需容量為:1024*1024*1.5=1.5*220(Byte)=1.5MB(由于顯示卡的顯存是按2的指數(shù)次倍增長的,因此所需顯存為2M)彩色素:*=4096(項)3)顏色總數(shù):28*2**28=2"(種)6、對于19英寸顯示器,若X和Y兩方向的分辨率相等,即1024*1024,那么每個像素點的直徑是多少?解:也半=0.33(mm)或」■尸=0.013(英寸)1024V2 1024V27、對于分辨率為1024X768的光柵系統(tǒng),若調(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)系。第一種是供應(yīng)用程序使用的實際世界坐標(biāo)系統(tǒng)(WorldCoordinateSystem,簡稱WC);第二種是GKS內(nèi)部使用的規(guī)范設(shè)備坐標(biāo)系(NormalizedDeviceCoordinate,簡稱NDC),它的取值范圍為[0,1],這是一種既與設(shè)備無關(guān)也與應(yīng)用無關(guān)的坐標(biāo)系;第三種是各工作站物理設(shè)備使用的設(shè)備坐標(biāo)系(DeviceCoordinateSystem,簡稱DC)OGKS只支持二維對象的圖形處理,因此上述3個坐標(biāo)系都是二維坐標(biāo)系。詳見課本圖3.28的描述。9、GKS中輸入設(shè)備有哪6種邏輯功能?請各舉出對應(yīng)的物理設(shè)備。答:見課本2.4.5.節(jié)。10、當(dāng)前主流的圖形軟件有哪些?答:見課本2.6.3節(jié)。第三章1、編寫畫一正方形程序,并在其中用不同的顏色畫15個正方形,每一個都比前一個小。ttinclude“graphics,h”ttinclude"conio.h"voidmain()(inti,color=0,ls=0;intj=700;intgdriver=VGA;intgmode=VGAHI;initgraph(&gdriver,&gmode,”3-1批改說明;setbkcolor(15);?必須至少包含"graphics.h〃for(i=0;i<225;i=i+15,?initgraph(&gdriver,&gmode,〃〃);(?必須包含15個正方形,一般用forsetcolor(color);循環(huán),也可能用到while等。bar(i,i,j,j);color++;ls++;getch();closegraph();2、用不同的線形繪制題1中的圖形ttinclude“graphics,h”ttincludeaconio.hvvoidmain()(inti,color=l,ls=0;intj=700;3-2批改說明;intgdriver=VGA;?注意查看3」部分內(nèi)容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);或者setlinestyle(4,Is,3);rectangle(i,i,j,j);setfillstyle(SOLID_FILL,color);//floodfill(getmaxxO/2,getmaxy()/2,color); 此句會出現(xiàn)最后只用一種顏色填充的情況color++;ls++;getch();closegraph();}3、畫一五顏六色的圖(此例為畫一個五顏六色的圓)ttinclude“graphics,h”ttinclude“conio.h"voidmain()intdriver=DETECT,mode=0;inti,start,end;initgraph(&driver,&mode,"”)3-3批改說明;start=0;?必須至少包含"graphics.h〃end=20;?initgraph(&gdriver,&gmode,for(i=0;i<18;i++)setfillstyle(SOLID_FILL,i);pieslice(300,200,start,end,100);start+=20;end+=20;)getch();restorecrtmode();4、編寫一輛自行車在一公路上由右至左快速行駛的程序。#include"stdlib.h"#include"graphics.h"#include*conio.h"#include*stdio.h"voidmain(){void*w;intdriver=DETECT,mode=0,i,start,end,j;initgraph(&driver,&mode,"");cleardevice();setbkcolor(15);setcolor(CGA-LIGHTGREEN);start=0;end=180;circle(387,290,37);circle(525,290,37);line(404,217,398,230);line(436,217,429,230);line(398,230,429,230);line(413,230,387,290);line(387,290,525,290);line(408,243,484,243);line(387,290,484,243);line(484,243,525,290);line(444,290,484,243):line(444,290,446,279):line(444,290,443,300);line(438,277,444,278);line(435,300,451,301);line(484,243,487,233);line(472,233,502,233); 〃自行車基本輪廓的繪制w=malloc(imagesize(350,200,562,327));getimage(350,200,562,327,w);for(i=350,j=0;i>0;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,COPYPUT);line(2,327,562,327);delay(lO); 〃自行車行駛動畫的實現(xiàn))for(i=0;i<10;i++){pieslice(37,290,start,end,37);pieslice(175,290,start,end,37);start+=40;end+=40;} 〃處于靜止?fàn)顟B(tài)的自行車車輪的軸線的繪制getchO;restorecrtmode();closegraph();)5、試自行設(shè)計一個美術(shù)圖案,并且用程序?qū)崿F(xiàn)。(略)第四章.為什么說直線生成算法是二維圖形生成技術(shù)的基礎(chǔ)?答:無論什么復(fù)雜圖形,它們都是由直線段和曲線段組成(三維圖形經(jīng)投影后最終變成了二維圖形),而圖形設(shè)備顯示曲線段時,最終還是將曲線段轉(zhuǎn)化成一系列直線段逼近表示的。因此,所有圖形都可以看成是由直線段組成的??蓞⒖颊n本圖4.1。.根據(jù)DDA畫直線算法,遍一程序求(0,0)到(4,12)和(0,0,)到(12,4)的直線#includegraphics.hnttinclude"math,h”voidDDA_Line(intxl,intyl,intx2,inty2)floatincrex,increy,x,y,length;if(abs(x2-xl)>abs(y2-yl))length=abs(x2-xl);elselength二abs(y2-yl);increx=(x2-xl)/length;increy=(y2-yl)/length;x=xl;y二yl;for(i=l;i<=length;i++)(putpixel(x,y,1);x=x+increx;y二y+increy;))voidmain()(intdriver=DETECT,mode=0;initgraph(&driver,&mode,"“);intxl=0,yl=0,x2=4,y2=12;intx3=12,y3=4;DDA_Line(xl,yl,x2,y2);DDA_Line(xl,yl,x3,y3);getch();}.根據(jù)逐點比較法編一程序畫一段圓弧,其圓心為(0,0),圓弧兩點為A(5,0)、B(0,5)方法L順4象限itinclude"graphics.h〃ttinclude"stdio.h"ttinclude"conio.h〃voidZDBJARC(floatxO,floatyO,floatxl,floatyl,floatx2,floaty2);voidmain()(intgdriver=CGA,mode=CGAC0;initgraph(&gdriver,ftmode,〃〃);ZDBJ_ARC(O,0,25,0,0,25);getchO;closegraph();}voidZDBJ_ARC(floatxO,floatyO,floatxl,floatyl,floatx2,floaty2)floatf=0.0,F;floatdx=l,dy=l;while(abs(xl-x2)>1){if(f>=0)(xl=xl-dx;yl=yl;putpixel(xl,yl,1);f=f-2*dx*(xl-xO)+dx*dx;)else{xl=xl;yl=yl+dy;putpixel(xl,yl,1);f=f+2*dy*(yl-yO)+dy*dy;方法2:逆4象限tiinclude"graphics,h”#include"stdlib.h"ttinclude"conio.h〃voidZDBJARC(floatxO,floatyO,floatxl,floatyl,floatx2,floaty2);voidmain()(intgdriver=CGA,mode=CGAC0;initgraph(&gdriver,&mode,〃〃);ZDBJ_ARC(0,0,0,25,25,0);getchO;closegraph();)voidZDBJ_ARC(floatxO,floatyO,floatxl,floatyl,floatx2,floaty2)(floatf=0.0,F;floatdx=l,dy=l;while(abs(yl-y2)>1){if(f>0)(xl=xl;yl=yl-dy;putpixel(xl,yl,1);f=f-2*dy*abs(yl-yO)+dy*dy;

elsexl=xl+dx;yl=yl;putpixel(xl,yl,1);f=f+2*dx*abs(xl-xO)+dx*dx;方法3:順1象限ttinclude“graphics,h” 〃省略了圖形初始化的步驟itincludeaconio.h"#include"math,h”voidmain()intxl=5,yl=0,x2=0,y2=5;intx0=0,y0=0;intR=sqrt((x2-xO)*(x2-x0)+(y2-y0)*(y2-y0));intdx=abs(x2-xl);intdy=abs(y2-yl);intn=dx+dy;putpixel(x2,y2,1);intf;intx=x2,y=y2;for(inti=0;i<n;i++)■f二(x-xO)*(x-xO)+(y-yO)*(y-yO)-R*R;if(f>=0)putpixel(x,y一,1);elseputpixel(x++,y,1);}getchO;closegraph();) 〃另一種做法是采用課本P97頁表4.2的公式.編一程序用角度DDA法畫一圓〃以圓點為圓心,半徑為20的圓ttinclude“graphics,h”〃省略了圖形初始化的步驟ttinclude“conio.h"ttinclude“math,h”voidmain()(intx0=0,y0=0,R=20;intN=R*8;floata=2*3.14/N;xl=20,yl=0;for(inti=l;i<=N;i++)(xi=xO+R*cos(i*a)yi=yO+R*sin(i*a);line(xl,yl,xi,yi);xl=xi;yl=yi;)getchO;closegraph();).如果線段端點坐標(biāo)值不是整數(shù),采用DDA算法產(chǎn)生的直線和將端點坐標(biāo)值先取整后再用Bressenham算法產(chǎn)生的直線是否完全相同?為什么?能否擴(kuò)充整數(shù)Bressenham算法使之能夠處理當(dāng)線段端點坐標(biāo)值不是整數(shù)的情況。答:不相同。因為DDA算法總是選擇或者Ay中的較大者作為步進(jìn)的方向,不失一般性,假設(shè)選擇x方向,則x方向每前進(jìn)一個像素點,y方向前進(jìn)的像素點個數(shù)應(yīng)該在[0,1]區(qū)間,但是由于采用了(向上或者向下或者四舍五入)取整運(yùn)算,必然會導(dǎo)致某些像素點偏在了真實直線的一側(cè)。而Bressenham算法每一步都會根據(jù)實際直線與網(wǎng)格的距離來決定下一個像素點的選擇,因此所選像素點更加貼近于真實的直線??梢詳U(kuò)充整數(shù)Bressenham算法使之能夠處理當(dāng)線段端點坐標(biāo)值不是整數(shù)的情況。.若采用Bresenham算法實現(xiàn)畫圓,寫出算法實現(xiàn)的具體流程(包括判別公式推導(dǎo)等等)。答:給定圓心在原點,半徑為R的圓,其方程為x?+y2=R2,構(gòu)造函數(shù)F(x,y)=x2+y2-RS對于圓上的點,有F(x,y)=0;對于圓外的點,F(xiàn)(x,y)>0;而對于圓內(nèi)的點,F(xiàn)(x,y)<0o此處僅考慮如圖所示的第一象限內(nèi)xw[p,R/a」的1/8圓弧,此時中點Bresenham畫圓算法要從(0,R)至U(R/痣,R/痣)順時針地確定最佳逼近于該圓弧內(nèi),這說明Pu離圓弧更近,應(yīng)取其為下一個像素點;當(dāng)F(網(wǎng),yM)>0,M在圓外,說明Pd離圓弧更近;當(dāng)F(Xm,y?)=0,則約定取Pd。構(gòu)造判別式&=F(Xm,yM)=F(xj+1,y]0.5造(xi+l)2+(y,-0.5)2-R2(1)當(dāng)&<0,取Pu(xi+1,yj,計算下一步的的判別式&-i=F(Xu,yu)=F(xj+2,y[0.5)=(x,+2尸+(丫]0.5尸-R2=&+2xi+3所以沿正右方向,&的增量為2xi+3。(2)當(dāng)&N0,取Pd(Xi+1,yi+l),計算下一步的的判別式&*尸F(xiàn)ix”yd)=F(x(+2,y-1.5)=(x,+2)2+(yi-l.5)2-R2=di+2(x「yJ+5所以沿右下方向,&的增量為2(x「y,)+5。顯然,所繪制圓弧段的第一個像素為Po(O,R),因此判別式d。的初始值為1.25-R,可以令d'=d-0.25來擺脫小數(shù)運(yùn)算,則判別式&以對應(yīng)于&<-0.25,由于d始終是整數(shù),&<-0.25等價于&<0、.已知4個型值點(L0,2.0),(2.5,3.5),(4.0,4.5),(5.0,4.0),求各段三次樣條曲線。Si(X)(i=l,2,3),設(shè)邊界條件為拋物線端解:ml=x2-xl=l.5,m2=x3-x2=l.5,m3=x4-x3Fh;A.2=m2/(m2+ml)=0.5; 八°0u2=ml/(ml+m2)=0.5;X3=m3/(m2+m3)=0.4;u3=m2/(m2+m3)=0.6;R2=3*[u2*(y3-y2)/m2+X2*(y2-yl)/ml]=2.5;R3=3*[u3*(y4-y3)/m3+X3*(y3-y2)/m2]=-0.1;于是有TOC\o"1-5"\h\z0.5bl+2b2+0.5b3=2.5 (1)0.4b2+2b3+0.6b4=-0.1 (2)又邊界拋物線端bl+b2=2 (3)b3+b4=-l (4)bl=39/38,b2=37/38,b3=3/38,b4=-41/38從而cl=-l/57;dl=O;c2=-l/57;d2=-64/513;c3=-ll/19;d3=0;故可得si(x)=2+39/38(x-1)-1/57(x-1)2xe[1.0,2.5]s2(x)=3.5+37/38(x-2.5)T/57(x-2.5)2-64/513(x-2.5尸 xe[2.5,4.0]s3(x)=4.5+3/38(x-4)-11/19(x-4)2xe[4.0,5.0]8.已知4個型值點坐標(biāo)值P0(5,5)、Pl(10,15)、P2(15,10)、P3(10,5),繪一個三次貝塞爾曲線。解:用矩陣表示為p(t)=[t'tJt1]PEpOplp2p3]TP=-13-313-6301-330)0p(0)=[5,5]p(0.15)=[7.215,8.536]p(0.35)=[9.83,10.64]p(0.5)=[11.25,10.625]p(0.65)=[12.015,9.615]p(0.85)=[11.606,7.198]P(D=[10,5]將上面各點相連可以畫出三次貝塞爾曲線。9.編寫一個繪制Bezier曲線的程序。該程序根據(jù)以下數(shù)據(jù)點[x,y]:[50,100][80,230][100,270][140,160][180,50][240,65][270,120][330,230][380,230][430,150]計算出結(jié)果,并實現(xiàn)三段首尾相接的三次貝塞爾曲線在屏幕上顯示的功能,采用了C++語言實現(xiàn);#include“graphics,h”#include"conio.h"ttinclude*stdio.h"typedefstruct(doublex,y;}DPOINT;〃定義結(jié)構(gòu)體classBezier 〃定義Bezier類(private:DPOINT*bP;intmmaxIndex;voiddrawFrame();voiddrawCurve();voiddrawCurve(intpO,intpl,intp2,intp3);public:Bezier(DPOINT*p,intlen);〃定義構(gòu)造函數(shù)voiddraw();Bezier::Bezier(DPOINT*p,intlen)//構(gòu)造函數(shù)的實現(xiàn)(this->bP=p;m_maxlndex=len-l;}voidBezier::draw()〃通過公有函數(shù)調(diào)用私有函數(shù)(drawFrame();drawCurve();}voidBezier::drawFrame()〃其功能是繪制出多邊形和各個端點{setcolor(12);for(inti=0;i<m_maxIndex;i++){line(bP[i].x,bP[i].y,bP[i+l].x,bP[i+l].y);〃繪制多邊形circle(bP[i].x,bP[i].y,5);〃繪制各個端點)circle(bP[m_maxIndex].x,bP[m_maxIndex].y,5);}voidBezier::drawCurve()〃實現(xiàn)多段Bezier曲線繪制的功能(for(inti=0;i〈二mmaxIndex-3;i+=3)(drawCurve(i,i+1,i+2,i+3);)}voidBezier::drawCurve(intpO,intpl,intp2,intp3)〃實現(xiàn)繪制某一段Bezier曲線的功能(doubletmpx=0.0;doubletmpy=0.0;doublet=0.0;for(;t<=l.0;t+=0.001){tmpx=(-bP[p0].x+3*bP[pl].x-3*bP[p2].x+bP[p3].x)*t*t*t+(3*bP[pO].x-6*bP[pl].x+3*bP[p2].x)*t*t+(-3*bP[p0].x+3*bP[pl].x)*t+bP[p0].x;tmpy=(-bP[p0].y+3*bP[pl].y-3*bP[p2].y+bP[p3].y)*t*t*t+(3*bP[p0].y-6*bP[pl].y+3*bP[p2],y)*t*t+(-3*bP[pO].y+3*bP[pl].y)*t+bP[pO].y;putpixel(tmpx,tmpy,3);})voidmain()〃主函數(shù)的實現(xiàn){intgraphdriver=DETECT,graphmode;initgraph(&graphdriver,&graphmode,"E:\\tc3\\bgi");setbkcolor(15);DPOINT*p;p=newDPOTNTtlO];p[0].x=50.0;p[0].y=100.0;p[l].x=80.0;p[l].y=230.0;p[2].x=100.0;p[2].y=270.0;p[3].x=140.0;p[3].y=160.0;p[4].x=180.0;p[4].y=50.0;p[5].x=240.0;p[5].y=65.0;p[6].x=270.0;p[6].y=120.0;p[7].x=330.0;p[7].y=230.0;p[8].x=380.0;p[8].y=230.0;p[9].x=430.0;p[9].y=150.0;Bezierbzr(p,10);bzr.draw();deletep;getchO;closegraph();)10.編寫一個繪制B樣條曲線的程序。該程序根據(jù)以下數(shù)據(jù)點[x,y]:P0[50,130]Pl[120,40]P2[100,270]和P3[140,160]計算出結(jié)果,并實現(xiàn)兩段首尾相接的兩次B樣條曲線在屏幕上顯示的功能,采用了C++語言實現(xiàn);將已知點代入式(4-19)可得兩段兩次B樣條曲線方程:TOC\o"1-5"\h\z-1 -2 11 [50 130'/^(t)=1[f2t1] -2 2 0 120 40J 1 oj[100 270=[-45160]/+[70-90]t+[8585]TOC\o"1-5"\h\z-1 -2 11 120 40/>(t)=1[t1] -2 2 0 100 270J 1 0j [140 160155]=[30-170] +[-20230]t+[110155]ttinclude“graphics,h”#include'conio.h"#include*stdio.h"typedefstruct(doublex,y;}DPOINT;〃定義結(jié)構(gòu)體classB_Spline〃定義B樣條曲線類(private:DPOINT*bP;intm_maxlndex;〃有多少個型值點voiddrawFrame();voiddrawCurve();voiddrawCurve(intpO,intpl,intp2);public:BSpline(DPOINT*p,intlen);〃定義構(gòu)造函數(shù)voiddraw();};B_Spline::B_Spline(DPOINT*p,intlen)〃構(gòu)造函數(shù)的實現(xiàn)(this->bP=p;mmaxlndex=len;)voidB_Spline::draw()〃通過公有函數(shù)調(diào)用私有函數(shù){drawFrame();drawCurve();)voidB_Spline::drawFrame()〃其功能是繪制出多邊形和各個端點(setcolor(12);for(inti=0;i<m_maxlndex-l;i++){line(bP[i].x,bP[i].y,bP[i+l].x,bP[i+l].y);〃繪制多邊形circle(bP[i].x,bP[i].y,5);〃繪制多邊形各個端點circle(bP[m_maxIndex-1],x,bP[m_maxIndex-1].y,5);voidBSpline::drawCurve()〃實現(xiàn)多段B樣條曲線繪制的功能(for(inti=0;i<m_maxIndex-2;i++)(drawCurve(i,i+1,i+2);))voidB_Spline::drawCurve(intpO,intpl,intp2)〃實現(xiàn)繪制某一段Bezier曲線的功能(doubletmpx=0.0;doubletmpy=0.0;doublet=0.0;for(;t<=1.0;t+=0.001)(tmpx=(0.5*bP[pO].x-bP[pl],x+0.5*bP[p2].x)*t*t+(-bP[pO].x+bP[pl].x)*t+0.5*bP[pO].x+0.5*bP[pl].x;tmpy=(0.5*bP[pO].y-bP[pl],y+0.5*bP[p2].y)*t*t+(-bP[pO].y+bP[pl].y)*t+O.5*bP[pO].y+0.5*bP[pl].y;putpixel(tmpx,tmpy,3);)}voidmainO〃主函數(shù)的實現(xiàn)(intgraphdriver=DETECT,graphmode;initgraph(&graphdriver,&graphmode,**);〃圖形初始化setbkcolor(15);DPOINT*p;p=newDPOINT[4];p[0].x=50.0;p[0].y=130.0;p[l].x=120.0;p[l].y=40.0;p[2].x=190.0;p[2].y=130.0;p[3].x=260.0;p[3].y=40.0;BSplinebsp(p,4);b_sp.draw();deletep;getchO;closegraph();.簡述NURBS曲線產(chǎn)生的背景和特點?答:NURBS曲線具有局部可調(diào)性、凸包性、幾何和透視投影變換不變性等等,它采用有理參數(shù)多項式可以精確表示圓錐曲線、二次曲面等,對于幾何造型算法提供了思路。.將下列數(shù)據(jù)X2610121416Y3811131517按最小二乘法曲線擬合,分別求一次和二次多項式曲線,擬合以上數(shù)據(jù)并畫圖表zj\O解:如下表所示:i1236412816268483628821612963101111010011001000100004121315614418721728207365141521019629402744384166161727225643524096655366067802736105649792136000一次多項式的情形:l6即+60%=67 C a0=l.4608、60ao+736a]=802 - q=0.9706所求多項式為y=f(x)=l.4608+0.9706x二次多項式的情形:6a0+60+736a2-67 a0=1.0793J 60劭+736%+9792%=8020J ^=1.0921<736a0+9792ax+136000a2=10564 < a2=~0.006796所求多項式為y=f(x)=l.0793+1.0921X-0.006796x213.設(shè)五邊形的五個頂點坐標(biāo)為(10,10),(15,5),(12,5),(8,2)和(4,5),利用多邊形區(qū)域填充算法,編一程序生成一個實心圖。解:假設(shè)以上五個頂點依次對應(yīng)編號A-B-C-D-E,首先計算得到ET表:6-1010 用于存放AET活動邊表該多邊形的AET指針的內(nèi)容為:1AET為空r\rA/具體編程實現(xiàn)如下:第1步:(1)根據(jù)輸入的五個頂點坐標(biāo)找到y(tǒng)值最小的點(例如點D,此時y=2),并找到與D有邊關(guān)系的兩個頂點(此時為E和C),在y=2處建立ET邊表記錄(ymax、xi和m值均可通過頂點坐標(biāo)間的計算得到,例如DE邊的建立,特別注意:當(dāng)D點和E點y坐標(biāo)值相同時,也即是DE與x軸平行,該邊不能計入ET邊表),之后標(biāo)記D點被訪問過;(2)排除訪問過的點以及和該點相關(guān)聯(lián)的邊,重復(fù)⑴直至將ET表建立完善。[注]邊關(guān)系的建立可通過鄰接矩陣的數(shù)據(jù)結(jié)構(gòu)實現(xiàn),權(quán)值可以為該矩陣行編號對應(yīng)點的y坐標(biāo)值,ET邊表采用鄰接表的數(shù)據(jù)結(jié)構(gòu)第2步:根據(jù)ET表構(gòu)建AET表,并逐行完成多邊形填充,具體的C++代碼如下:(1)建立頭文件base_class.h,主要是邊表結(jié)點結(jié)構(gòu)體和ET邊表類的實現(xiàn)enumResultCode{Success,Failure);template<classT>structEnode(Enode(){next=NULL;}Enode(Tpymax,floatpxi,floatpm,Enode*pnext){ymax=pymax; xi=pxi;m=pm;next=pnext;)Tymax,xi;〃ymax表示最大的y值,xi表示最底端點的x坐標(biāo)值floatm; 〃01表示斜率的倒數(shù)Enode*next;); 〃定義了ET表和AET表中結(jié)點的結(jié)構(gòu)體template<classT>classET(public:ET(intmSize);?ET();ResultCodeInsert(intu,Tymax,floatxi,floatm);intn;〃覆蓋該多邊形的掃描線的總數(shù),從0開始計數(shù)Enode<T>**a;);〃定義了邊表類template<classT>ET<T>::ET(intmSize){n二mSize;a=newEnode<T>*[n];for(inti=0;i<n;i++)a[i]=0;)〃ET邊表的初始化template<classT>ET<T>:<ET()Enode<T>*p,*q;deletea[0];for(inti=l;i<n;i++)(P=a[i];q=p;while(p){p=p->next;deleteq;q=P;})delete[1a;)〃析構(gòu)函數(shù)負(fù)責(zé)回收內(nèi)存空間template<classT>ResultCodeET<T>::Insert(intu,Tymax,floatxi,floatm)(if(u<01|u>n-l)returnFailure;Enode<T>*p=newEnode<T>(ymax,xi,m,a[u]);a[u]=p;returnSuccess;)〃依次插入結(jié)點構(gòu)建出邊表,其中a[l]到a[10]用于構(gòu)建ET邊表〃a[0]用于構(gòu)建活動AET邊表(2)填充函數(shù)的實現(xiàn)和主函數(shù)的實現(xiàn)ttincludez,base_class.h,zttinclude"graphics.h〃ttinclude<iostream.h>voidpo_fill(ET<int>&etp,intep,intcolor)//多邊形填充函數(shù)的實現(xiàn)(inti=l;//i作為控制變量標(biāo)識掃描線while(i<ep-l)(if(etp.a[i]!=NULL)Enode<int>*p,*r;p=etp.a[i];r=etp.a[0];while(p)(Enode<int>*q=newEnode<int>(p->ymax,p->xi,p->m,NULL);if(!etp.a[0]){etp.a[0]=q;r=q;}elseif(r->xi=q->xi){q->next=r->next;r->next=q;r=q;}if(r->xi>q->xi){etp.a[O]=q;q->next=r;}else{while(q->xi>r->xi&&r->next)r=r->next;if(r->next){q->next=r->next;r->next=q;}else{r->next=q;q->next=NULL;}))p=p->next;})〃按照xi值的大小將當(dāng)前ET表中的記錄放置到AET表中Enode<int>*f,*g;if(etp.a[0]){f=etp.a[0];while(f->next){g二f;f=f->next;for(intj=g->xi;j<=g->next->xi;j++)putpixel(j,i,color);)〃把一對相鄰結(jié)點的xi區(qū)間范圍進(jìn)行填充if(etp.a[0]!=NULL)Enode<int>*w;ints=l;while(s){Enode<int>*z=NULL;w=etp.a[0];s=0;while(w&&w->ymax!=i){z=w;w=w->next;)if(!w)break;if(z)z->next=w->next;elseetp.a[0]=w->next;deletew;s=l;}〃刪去AET表中i值已經(jīng)等于ymax的結(jié)點記錄if(etp.a[0])Enode<int>*u,*v;u=etp.a[0];while(u)u=u->next;v->xi=v->xi+v->m;})〃用xi+m來替代原有的xi)i++;〃進(jìn)入下一條掃描線))voidmain()〃主函數(shù)的實現(xiàn){intgdriver,gmode;gdriver=DETECT;gmode=VGAHI;initgraph(&gdriver,&gmode,;〃圖形系統(tǒng)初始化inte=ll;intcolor=5;〃color用于標(biāo)識填充顏色ET<int>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)算,計算出來的像素點坐標(biāo)值將可能與多邊形填充點真實值之間存在偏差,導(dǎo)致所繪制的圖形不完全與實際吻合。14.已知多邊形各頂點坐標(biāo)為(2,2)(2,4)(8,6)(12,2)(8.1)(6,2)及(2,2),在用多邊形區(qū)域填充時,請寫出ET及全部AET內(nèi)容。解:如圖所示:則該多邊形的ET表為:該多邊形的AET指針的內(nèi)容為:(每條掃描線均有3行指針鏈,第1行表示將ET表加入AET中,第2行表示從AET表中刪去y尸y皿,第3行表示Xi=Xi+l/m后,學(xué)生只要寫出第2行即可)該測試多邊形的各個端點坐標(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)該用變量表示以易于修改,畫多邊形和求種子點應(yīng)該做成獨(dú)立的函數(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);*******/ttinclude<graphics.h>ttinclude<stdio.h>ttinclude<dos.h>#include<conio.h>ttinclude<stdlib.h>//creatastackstructstack_node(//stack_node(){next二NULL;}〃定義構(gòu)造函數(shù)intx;inty;stack_node*next;);typedefstack_nodestack」ist;typedefstack_list*1ink;〃用單鏈表來表示堆棧linkstack=0;//stack標(biāo)識棧頂指針//pushanelementvoidpush(intxx,intyy)(stack_list*new_node;new_node=newstack_list();new_node->x=xx;new_node->y=yy;newnode->next=stack;stack=newnode;}//popanelementvoidpop(int&xx,int&yy)(linktop;top=stack;xx=stack->x;yy=stack->y;stack=stack->next;deletetop;)//filltheplotvoidfill(intx,inty){intxO,yO,xl,xr,xlold,xrold;/*xO,yO用來標(biāo)記x,y的值,xl記錄x的最左值,xr記錄x的最右值*/intgo=0,go2=0;inti=0;push(x,y);〃種子像素入棧while(stack!=0)〃如果棧不空則循環(huán),stack==O表示??調(diào)go=0;〃go只是一個標(biāo)記pop(x,y);〃從棧中將棧頂元素彈出putpixel(x,y,4);〃將該點置色xO=x+l;〃取種子右邊的像素while(getpixel(xO,y)!=4)//fillright填充右邊像素{putpixel(xO,y,4);xO=xO+l;)xr=xOT;〃記錄最右值xrold=xr;〃再記錄一次最右值,以備后用xO=x-l;〃取種子左邊的像素while(getpixel(xO,y)!=4)//fillleft填充左邊像素{putpixel(xO,y,4);xO=xO-l;xl=xO+l;〃記錄最左值xlold=xl;〃再記錄一次最左值,以備后用yO=y+l;//goup向上移一條掃描線go2=0;〃go2也只是一個用來標(biāo)記的變量while(xr>xl&&go==0)〃查找上一條線的最右值,并記錄為xr{if(getpixel(xr,y0)==4)〃看看上一條掃描線最右值是否超出了當(dāng)前掃描線的坐標(biāo)范圍xr=xr-l;〃如果超出,則減1else8。=1;〃若8。=1這句執(zhí)行的話就說明找到了最右值,并在while中的go==0中判斷并退出while}while(xl<xr&&go2==0)〃查找上一條線的最左值,并記錄為xl(if(getpixel(xl,y0)==4)〃看看上一條掃描線最左值是否超出了當(dāng)前掃描線的坐標(biāo)范圍xl=xl+l;〃如果超出,則加1elsego2=l;〃go2=l這句執(zhí)行就說明找到了最左值,并在此while中的go2==0中退出whileif(go==l&&go2==D〃如果找到了最左值和最右值,則執(zhí)行下面的語句

push(xr,yO);〃先將上一條線上的最右點作為種子點入棧for(i=xl;i<xr;i++)//從最左到最右循環(huán),在每個連續(xù)區(qū)間上找一個種子點入棧(if(getpixel(i,yO)!=4)〃如果不是邊界點,什么也不做{} 〃這樣做的目的是如果出現(xiàn)ooBBooBBoooBooo的情況,其中o是未填充的點,B是邊界點elseif(getpixel(iT,yO)!=4)〃如果是邊界點,則看它左邊的點是不是邊界點,如果不是,則入棧{push(i-l,yO);〃實際入棧的是最靠近邊界點的右像素yO=y-l;//godown向下移一條掃描線go=0;go2=0;xl=xlold;〃還原最左,最右xr=xrold;while(xr>xl&&go==0)〃找下一條掃描線的最右像素if(getpixel(xr,yO)!=4)go=l;elsexr——;}while(xl〈xr&&go2==0)//找下一條掃描線的最左像素(if(getpixel(xl,yO)!=4)go2=l;elsexl++;}if(go==l&&go2==l)//如果找到最左和最右,則執(zhí)行(push(xr,yO);for(i=xl;i<=xr;i++){if(getpixel(i,yO)[-4){}elseif(getpixel(i-1,yO)!=4)push(i-l,yO);voidmain()(voidfill(intx,inty);intgdriver,gmode;/*顯示模式*/detectgraph(&gdriver,&gmode);initgraph(&gdriver,&gmode,〃〃);inti,j;intn,u,px,py,pxO,pyO,pxl,pyl;intya=0,yi=getmaxy();printf(z,pleasinputthenumberofthepolygons:z,);scanf(〃%d〃,&u);〃看看究竟有多少個多邊形(可能多邊形里包含了多邊形)for(intk=0;k<u;k++){printf(,zpleasinputthenumberofthetoppoints:;scanf(〃%d〃,&n);〃看看該多邊形究竟有幾個端點for(i=0;i〈n;i++)〃從鍵盤接受各頂點的坐標(biāo),依次入棧,并記錄最大Y值和最小Y值coordinateoftheprintf(,zpleaseinputthecoordinateofthepoints-like:100,200:;scanf("%d,&px,&py);if(ya<py)ya=py;//ya是最大Y值if(yi>py)yi=py;//yi是最小Y值push(px,py);)setbkcolor(0);//cleardevice();setcolor(4);pop(pxO,pyO);〃輸入的最后一個頂點出棧px=px0;py=py0;〃記錄最后一個頂點//drawtheplotwhile(stack!=0)(pop(pxl,pyl);line(px0,pyO,pxl,pyl);px0=pxl;pyO=pyl;delay(500);〃時延,慢慢畫)line(pxO,pyO,px,py);〃依次畫線,畫出多邊形)〃畫完多邊形后,棧為空//findtheyvaluej=(ya+yi)/2;〃找丫的中間值,就是第一個種子點的丫值i=0;n=0;〃記錄入棧個數(shù)//findtheseedelementwhile(i<getmaxx()&&n!=2)〃按X值從0到X最大值依次查找,并在入棧個數(shù)為2的時候退出{if(getpixel(i,j)==4)〃如果是多邊形上的點,則入棧,用n記錄入棧的個數(shù){push(i,j);n=n+l;i=i+l;//i是記錄當(dāng)前的X值pop(i,j);〃第二個交點出棧pop(n,j);〃第一個交點出棧,雖然覆蓋了丫值,但這不重要,我們要的是X值i=(i+n)/2;〃現(xiàn)在i是我們要找的種子點的X值//filltheplotfill(i,j);〃將種子點作為參數(shù)傳入fill()方法delay(1000);outtextxy(100,410,z,theredlinewasdrawing,fillover");getch();closegraph();)特別指出:該程序在理論上是沒有問題的,但是由于使用了line函數(shù),導(dǎo)致某些多邊形的端點數(shù)據(jù),會出現(xiàn)運(yùn)行未果或者錯誤的問題。出現(xiàn)這種錯誤的原因就是line函數(shù)采用了離散的像素點來取代連續(xù)的邊界點。大家可以試試u=l,n=3,F(100,100),G(100,75),H(175,135),如圖(a)所示;此時的問題在于種子的選取,計算出來的種子y坐標(biāo)為105,沒有問題,此時i從。開始向右搜索,遇到兩個邊界點分別記錄并在第二個邊界點停止搜索,那么記錄的應(yīng)該分別是A點(110,105)和B點(137.5,105),然后種子的x坐標(biāo)就應(yīng)該是(110+137.5)/2=123,結(jié)果程序運(yùn)行后居然是(110+111)/2=110,這個結(jié)果說明A點是邊界,A點緊右相鄰的點也是邊界點,看這個圖就知道不可能啊,在理論上是絕不可能。但是看看圖(b)就知道在實際上是可能的而且是經(jīng)常發(fā)生的。如果一旦出現(xiàn)了這種情況,fill()函數(shù)里面的諸多判斷也會出現(xiàn)問題,而且這個問題是隨著多邊形的端點數(shù)據(jù)的變化而

難以捕捉。-rn- - 閔16.匚知四邊形各頂點坐標(biāo)為(0,0),(20,0),(20,15)和(0,15),對此圖形分別4行下列比仞麋換:(1)使長度方向縮小一半,高度方向增長一倍;(2)使整個圖形放大一倍。解:如EiY&同所示(),實線部分為原圖,虛線部分為變換后得到的圖形:15(1)(2)1n原先坐'001'2001201510151原先坐-00f2001on標(biāo) 變換矩陣變換后r r「00110.5 0 01001* 0 2 0 =103010 0 1L J |_0 30 1_標(biāo) 變換矩陣變換r r「0 0 0.5110020 0 0.5;坐標(biāo)后坐標(biāo)0 01',1八 40 0 120151015117.已知三角開20150.5000.5L J[0150.5鄉(xiāng)各頂點坐標(biāo)為(10,10),7—1403010301(10,30),(30,15),試對其進(jìn)行下列變換,寫出變換矩陣,畫出變換后的圖形。(1)沿X向平移20,沿Y向平移15,再繞原點旋轉(zhuǎn)90度(2)繞原點旋轉(zhuǎn),再沿X向平移20,沿Y軸平移15解:⑴由二維圖形變換相關(guān)知識,可得變換矩陣為cos90sir90解:⑴由二維圖形變換相關(guān)知識,可得變換矩陣為cos90sir90-sin90cos9C-sin90cos9C20151 0-1520151 0-1520根據(jù)得出的新坐標(biāo)可畫出圖形(圖形略)根據(jù)得出的新坐標(biāo)可畫出圖形(圖形略)新坐標(biāo)的值為[-25,30][-45,新坐標(biāo)的值為[-25,30][-45,30][-30,50](2)變換矩陣為:10(2)變換矩陣為:10T=1031030152015坐標(biāo)數(shù)據(jù)點變換矩陣T=1031030152015坐標(biāo)數(shù)據(jù)點變換矩陣1010 25T=-10T=-102555 451由得出的新坐標(biāo)畫圖(圖形略)由得出的新坐標(biāo)畫圖(圖形略)18.已知直線方程y=kx+bx/a+y/b=l(a!=0.b!18.已知直線方程y=kx+bx/a+y/b=l(a!=0.b!=0)試求出圖形對該直線進(jìn)行對稱變換得變換矩陣解:⑴kx-y+b=0a=arctg(-A/B)=arctgkcos2aT=sin2asin2a 0-cos2a 0(Cos2a-1)C/Asin2aC/A1將(1)代入(2)式可得變換矩陣,并根據(jù)萬能公式sin2a=2sinacosacos2Q=cosJa=arctg(-A/B)=arctgkcos2aT=sin2asin2a 0-cos2a 0(Cos2a-1)C/Asin2aC/A1將(1)代入(2)式可得變換矩陣,并根據(jù)萬能公式sin2a=2sinacosacos2Q=cosJa-sir?atga二sina/cosa可得(1-K2)/(1+K2) 2K/(1+K2) 0T=2K/(1+K2) (K-l)/(K2+b0-2bK/(1+K2) 2b/(1+K2) 1(2)x/a+y/b=1bx+ay-ab=0所以a=arctg(-A/B)=arctg(-b/a)將⑶代入⑵式得(a2-b2)/(a2+b2)T=-2ab/(a2+b2)2ab7(a"+b")-2ab/(a^b2) 0(b2-a2)/(j2+a2)02a2b/(a2+b2) 119.編一程序?qū)崿F(xiàn)直線的編碼裁剪法解:具體源代碼如下所示:tiincludegraphics,h”ttinclude"conio.h"ttinclude"math.h〃ttinclude"stdio.h〃intwl=90,w2=270,w3=40,w4=160;〃定義窗口的幾個關(guān)鍵點坐標(biāo)voidclipline(char*a,int&x,int&y,intxl,intyl,intx2,inty2)〃求出與區(qū)域中各個方向邊的交點{intxtl=0,ytl=0,xt2=0,yt2=0,xt3=0,yt3=0,xt4=0,yt4=0;if(*a=='r){ytl=yl+(y2-yl)*(wl-xl)/(x2-xl);xtl=wl;) 〃求左交點if(*(a+l)==,r){yt2=yl+(y2-yl)*(w2-xl)/(x2-xl);xt2=w2;} 〃求右交點if(*(a+2)==,T){xt3=xl+(x2-xl)*(w3-yl)/(y2-yl);yt3=w3;〃求下交點if(*(a+3)==,r)xt4=xl+(x2-xl)*(w4-yl)/(y2-yl);yt4=w4;) 〃求上交點〃有可能會求出兩個交點,例如左交點和上交點,必然有一個是超出窗口范圍的〃必須將其排除if(xtl<=270&& xtl>=90 && ytl<=160 && ytl>=40) { x=xtl; y=ytl;}if(xt2<=270&& xt2>=90 && yt2<=160 && yt2>=40) { x=xt2; y=yt2;}if(xt3<=270&& xt3>=90 && yt3<=160 && yt3>=40) { x=xt3; y=yt3;}if(xt4<=270&& xt4>=90 && yt4<=160 && yt4>=40) { x=xt4; y=yt4;})voidcode(intxi,intyi,char*a)〃四位編碼的實現(xiàn)(if(xi<wl)*a='1'; 〃左if(xi>w2)*(a+l)=T';〃右if(yi<w3)*(a+2)=,T;〃下if(yi>w4)*(a+3)='T;〃上return;voidclipdraw(intxl,intyl,char*a,intx2,inty2,char*b)intxl1,yl1,x21,y21;intsl=0,s2=0;code(xl,yl,a);〃得到直線第一個端點的編碼code(x2,y2,b);〃得到直線第二個端點的編碼if(*a==,0'&&*b=='O'&&*(a+l)=='O'&&*(b+l)=='O'&&*(a+2)=='O'&&*(b+2)=='0'&&*(a+3)=='O'&&*(b+3)=='O')line(xl,yl,x2,y2); 〃若兩個端點的編碼全為0,則直線完全可見elseif((a[0]-48)*(b[0]-48)+(a[l]-48)*(b[l]-48)+(a[2]-48)*(b[2]-48)+(a[3]-48)*(b[3]-48)==0){ 〃兩端點四位編碼的邏輯乘為0if(!(a[0]==,O'&&a[l]=='O'&&a[2]=='O'&&a[3]==,O'))〃第一個端點不在窗口內(nèi),求與窗口交點{clipline(a,xll,yl1,xl,yl,x2,y2);sl=l;}if(!(b[0]=='O'&&b[l]=='O'&&b[2]=='O'&&b[3]=='O'))〃第二個端點不在窗口內(nèi),求與窗口交點clipline(b,x21,y21,xl,yl,x2,y2);s2=l;}if(sl==l&&s2==l)line(xll,yll,x21,y21);〃說明兩個端點均不在窗口內(nèi),直線與窗口有兩個交點if(sl==l&&s2==0)line(xll,yll,x2,y2);〃說明第一個端點不在窗口內(nèi),第二個在,直線與窗口有一個交點if(sl==0&&s2==l)line(xl,yl,x21,y21);〃說明第二個端點不在窗口內(nèi),第一個在,直線與窗口有一個交點))voidmain()(intxl,yl,x2,y2;scanf("%d%d%d%d”,&xl,&yl,&x2,&y2);〃讀入直線兩個端點的坐標(biāo)chara[4]={'O','O','O','O'};charb[4]={'O','O','O','O'};〃分別初始化兩個端點的編碼數(shù)組intdriver=VGA,mode=VGAHI;initgraph(&driver,&mode,;〃圖形初始化setcolor(4);rectangle(wl,w3,w2,w4);//畫出窗口setcolor(3);line(xl,yl,x2,y2);〃畫出裁剪之前的直線getch();cleardevice();〃清除屏幕getch();setcolor(4);rectangle(wl,w3,w2,w4);〃再次畫出窗口setcolor(7);clipdraw(xl,yl,a,x2,y2,b);〃畫出保留在窗口內(nèi)的直線getchO;closegraph();〃關(guān)閉圖形系統(tǒng))20.編一程序?qū)崿F(xiàn)直線中點今割裁剪法解:如圖所示:D1DO(6#include"graphics.h〃 ttinclude"stdio.h〃ttinclude"conio.h〃#include"stdlib.h"ttdefinee1〃(單位像素)

voidmidclip(intxmin,intymin,intxmax,intymax,intxl,intx2,intyl,inty2)〃參數(shù)為視窗和直線端點坐標(biāo)(intxmid,ymid,x3,y3,x4,y4;〃定義了中點坐標(biāo),x3,y3用于保存中間結(jié)果x4=xl;y4=yl; 〃保留xl和yl的光標(biāo)位置do{if((xl<xmin&&x2<xmin)||(xl>xmax&&x2>xmax)||(yl<xmin&&y2<ymin)|(yl>ymax&&y2>ymax))return; 〃說明直線段完全被排斥于窗口之外else(xmid=(xl+x2)/2;ymid=(yl+y2)/2; 〃求中點坐標(biāo)Pmif((xmid<xmin&&x2<xmin)||(xmid>xmax&&x2>xmax)||(ymid<ymin&&y2<ymin)||(ymid>ymax&&y2>ymax))〃如果P2Pm被完全排斥在窗口外{x2=xmid;y2=ymid;} 〃將P2用Pm替代else{xl=xmid;yl=ymid;}〃否則將{xl=xmid;yl=ymid;}〃否則將Pl用Pm替代while(!((xmin-e<=x2)&&(x2<=xmax+e)&&(ymin-e<=y2)&&(y2<=ymax+e))); 〃檢查端點P2是否可見,允許一個單位像素的誤差x3=x2;y3=y2;〃此時(x3,y3)為Pl的最遠(yuǎn)可見點moveto(x4,y4); 〃獲取光標(biāo)位置line(x4,y4,x3,y3);〃裁剪后連線moveto(x3,y3); 〃獲取光標(biāo)位置)〃再將直線兩端點互換,重復(fù)調(diào)用該過程尋找P2的最遠(yuǎn)可見點。voidmain(){intdriver,mode;driver=EGA;mode=EGAHI;initgraph(&driver,&mode,"");rectangle(100,100,650,500);〃定義視圖區(qū)大小intxl=50,x2=550,yl=170,y2=780,x,y;〃給出線段兩端點的初始值line(xl,yl,x2,y2);〃畫出初始線段getch();cleardevice();〃清屏getch();rectangle(100,100,650,500);〃再次顯示視圖區(qū)getch();midclipdOO,100,650,500,xl,x2,yl,y2);〃以(xl,yl)為起點尋找最遠(yuǎn)可見點并裁剪④ //x=x2;y=y2;//y2=500;x2=xl+(y2-yl)*(x-xl)/(y-yl); 〃求出裁剪后的線段與窗口的交點getch();②x2=getx();y2=gety();〃或者直接取midclipO函數(shù)中x3和x4的光標(biāo),即交點坐標(biāo)setcolor(5);setlinestyle(2,0,1);midclip(100,100,650,500,x2,xl,y2,yl); 〃以裁剪后的線段與窗口的交點為新的起點尋找最遠(yuǎn)可見點并裁剪getch();closegraph();)[注]①和②的代碼段功能是相同的,只能二選一。21.什么是反走樣技術(shù),比較超采樣和區(qū)域采樣的異同點?答:各種光柵化算法,如非水平亦非垂直的直線或多邊形邊界進(jìn)行掃描轉(zhuǎn)換時,或多或少會產(chǎn)生鋸齒或階梯狀。我們把這種用離散量表示連續(xù)量引起的失真稱為走樣(Aliasing)。走樣是數(shù)字化發(fā)展的必然產(chǎn)物。所謂的反走樣(Antialiasing)技術(shù),就是減緩或者消除走樣效果的技術(shù)。目前有兩類反走樣的方法,第一類方法是通過提高采樣頻率(提高光柵分辨率)來顯示圖形的細(xì)節(jié)?;诖耍梢詫@示器看成比實際更加細(xì)膩的網(wǎng)格,在這種假想的高分辨率上對光柵進(jìn)行計算,采用某種平均算法得到較低分辨率的像素的屬性,并把結(jié)果轉(zhuǎn)換到較低分辨率的顯示器上進(jìn)行顯示。我們將這種方法稱之為超采樣(Supersampling)或者后置濾波(有些教材也稱為過取樣)。第二類反走樣技術(shù)是根據(jù)圖形在每個像素點上的覆蓋程度來確定像素點的最終亮度,此時將像素點當(dāng)成了一個有面積的平面區(qū)域而并非一個點,這種方法稱之為區(qū)域采樣(AreaSampling)或者前置濾波。第五章習(xí)題參考答案.試編寫一個繪制Bezier曲面的程序。解答:voidCMyView::OnAppBezier(){//TODO:AddyourcommandhandlercodehereInvalidate(true);UpdateWindow();CClientDCde(this

溫馨提示

  • 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

提交評論