第一篇:計算機(jī)圖形學(xué)的簡單認(rèn)識
計算機(jī)圖形學(xué)的簡單認(rèn)識
090600304229計科0942卿文玲
第一周,我們上了一節(jié)計算機(jī)圖形學(xué)。記得剛開始領(lǐng)到書的時候,翻看里面的內(nèi)容,發(fā)現(xiàn)好多數(shù)學(xué)公式,心想:“完了,這不就是變相數(shù)學(xué)嘛,還結(jié)合計算機(jī)圖形,天哪,肯定很難很難。”
事實證明,第一節(jié)課結(jié)束后,我還是不清楚計算機(jī)圖形學(xué)要學(xué)的是什么,只是大概的了解了計算機(jī)圖形學(xué)是講圖形用公式等直觀的表達(dá)幾何圖形出來。所以說認(rèn)識的話,根本談不上。在瀏覽了課本前面的前言后,大概了解了計算機(jī)圖形學(xué)涉及計算機(jī)硬件、數(shù)學(xué)、物理、計算機(jī)科學(xué)、美學(xué)等領(lǐng)域的綜合知識,需要有較好的數(shù)學(xué)基礎(chǔ)和相關(guān)的計算機(jī)知識才能將本門課程學(xué)好。同時了解到圖形本質(zhì)上是具有線性、寬度、顏色等屬性信息胡圖形元素的組合。因此,抽象圖形本質(zhì)可以概括為:圖形=圖元+屬性。幾何是表示是輸入;繪制是展現(xiàn),是輸出。
了解了這些淺顯的東西,或許在今后的學(xué)習(xí)上有一點點幫助。不過,我相信,前面的路還很長,需要努力的還很多才能學(xué)好這門課程。
第二篇:計算機(jī)圖形學(xué)學(xué)習(xí)心得
《計算機(jī)圖形學(xué)》學(xué)習(xí)報告
? 東西方建筑中的理性
盡管東方“木構(gòu)”的暫時性文化和西方“石砌”的永久性文化氛圍造成了建筑形式風(fēng)格的差異,但是它們都兼有理性和感性美。從柱式的英文“order”一詞,到中國古建筑等級制的基數(shù)開間,無不透露著匠人的理性思考;從古埃及繪畫中為了將人的特征最大限度表現(xiàn)而作的頭部側(cè)面身體正面的繪畫,到文藝復(fù)興達(dá)芬奇創(chuàng)造的透視畫法,一步步將人們引向更為理性的世界。
西方古典主義者強(qiáng)調(diào)構(gòu)圖中的主從關(guān)系,突出軸線、講求配稱;倡導(dǎo)理性,主張建筑的真實,反對表現(xiàn)感情和情緒。隨之而來的比例、節(jié)奏、韻律、秩序美,是建筑區(qū)別于雕塑和繪畫兩大藝術(shù)的特點。
維特魯威提出的建筑三原則:堅固、適用、美觀,時時刻刻提醒著我們建筑是要被建造起來的,它是我們的“避難所”,需要理性的結(jié)構(gòu)、縝密的分析和思考。時代在進(jìn)步,建筑理論從勒杜克的結(jié)構(gòu)理性主義發(fā)展到現(xiàn)在的解構(gòu)主義,再也不是建筑形式適應(yīng)結(jié)構(gòu)的時代了,而是兩者互為促進(jìn)。
我們對建筑的理解不再是像路易斯康那樣再去問磚想做什么,等待它做拱卷的回答。我們向大自然學(xué)習(xí),卡拉特拉瓦創(chuàng)造了許多帶有理性美的仿生建筑。當(dāng)我們想進(jìn)一步拓寬我們的思維時,我們還能向誰求助?計算機(jī)圖形學(xué)為我們打開了理性思考的一扇窗。
? 計算機(jī)圖形學(xué)對理性建筑的貢獻(xiàn)
半個多世紀(jì)以來,計算機(jī)技術(shù)得到了飛速的發(fā)展。它的進(jìn)步不僅僅使世界變得更平,信息交流更便捷,在此平臺上開發(fā)的各種繪圖軟件更是將建筑師從傳統(tǒng)的手工渲染畫圖中解放出來,也解放了結(jié)構(gòu)師的工作量。用了30年的時間,計算機(jī)的速度從K(103)到T(1012),而從T到Z(1021),我們只用了10年時間。發(fā)展的速度是越來越快,我們設(shè)計方法和速度都得到了革新。這是這樣一個數(shù)字化信息化的時代,才有弗蘭克蓋里建筑的夸張和扎哈哈迪德設(shè)計的新奇。
原來我們隨手繪出的自由曲線,現(xiàn)在計算機(jī)都能幫我們算出是否有建造的可能,以及建筑性能也能在建造前得到分析。在創(chuàng)意上,計算機(jī)也能將我們模糊的概念無限發(fā)展,給它一個規(guī)則,它可能還你一個超乎想象的造型,在理性規(guī)則中生成感性而自由的建筑。
知其然,還應(yīng)知其所以然,看著電視機(jī)的變薄,圖像更加逼真,這變化的一切都建立在計算機(jī)圖形學(xué)的架構(gòu)下,了解了基礎(chǔ)原理,才能更高效地做高質(zhì)量的建筑設(shè)計。
? 計算機(jī)圖形學(xué)的理論知識
1.相關(guān)概念
計算機(jī)圖形學(xué)是主要研究通過計算機(jī)處理用集合數(shù)據(jù)和數(shù)學(xué)模型所描述的圖形的原理、算法和系統(tǒng)。包括圖形的輸入、存儲、運(yùn)算、轉(zhuǎn)換、傳送和輸出。數(shù)字化技術(shù)是泛指在某特定領(lǐng)域利用包括硬件、軟件在內(nèi)的計算機(jī)與電子技術(shù)以及數(shù)學(xué)或數(shù)字模型等描述的問題進(jìn)行求解、模擬或分析活動的一切應(yīng)用技術(shù)。
建筑數(shù)字化技術(shù)研究應(yīng)用包括建筑的數(shù)字化設(shè)計和反映建筑的數(shù)字化特征在內(nèi)的數(shù)字技術(shù)。而建筑數(shù)字化技術(shù)的核心幾何學(xué)科就是計算機(jī)圖形學(xué)。2.反映建筑數(shù)字化特征的典型圖形技術(shù)
建筑的動態(tài)特征——圖形顯示:如奧地利格拉茨美術(shù)館的925盞燈形成的外墻面顯示屏 建筑的互動特征——圖形顯示:如杜瑟赫姆市的隨情感變化而色彩變化的建筑物
建筑的數(shù)字特征——幾何運(yùn)算:如柏林Max Reinhardt大樓模型及“莫比烏斯環(huán)”變換 建筑的虛實特征——交互式圖形:如法國國立圖書館(實體與網(wǎng)絡(luò)圖書館)
設(shè)計手段和設(shè)計媒體的數(shù)字化特征——交互式圖形:如紐約韓國基督教長老會教堂 而建筑性能如聲環(huán)境、熱環(huán)境、光環(huán)境、風(fēng)環(huán)境模擬的可視化分析中都用到了圖形學(xué)。3.虛擬現(xiàn)實技術(shù)(VR)
虛擬現(xiàn)實技術(shù)是計算機(jī)生成的給人多種感官刺激的虛擬世界(環(huán)境),是一種高級的人機(jī)交互系統(tǒng)。
虛擬現(xiàn)實技術(shù)的三個基本特征:沉浸感、交互性、想象力 它具有多學(xué)科的綜合性,正如建筑學(xué)是一門綜合的藝術(shù),虛擬現(xiàn)實技術(shù)包括圖像處理、圖形學(xué)、計算幾何、多傳感器、網(wǎng)絡(luò)、多媒體和仿真技術(shù)等。
正如課堂上老師放映的《碟中諜4》,逼真的爆炸場景,以及從皮克斯動畫開始的動物毛發(fā)到最近火熱的《少年派》逼真的老虎與人共存畫面,虛擬現(xiàn)實技術(shù)的進(jìn)步影響到了我們生活的方方面面,觸到了我們原來想都不敢想的世界。
而VR技術(shù)在建筑行業(yè)中,有以下作用:(1)指導(dǎo)設(shè)計:讓建筑師通過瀏覽觀察和了解空間關(guān)系,特別是對空間大小、方向、形狀和建筑元素行為的理解。(2)建筑表現(xiàn)與環(huán)境仿真(3)仿真施工:檢查和修改施工細(xì)節(jié)、合理性和有效性
4.虛擬現(xiàn)實的基礎(chǔ)與關(guān)鍵技術(shù):建模與描繪
基于幾何和圖形學(xué)的建模和描繪技術(shù)
直接幾何建模
3D掃描建模
投影視圖建模
基于圖像的場景描繪技術(shù)(IBR)
圖像投影變形技術(shù) 光場重建技術(shù)
混合式IBR技術(shù)
IBR技術(shù)圖形的繪制獨(dú)立于場景的復(fù)雜性,僅僅與所要生成畫面的分辨率有關(guān)。
第三篇:計算機(jī)圖形學(xué)實驗
實驗三 MFC畫直線
最近自己在學(xué)習(xí)如何在VC 6.0 開發(fā)環(huán)境下的使用MFC AppWizard(exe)來繪畫一條直線,雖然比較簡單,通過這樣的練習(xí)可以幫助你熟悉MFC的開發(fā)環(huán)境以及其中的消息傳遞機(jī)制,希望對于像我一樣初入MFC圖形繪制學(xué)習(xí)的人有幫
助
第一步:構(gòu)建MFC窗體
打開Visual C++ 6.0編譯器 新建→工程→MFC AppWizard(exe),工程名以DrawLine為例,然后確定。為了方便,在MFC應(yīng)用程序向?qū)А襟E1當(dāng)中選擇“單文檔”,其余所有的步驟都為默認(rèn)值,直接“完成”。這樣一個簡單的MFC窗體就構(gòu)建好了,自己不妨Compile—Build—BuildExecute一下。
第二步:編輯菜單項
選擇ResourceView視窗展開Menu文件夾,左鍵雙擊IDR_DRAWLITYPE,右邊就會出現(xiàn)菜單圖形編輯界面,為了簡化,我們只在添加幫助→DrawLine功能選擇項。雙擊空白會彈出“菜單項目 屬性”對話框。ID:ID_DRAW_LINE;標(biāo)明:
DrawLine(&D),其它的為缺省。
第三步:建立消息命令
如果此時運(yùn)行該程序,你會發(fā)現(xiàn)幫助—DrawLine的功能選項是灰色的,原因就在于我們還沒有添加該功能的消息命令相應(yīng)函數(shù)。通過“查看—Message Maps—Project:DrawLine—Class name:CDrawLineView—Object IDs:ID_DRAW_LINE—選定COMMAND—Add Function?”,其它為默認(rèn),最后確定完成。現(xiàn)在如果再重新運(yùn)行該程序的話,會發(fā)現(xiàn)原來的灰色已經(jīng)消除了。
第四步:添加鼠標(biāo)消息響應(yīng)
打開ClassView視窗,右鍵選定CDrawLineView,選擇Add Windows Messsage Handler會彈出對話框,完成CDrawLineView類的WM_LBUTTONDOWN、WM_MOUSEMOVE、WM_LBUTTONUP三個Windows消息事件的新建。
第五步:添加響應(yīng)代碼
首先,在ClassView視窗中雙擊CDrawLineView會定位到“DrawLineView.h : interface of the CDrawLineView class”的文件,添加CDrawLineView類的成員:protected: int m_Drag;POINT m_pPrev;POINT m_pOrigin;三個成員變量。視窗中展開CDrawLineView類,雙擊定位OnLBUTTONDOWN()函數(shù)。在該函數(shù)消息響應(yīng)
處添加如下代碼:
//建立好繪圖的設(shè)備環(huán)境
CClientDC dc(this);OnPrepareDC(&dc);
dc.DPtoLP(&point);
//獲取起始點坐標(biāo) m_pPrev=point;m_pOrigin=point;
m_Drag=1;
然后,定位于OnMouseMove(),添加如下代碼(其中關(guān)鍵用到了橡皮筋技術(shù)):
//建立好繪圖的設(shè)備環(huán)境
CClientDC dc(this);
OnPrepareDC(&dc);dc.DPtoLP(&point);
dc.SetROP2(R2_NOT);//橡皮筋繪圖技術(shù)
//判斷是否BUTTONDOWN
if(m_Drag)
{
dc.MoveTo(m_pOrigin);dc.LineTo(m_pPrev);dc.MoveTo(m_pOrigin);dc.LineTo(point);
}
m_pPrev=point;
最后,在OnLBUTTONDOWN()添加代碼: m_Drag=0;
程序運(yùn)行效果圖
實驗4 實現(xiàn)圓的生成算法
一、實驗?zāi)康?/p>
1.熟悉CDC圖形程序庫; 2.掌握中點畫圓生成算法; 3.掌握Bresenham畫圓算法。
二、實驗內(nèi)容
利用VisualC++6.0設(shè)計一個簡易畫圓繪圖板,驗證圓生成算法。
三、實驗指導(dǎo)
1.生成繪圖應(yīng)用程序的框架,如下圖所示。具體實現(xiàn)見第二次實驗,過程不再詳細(xì)說明。
2.在應(yīng)用程序中增加菜單
完成相關(guān)菜單的設(shè)計,具體的效果如下圖所示,并設(shè)置好相關(guān)菜單消息的映射,具體的實現(xiàn)在前面的實驗中介紹過,再此不在詳細(xì)說明。
3.在繪圖函數(shù)中添加代碼
通過以上步驟,得到了與菜單對應(yīng)的消息映射,就可以在函數(shù)中添加代碼繪制圖形了。(1)利用中點畫圓算法實現(xiàn)圓的生成(算法原理見教材)。void CDraw_CirView::OnMid(){ // TODO: Add your command handler code here CDC*pDC=GetDC();//得到繪圖類指針
RedrawWindow();//重繪窗口
int x,y,x0=200,y0=200,r=100;//圓的圓心為(x0,y0),半徑為r float d;x=0;y=r;d=1.25-r;
pDC->SetPixel(x+x0,y+y0,RGB(255,0,0));pDC->SetPixel(y+x0,x+y0,RGB(255,0,0));pDC->SetPixel(y+x0,-x+y0,RGB(255,0,0));pDC->SetPixel(x+x0,-y+y0,RGB(255,0,0));pDC->SetPixel(-x+x0,-y+y0,RGB(255,0,0));pDC->SetPixel(-y+x0,-x+y0,RGB(255,0,0));pDC->SetPixel(-y+x0,x+y0,RGB(255,0,0));pDC->SetPixel(-x+x0,y+y0,RGB(255,0,0));while(x<=y){
if(d<0)
{
d=d+2*x+3;
x++;
}
else
{
d=d+2*(x-y)+5;
x++;
y--;}
pDC->SetPixel(x+x0,y+y0,RGB(255,0,0));
pDC->SetPixel(y+x0,x+y0,RGB(255,0,0));
pDC->SetPixel(y+x0,-x+y0,RGB(255,0,0));
pDC->SetPixel(x+x0,-y+y0,RGB(255,0,0));
pDC->SetPixel(-x+x0,-y+y0,RGB(255,0,0));
pDC->SetPixel(-y+x0,-x+y0,RGB(255,0,0));
pDC->SetPixel(-y+x0,x+y0,RGB(255,0,0));
pDC->SetPixel(-x+x0,y+y0,RGB(255,0,0));} } 由以上代碼繪出的圖形如下:
(2)利用Bresenham算法生成圓(算法原理見教材)。void CDraw_CirView::OnBre(){ // TODO: Add your command handler code here CDC*pDC=GetDC();//得到繪圖類指針
//RedrawWindow();//重繪窗口
int x,y,x0=200,y0=200,r=50;//圓的圓心為(x0,y0),半徑為r int delta,delta1,delta2,direction;x=0;y=r;delta=2*(1-r);while(y>=0){
pDC->SetPixel(x+x0,y+y0,RGB(0,0,255));
pDC->SetPixel(x+x0,-y+y0,RGB(0,0,255));
pDC->SetPixel(-x+x0,y+y0,RGB(0,0,255));
pDC->SetPixel(-x+x0,-y+y0,RGB(0,0,255));
if(delta<0)
{
delta1=2*(delta+y)-1;
if(delta<=0)direction=1;
else direction=2;
}
else if(delta>0)
{
delta2=2*(delta-x)-1;
if(delta2<=0)direction=2;
else direction=3;
}
else direction=2;
switch(direction)
{
case 1:x++;
delta+=2*x+1;
break;
case 2:x++;y--;
delta+=2*(x-y+1);
break;
case 3:y--;
delta+=(-2*y+1);
break;
} } }
由以上代碼繪出的圖形如下:
(3)以上是本次實驗的基本部分,利用中點畫圓和Bresenham畫圓算法實現(xiàn)的基本圖形的繪制。能不能利用該算法,完成一些復(fù)雜圖形的生成,比如利用基本的畫圓算法繪制一個奧運(yùn)五環(huán)。甚至根據(jù)畫圓算法,實現(xiàn)二次曲線的生成,如橢圓的生成等等。請同學(xué)們認(rèn)真考慮,完成這部分的內(nèi)容,上機(jī)調(diào)試。
四、思考
1.如何實現(xiàn)圓心為任意位置的圓的繪制; 2.兩種畫圓算法的比較。
第四篇:計算機(jī)圖形學(xué)學(xué)習(xí)體會
計算題圖形學(xué)課程學(xué)習(xí)體會
計算機(jī)圖形學(xué)是研究用計算機(jī)生成、處理和顯示圖形的一門學(xué)科。他的重要性體現(xiàn)在人們越來越強(qiáng)烈的需要和諧的人機(jī)交互環(huán)境,UI已經(jīng)成為軟件的重要組成部分,以圖形的方式表示抽象的概念和數(shù)據(jù)已經(jīng)成為信息領(lǐng)域的發(fā)張趨勢。這門課我們通過自學(xué)和同學(xué)間互相上課,了解和掌握了計算機(jī)圖形學(xué)的概念、方法和基本的算法。
學(xué)習(xí)的過程中,感觸比較深的是,常常被那些算法所困擾,算法很難理解,解釋的枯燥而且難學(xué)。原因首先是計算機(jī)圖形學(xué)這門學(xué)科本身特點就是綜合性很強(qiáng),涉及的內(nèi)容和應(yīng)用廣泛,學(xué)科交叉復(fù)雜。綜合了計算機(jī)科學(xué)、數(shù)學(xué)、物理學(xué)等其他相關(guān)學(xué)科的知識。而且學(xué)科發(fā)展日新月異,新的應(yīng)用領(lǐng)域不斷拓展,相關(guān)學(xué)科相互滲透。其次是與計算機(jī)圖形學(xué)課程中的算法特點有關(guān)。很多的算法是為了追求高效率,精益求精,構(gòu)思獨(dú)特、實現(xiàn)精巧,算法本身就很難看懂和理解。第三方面就是這門課程是一門理論性和實踐性兼顧的綜合性課程,實踐性很強(qiáng),不實踐就顯得空洞,枯燥乏味。
這門課學(xué)習(xí)的目的是讓我們掌握計算機(jī)圖形學(xué)的相關(guān)概念、原理和知識,算法的難學(xué)難理解,是我們學(xué)習(xí)的主要障礙。課程實踐中,教員讓我們自學(xué),互相授課,增強(qiáng)時間體會。在自學(xué)和自作可見互相授課過程中,要求要注重基礎(chǔ),強(qiáng)調(diào)基本
這些動畫,對增強(qiáng)原理、算法的理解性具有很大的作用。
以上是本人在計算機(jī)圖形課學(xué)習(xí)過程中的體會,字?jǐn)?shù)不多,確是心得,不足之處還請曹老師指正。
第五篇:計算機(jī)圖形學(xué)實驗報告
實 驗 報 告
一、實驗?zāi)康?/p>
1、掌握有序邊表算法填充多邊形區(qū)域;
2、理解多邊形填充算法的意義;
3、增強(qiáng)C語言編程能力。
二、算法原理介紹
根據(jù)多邊形內(nèi)部點的連續(xù)性知:一條掃描線與多邊形的交點中,入點和出點之間所有點都是多邊形的內(nèi)部點。所以,對所有的掃描線填充入點到出點之間所有的點就可填充多邊形。
判斷掃描線上的點是否在多邊形之內(nèi),對于一條掃描線,多邊形的掃描轉(zhuǎn)換過程可以分為四個步驟:
(1)求交:計算掃描線與多邊形各邊的交點;(2)排序:把所有交點按x值遞增順序排序;
(3)配對:第一個與第二個,第三個與第四個等等;每對交點代表掃描線與多邊 形的一個相交區(qū)間;(4)著色:把相交區(qū)間內(nèi)的象素置成多邊形顏色,把相交區(qū)間外的象素置成背景色。
p1,p3,p4,p5屬于局部極值點,要把他們兩次存入交點表中。如掃描線y=7上的交點中,有交點(2,7,13),按常規(guī)方法填充不正確,而要把頂點(7,7)兩次存入交點表中(2,7,7,13)。p2,p6為非極值點,則不用如上處理。
為了提高效率,在處理一條掃描線時,僅對與它相交的多邊形的邊進(jìn)行求交運(yùn)算。把與當(dāng)前掃描線相交的邊稱為活性邊,并把它們按與掃描線交點x坐標(biāo)遞增的順序存放在一個鏈表中,稱此鏈表為活性邊表(AET)。
對每一條掃描線都建立一個與它相交的多邊形的活性邊表(AET)。每個AET的一個節(jié)點代表一條活性邊,它包含三項內(nèi)容
1.x-當(dāng)前掃描線與這條邊交點的x坐標(biāo);
2.Δx-該邊與當(dāng)前掃描線交點到下一條掃描線交點的x增量; 3.ymax-該邊最高頂點相交的掃描線號。
每條掃描線的活性邊表中的活性邊節(jié)點按照各活性邊與掃描線交點的x值遞增排序連接在一起。
當(dāng)掃描線y移動到下一條掃描線y = y+1時,活性邊表需要更新,即刪去不與新掃
描線相交的多邊形邊,同時增加與新掃描線相交的多邊形邊,并根據(jù)增量法重新計算掃描線與各邊的交點x。
當(dāng)多邊形新邊表ET構(gòu)成后,按下列步驟進(jìn)行:
① 對每一條掃描線i,初始化ET表的表頭指針ET[i]; ② 將ymax = i的邊放入ET[i]中;
③ 使y =多邊形最低的掃描線號; ④ 初始化活性邊表AET為空; ⑤ 循環(huán),直到AET和ET為空。
? 將新邊表ET中對應(yīng)y值的新邊節(jié)點插入到AET表。? 遍歷AET表,將兩兩配對的交點之間填充給定顏色值。
? 遍歷AET表,將 ymax= y的邊節(jié)點從AET表中刪除,并將ymax> y的各邊節(jié)點的x值遞增Δx;并重新排序。? y增加1。
三、程序源代碼
#include “graphics.h” #define WINDOW_HEIGHT 480 #define NULL 0 #include “alloc.h” #include “stdio.h” #include “dos.h” #include “conio.h” typedef struct tEdge /*typedef是將結(jié)構(gòu)定義成數(shù)據(jù)類型*/ { int ymax;/* 邊所交的最高掃描線號 */ float x;/*當(dāng)前掃描線與邊的交點的x值 */ float dx;/*從當(dāng)前掃描線到下一條掃描線之間的x增量*/ struct tEdge *next;}Edge;
typedef struct point{int x,y;}POINT;/*將結(jié)點插入邊表的主體函數(shù)*/
void InsertEdge(Edge *list,Edge *edge)/*活性邊edge插入活性邊表list中*/ { Edge *p,*q=list;p=q->next;/*記住q原來所指之結(jié)點*/ while(p!=NULL)/*按x值非遞減順序增加邊表*/ {
if(edge->x
x)/*要插入的邊的x較大不應(yīng)該在當(dāng)前插入*/
p=NULL;
else /*要插入的邊的x較小應(yīng)該在當(dāng)前插入*/
{q=p;
p=p->next;
} } edge->next=q->next;/*使欲插入之結(jié)點edge指向q原來所指之結(jié)點*/ q->next=edge;/*使q指向插入之結(jié)點*/ }
int yNext(int k,int cnt,POINT *pts)/*對于多邊形中的某個頂點序號k(0,1...6),返回下一頂點的縱坐標(biāo),如果這2個頂點所在邊是 水平的,則順延,即返回第(k+2)個頂點的縱坐標(biāo)),cnt是頂點個數(shù)+1,pts指向多邊形頂點結(jié)構(gòu)體的指針*/
{ int j;if((k+1)>(cnt-1))/*當(dāng)前頂點為最后一個頂點,則下一個頂點為第0個頂點 */
j=0;else
j=k+1;/*當(dāng)前頂點不是最后一個頂點,下一個頂點為數(shù)組下標(biāo)加一*/ while(pts[k].y==pts[j].y)/*掃描線掃過平行頂點,需分情況找到當(dāng)前頂點下下個頂點*/ if((j+1)>(cnt-1))
j=0;
else
j++;return(pts[j].y);/*返回下一個頂點的y值 */ }
/* 計算增量,修改AET*/ /*生成邊表結(jié)點,并插入到邊表中的主體函數(shù)*/ void MakeEdgeRec(POINT lower,POINT upper,int yComp,Edge *edge,Edge *edges[])/*把邊結(jié)點edge,放到lower.y掃描線所在的邊結(jié)點指針數(shù)組edges[]中 */ {edge->dx=(float)(upper.x-lower.x)/(upper.y-lower.y);edge->x=lower.x;if(upper.y
/*創(chuàng)建邊表的主體函數(shù)*/ void BuildEdgeList(int cnt,POINT *pts,Edge *edges[])/*建立新邊表,cnt:多邊形頂點個數(shù)+1,edges[]:指向活性邊結(jié)點的指針數(shù)組*/ { Edge *edge;POINT v1,v2;int i,yPrev=pts[cnt-2].y;/*當(dāng)前頂點的前一個頂點的y值,在當(dāng)前頂點不是奇點時使用該參數(shù)*/ v1.x=pts[cnt-1].x;v1.y=pts[cnt-1].y;for(i=0;i edge=(Edge *)malloc(sizeof(Edge)); edge=(Edge*)malloc(sizeof(Edge));if(v1.y yNext*/ MakeEdgeRec(v1,v2,yNext(i,cnt,pts),edge,edges);/*確定v1,v2邊較高端點的開閉*/ else MakeEdgeRec(v2,v1,yPrev,edge,edges);/*當(dāng)前頂點 是奇點*/ } yPrev=v1.y;v1=v2;} } /*建立活性邊表的主體函數(shù):建立第scan條掃描線的活性邊表*/ void BuildActiveList(int scan,Edge *active,Edge *edges[])/*建立掃描線scan的活性邊表,把活性邊結(jié)點放入掃描線scan的結(jié)點指針數(shù)組 edges[scan]中*/ { Edge *p,*q;p=edges[scan]->next;/*查找當(dāng)前掃描線對應(yīng)的y桶*/ while(p)/*y桶不空*/ {q=p->next;/*找到最后一個邊結(jié)點,插入*/ InsertEdge(active,p);/*把更新后的邊表重新插入邊表中保存*/ p=q; } } /*填充一對交點的主體函數(shù)*/ void FillScan(int scan,Edge *active,int color)/*填充掃描線:填充掃描線上,且在下一結(jié)點到再下一結(jié)點之間的點*/ { Edge *p1,*p2;int i;p1=active->next;while(p1){ p2=p1->next; for(i=p1->x;i x;i++) putpixel((int)i,scan,color);/*畫出圖形內(nèi)部的點*/ p1=p2->next;/*活性表的下一條邊表 */ } } void DeleteAfter(Edge *q)/*刪除鏈表中結(jié)點,刪除邊結(jié)點q的后續(xù)結(jié)點p*/ { Edge *p=q->next;q->next=p->next;/*刪除結(jié)點*/ free(p);} /* 刪除 y=ymax 的邊 */ /*填充完后,更新活動邊表的主體函數(shù)*/ void UpdateActiveList(int scan,Edge *active)/*刪除掃描線scan完成交點計算的活性邊,同時更新交點x域*/ { Edge *q=active,*p=active->next;while(p)if(scan>=p->ymax)/*掃描線超過邊的最大y值,此條邊的節(jié)點應(yīng)該刪掉*/ { p=p->next;deleteAfter(q);} else /*掃描線未超過邊的最大y值,相應(yīng)的x值增加*/ { p->x=p->x+p->dx;q=p;p=p->next;} } /*對活性邊表結(jié)點重新排序的主體函數(shù)*/ void ResortActiveList(Edge *active)/*活性邊表active中的結(jié)點按x域從小到大重新排序*/ { Edge *q,*p=active->next;active->next=NULL;while(p){q=p->next;InsertEdge(active,p);/*把更新后的邊表重新插入邊表中保存 */ p=q;} } /*多邊形填充的主體程序*/ void ScanFill(int cnt,POINT *pts,int color)/*填充函數(shù),輸入:多邊形頂點個數(shù)+1=cnt, 指向多邊形頂點的指針數(shù)組pts*/ { Edge *edges[WINDOW_HEIGHT],*active;int i,scan,scanmax=0,scanmin=WINDOW_HEIGHT;for(i=0;i {if(scanmax if(scanmin>pts[i].y)scanmin=pts[i].y; } for(scan=scanmin;scan<=scanmax;scan++)/*初始化每條掃面線的邊鏈表*/ {edges[scan]=(Edge *)malloc(sizeof(Edge));/*建 edges[scan]->next=NULL; } BuildEdgeList(cnt,pts,edges);/*建立有序邊表*/ active=(Edge *)malloc(sizeof(Edge));“桶”*/ active->next=NULL;for(scan=scanmin;scan<=scanmax;scan++)/*掃描每條掃描線,求活性表*/ { BuildActiveList(scan,active,edges);/*建立活性邊表*/ if(active->next)/*活性邊表不為空*/ { FillScan(scan,active,color);/*填充當(dāng)前掃描線*/ UpdateActiveList(scan,active);/*更新活化邊表*/ ResortActiveList(active);/*重排活化邊表*/ } } } /*開始菜單*/ void main(){ POINT pts[7];/*保存數(shù)組*/ int gdrive=DETECT,gmode;pts[0].x=100;pts[0].y=40;/*多邊形頂點x、y坐標(biāo)*/ pts[1].x=220;pts[1].y=140;pts[2].x=280;pts[2].y=80;pts[3].x=350;pts[3].y=300;pts[4].x=200;pts[4].y=380;pts[5].x=50;pts[5].y=280;pts[6].x=100;pts[6].y=40;/*合并桶中的新邊,按次序插入到 AET 中*/ initgraph(&gdrive,&gmode,“C:TC3.0BGI”);/*設(shè)置graphic模式*/ ScanFill(7,pts,2);getch();} 四、實驗結(jié)果 圖1 用有序邊表算法生成的多邊形 五、總結(jié)與體會 實驗步驟 1)分析多邊形區(qū)域掃描線填充算法的原理,確定算法流程 ① 初始化:構(gòu)造邊表,AET表置空 ② 將第一個不空的ET表中的邊插入AET表 ③ 由AET表取出交點進(jìn)行配對(奇偶)獲得填充區(qū)間,依次對這些填充區(qū)間著色 ④ y=yi+1時,根據(jù)x=xi+1/k修改AET表所有結(jié)點中交點的x坐標(biāo)。同時如果相 應(yīng)的ET表不空,則將其中的結(jié)點插入AET表,形成新的AET表 ⑤ AET表不空,則轉(zhuǎn)(3),否則結(jié)束。2)編程實現(xiàn) ① 首先確定多邊形頂點和ET/AET表中結(jié)點的結(jié)構(gòu) ② 編寫鏈表相關(guān)操作(如鏈表結(jié)點插入、刪除和排序等) ③ 根據(jù)1)中的算法結(jié)合上述已有的鏈表操作函數(shù)實現(xiàn)多邊形區(qū)域掃描線填充的主體功能 ④ 編寫主函數(shù),測試該算法 通過運(yùn)用C語言環(huán)境下的圖像顯示設(shè)置,本次實驗我學(xué)會了多邊形區(qū)域掃描線填充的有序邊表算法,設(shè)計相關(guān)的數(shù)據(jù)結(jié)構(gòu)(如鏈表結(jié)構(gòu)、結(jié)點結(jié)構(gòu)等),并將實現(xiàn)的算法應(yīng)用于任意多邊形的填充,為深一步的學(xué)習(xí)做好了鋪墊。 六、參考文獻(xiàn) [1]張家廣 等編著.計算機(jī)圖形學(xué)(第3版).北京:清華大學(xué)出版社,1998年9月.[2]陳傳波,陸楓主編,《計算機(jī)圖形學(xué)基礎(chǔ)》,電子工業(yè)出版社,2002年3月.