2020年計算機圖形學課程設計實驗報告_第1頁
2020年計算機圖形學課程設計實驗報告_第2頁
2020年計算機圖形學課程設計實驗報告_第3頁
2020年計算機圖形學課程設計實驗報告_第4頁
2020年計算機圖形學課程設計實驗報告_第5頁
已閱讀5頁,還剩32頁未讀 繼續免費閱讀

下載本文檔

版權說明:本文檔由用戶提供并上傳,收益歸屬內容提供方,若內容存在侵權,請進行舉報或認領

文檔簡介

計算機圖形學課程

設計實驗報告

文檔僅供參考,不當之處,請聯系改正。

一小女對//我

eSHANDONGUNIVERSITYOFSCIENCEANDTECHNOLOGY

《計算機圖形學》

實驗報告

班級計算機科學與技術

姓名

學號

年6月2日

文檔僅供參考,不當之處,請聯系改正。

實驗一基本圖形生成算法

一、實驗目的:

1、掌握中點Bresenham繪制直線的原理;

2、設計中點Bresenham算法;

3、掌握八分法中點Bresenham算法繪制圓的原理;

4、設計八分法繪制圓的中點Bresenham算法;

5、掌握繪制1/4橢圓弧的上半部分和下半部分的中點

Bresenham算法原理;

6、掌握下半部分橢圓偏差判別式的初始值計算方法;

7、設計順時針四分法繪制橢圓的中點Bresenham算法。

二、實驗過程:

1、實驗描述

實驗1:使用中點Bresenham算法繪制斜率為0<=k<=l的直

線。

實驗2:使用中點Bresenham算法繪制圓心位于屏幕客戶區中心

的圓。

實驗3:使用中點Bresenham算法繪制圓心位于屏幕客戶區中心

的橢圓。

2、實驗過程

1)用MFC(exe)建立一個單文檔工程;

2)編寫對話框,生成相應對象,設置相應變量;

文檔僅供參考,不當之處,請聯系改正。

3)在類CLineView中聲明相應函數,并在相關的cpp文件中實

現;

4)在OnDraw()函數里調用函數實現繪制直線、圓、橢圓;

5)運行程序,輸入相應值,繪制出圖形。

三、源代碼

實驗1:直線中點Bresenham算法

1.//cline.cpp:implementationfile

//clinedialog

cline::cline(CWnd*pParent/*=NULL*/)

:CDialog(cline::IDD,pParent)

(

〃{{AFX_DATA」NIT(cline)

m_xO=0;

m_y0=0;

m_x1=0;

m_yl=0;

〃}}AFX_DATA」NIT

}

voidcline::DoDataExchange(CDataExchange*pDX)

文檔僅供參考,不當之處,請聯系改正。

CDialog::DoDataExchange(pDX);

//{{AFX_DATA_MAP(cline)

DDX_Text(pDX,IDC_xO,m_xO);

DDX_Text(pDX,IDC_yO,m_yO);

DDX_Text(pDX,IDC_xl,m_xl);

DDX_Text(pDX,IDC_yl,m_yl);

//}}AFX_DATA_MAP

}

BEGIN_MESSAGE_MAP(cline,CDialog)

//{{AFX_MSG_MAP(cline)

//}}AFX_MSG_MAP

END_MESSAGE_MAP()

2、//LineView.h

classCLineView:publicCView

public:

CLineDoc*GetDocument();

文檔僅供參考,不當之處,請聯系改正。

voidMbline(double,double,double,double);〃直線中點

Bresenham函數

}

3、IILine.cpp

〃*******************百]111L旨:Bresenham

51c51c/

voidCLineView::Mbline(doublexO,doubleyO,doublexl,doubleyl)

(

CClientDCdc(this);

COLORREFrgb=RGB(0,0,255);//定義直線顏色為藍色

doublex,y,d,k;

x=xO;y=yO;k=(y1-yO)/(x1-xO);d=O.5-k;

for(x=xO;x<=xl;x++)

(

dc.SetPixeI((int)x,(int)y,rgb);

if(d<0)

(

y++;

d+=l-k;

文檔僅供參考,不當之處,請聯系改正。

else

d-=k;

)

)

4、//LineView.cpp

voidCLineView::OnDraw(CDC*pDC)

(

CLineDoc*pDoc=GetDocument();

ASSERT_VALID(pDoc);

//TODO:adddrawcodefornativedatahere

clinea;

a.DoModal();〃初始化

CLineView::Mbline(a.m_xO,a.m_yO,a.m_x1,a.m_y1);

}

實驗2:圓中點Bresenham算法

l^//cricle.cpp

//Ccricledialog

Ccricle::Ccricle(CWnd*pParent/*=NULL*/)

:CDialog(Ccricle::IDD,pParent)

文檔僅供參考,不當之處,請聯系改正。

//{{AFX_DATA_INIT(Ccricle)

m_r=0;

//}}AFX_DATA_INIT

)

voidCcricle::DoDataExchange(CDataExchange*pDX)

(

CDialog::DoDataExchange(pDX);

//{{AFX_DATA_MAP(Ccricle)

DDX_Text(pDX,r_EDIT,m_r);

//}}AFX_DATA_MAP

)

2、//CcircleView.h

classCCcircleView:publicCView

public:

CCcircleDoc*GetDocument();

voidCirclePoint(double,double);〃八分法畫圓函數

voidMbcircle(double);〃圓中點Bresenham函數

文檔僅供參考,不當之處,請聯系改正。

3、//CcircleView.cpp

voidCCcircleView::OnDraw(CDC*pDC)

CCcircleDoc*pDoc=GetDocument();

ASSERT_VALID(pDoc);

//TODO:adddrawcodefornativedatahere

Ccricler;

r.DoModal();

CCcircleView::Mbcircle(r.m_r);//lffl|圓

4^//CcircleView.cpp

!!*|Cr|C*|C八分法畫圓

r|Cr|CrgCrgCr|C<{*<{Cr|C*{C5gC/

voidCCcircleView::CirclePoint(doublex,doubley)

CClientDCdc(this);

COLORREFrgb=RGB(0,0,255);

dc.SetPixel((int)(300+x),(int)(300+y),rgb);

文檔僅供參考,不當之處,請聯系改正。

dc.SetPixel((int)(3OO-x),(int)(3OO+y),rgb);

dc.SetPixel((int)(3()()+x),(int)(300-y),rgb);

dc.SetPixel((int)(3OO-x),(int)(3()()-y),rgb);

dc.SetPixel((int)(3OO+y),(int)(3OO+x),rgb);

dc.SetPixel((int)(3O()-y),(int)(3OO+x),rgb);

dc.SetPixel((int)(3()0+y),(int)(300-x),rgb);

dc.SetPixel((int)(3OO-y),(int)(3OO-x),rgb);

)

〃**************************圓中點-Bresenham函數

*|c51c|

voidCCcircleView::Mbcircle(doubler)

doublex,y,d;

COLORREFrgb=RGB(0,0,255);

d=1.25-r;

x=();

y=r;

for(x=0;x<y;x++)

(

CirclePoint(x,y);〃調用八分法畫圓子函數

if(d<0)

d+=2*x+3;

文檔僅供參考,不當之處,請聯系改正。

else

(

d+=2*(x-y)+5;

y-;

實驗3:橢圓中點Bresenham算法

1、//ellipsel.cpp

//Cellipsedialog

Cellipse::Cellipse(CWnd*pParent/*=NULL*/)

:CDialog(Cellipse::IDD,pParent)

(

//{{AFX_DATA_INIT(Cellipse)

m_a=0;

m_b=0;

//}}AFX_DATA_INIT

}

voidCellipse::DoDataExchange(CDataExchange*pDX)

CDialog::DoDataExchange(pDX);

文檔僅供參考,不當之處,請聯系改正。

//{{AFX_DATA_MAP(Cellipse)

DDX_Text(pDX,IDC_EDIT1,m_a);

DDX_Text(pDX,IDC_EDIT2,m_b);

//}}AFX_DATA_MAP

)

2、//EllipseView.h

classCEllipseView:publicCView

public:

CEllipseDoc*GetDocument();

voidEUipsePoint(double,double);〃四分法畫橢圓

voidMbellipse(doublea,doubleb);//橢圓中點Bresenham函數

3、//Ellipse.cpp

!!rjCrjCrJCrjCrjCrJCrJC四分法畫橢圓

r|Cr|CrJCr{Cr|Cr|Cr|Cr{Cr|Cr|CrJCr{Cr|C/

voidCEllipseView::EllipsePoint(doublex,doubley)

文檔僅供參考,不當之處,請聯系改正。

CClientDCdc(this);

COLORREFrgb=RGB(0,0,255);

dc.SetPixel((int)(300+x),(int)(300+y),rgb);

dc.SetPixel((int)(300-x),(int)(300+y),rgb);

dc.SetPixel((int)(3()0+x),(int)(300-y),rgb);

dc.SetPixel((int)(3OO-x),(int)(3OO-y),rgb);

)

//************************那育|員|L'IIJJ':Bresenham

51c51c51c51c51c/

voidCEllipseView::Mbellipse(doublea,doubleb)

(

doublex,y,dl,d2;

x=0;

y=b;

dl=b*b+a*a*(-b+0.25);

EllipsePoint(x,y);

while(b*b*(x+1)<a*a*(y-0.5))〃橢圓AC弧段

(

if(dl<0)

dl+=b*b*(2*x+3);

else

文檔僅供參考,不當之處,請聯系改正。

d1+=b*b*(2*x+3)+a*a*(-2*y+2);

y-;

}

x++;

EllipsePoint(x,y);

}

d2=b*b*(x+0.5)*(x+0.5)+a*a*(y-1)*(y-1)-a*a*b*b;〃橢圓CB弧

while(y>0)

(

if(d2<0)

(

d2+=b*b*(2*x+2)+a*a*(-2*y+3);

x++;

}

else

d2+=a*a*(-2*y+3);

y-;

EllipsePoint(x,y);

}

文檔僅供參考,不當之處,請聯系改正。

4、//EllipseView.cpp

voidCEllipseView::OnDraw(CDC*pDC)

(

CEllipseDoc*pDoc=GetDocument();

ASSERT_VALID(pDoc);

//TODO:adddrawcodefornativedatahere

Cellipseel;

el.DoModal。;//初始化

CEllipseView::Mbellipse(el.m_a,el.m_b);//畫橢圓

)

四、實結果驗

實驗1:直線中點Bresenham算法

文檔僅供參考,不當之處,請聯系改正。

實驗2:圓中點Bresenham算法

文檔僅供參考,不當之處,請聯系改正。

實驗3:橢圓中點Bresenham算法

文檔僅供參考,不當之處,請聯系改正。

文檔僅供參考,不當之處,請聯系改正。

實驗二有效邊表填充算法

一、實驗目的:

1、設計有效邊表結點和邊表結點數據結構;

2、設計有效邊表填充算法;

3、編程實現有效邊表填充算法。

二、實驗過程:

1、實驗描述

下圖1所示多邊形覆蓋了12條掃描線,共有7個頂點和7條

邊。7個頂點分別為:P0(7,8),P1(3,12),P2(1,

7),P3(3,1),P4(6,5),P5(8,1),P6(12,9)。在

1024X768的顯示分辯率下,將多邊形頂點放大為P0

(500,400),P1(350,600),P2(250,350),P3(350,

50),P4(500,250),P5(600,50),P6(800,450)。請使用

有效邊表算法填充該多邊形。

文檔僅供參考,不當之處,請聯系改正。

Pi

圖1示例多邊形留2屏幕顯示多邊形

2、實驗過程

(1)建立AET類和Bucket類;

(2)初始化桶,并在建立桶結點時為其表示的掃描線初始化為

帶頭結點的鏈表;

(3)對每個桶結點進行循環,將桶內每個結點的邊表合并為有

效邊表,并進行有效邊表循環;

(4)按照掃描線從小到大的移動順序,計算當前掃描線與多邊

形各邊的交點,然后把這些交點按X值遞增的順序進行排序,配

對,以確定填充區間;

(5)用指定顏色點亮填充區間內的所有像素,即完成填充工

作。

三、源代碼

1、//AET.h

classAET

文檔僅供參考,不當之處,請聯系改正。

public:

AET();

virtual-AET();

doublex;

intyMax;

doublek;〃代替1/k

AET*next;

};

//AET..cpp

AET::AET()

(

}

AET::~AET()

2、//Bucket.h

include"AET.h"

classBucket

文檔僅供參考,不當之處,請聯系改正。

public:

Bucket();

virtual-Bucket();

intScanLine;

AET*p;//桶上的邊表指針

Bucket*next;

};

//Bucket.cpp

Bucket::Bucket()

Bucket::~Bucket()

(

3、//testl.cpp

voidCTest2View::Et()〃構造邊表函數

(

for(inti=O;i<Number;i++)〃訪問每個頂點

(

CurrentB=HeadB;//從桶鏈表的頭節點開始循環

intj=i+l;//邊表第二個頂點,Point[i]和Pointfj]構成邊

文檔僅供參考,不當之處,請聯系改正。

if(j==Number)

j=0;〃保證多邊形的閉合

if(Point[j].y>Point[i].y)〃終點比起點高

(

while(CurrentB->Scanline!=Point[i].y)//在桶內尋

找該邊的yMin

CurrentB=CurrentB->next;〃移到下一個桶結

E[i].x=Point[i].x;〃計算AET表的值

E[i].yMax=Point[j].y;

E[i].k=double((Point[j].x-Point[i].x))/(Point[j].y-

Poin用].y);〃代表1/k

E[i].next=NULL;

CurrentE=CurrentB->p;//獲得桶上連接邊表的地址

if(CurrentB->p==NULL)

(

CurrentE=&E[i];〃邊表的起始地址

CurrentB->p=CurrentE;〃第一個邊表直接連

接到對應的桶中

)

else

文檔僅供參考,不當之處,請聯系改正。

while(CurrentE->next!=NULL)〃如果當前邊

已連有邊結點

CurrentE=CurrentE->next;//移動指針

到當前邊的最后一個結點

CurrentE->next=&E[i];〃把當前邊接上去

)

}

if(Point[j].y<Point[i].y)〃終比起點低

(

while(CurrentB->Scanline!=Point[j].y)//在桶內尋

找該邊的yMin

CurrentB=CurrentB->next;〃移至(J下一個桶結

E[i].x=Point[j].x;〃計算AET表的值

E[i].yMax=Point[i].y;

E[i].k=double((Point[i].x-Point[j].x))/(Point[i].y-

Point[j].y);//代表1/k

E[i].next=NULL;

CuirentE=CurrentB->p;//獲得桶上連接邊表的地址

if(CurrentE==NULL)

CurrentE=&E[i];〃邊表的起始地址

文檔僅供參考,不當之處,請聯系改正。

CurrentB->p=CurrentE;//第一個邊表直接連

接到對應的桶中

)

else

(

while(CurrentE->next!=NULL)〃如果當前邊

已連有邊結點

CurrentE=CurrentE->next;//移動指針

到當前邊的最后一個結點

CurrentE->next=&E[i];〃把當前邊接上去

)

}

}

CurrentB=NULL;

CurrentE=NULL;

}

voidCTest2View::AddEdge(AET*NewEdge)〃插入臨時邊表函數

(

Tl=HeadE;

if(Tl=NULL)〃邊表為空,將邊表置為TempEdge

Tl=NewEdge;

文檔僅供參考,不當之處,請聯系改正。

HeadE=Tl;

}

else

(

whiIe(Tl->next!=NULL)〃邊表不為空,將TempEdge連

在該邊之后

(

T1=T1->next;

)

T1->next=NewEdge;

voidCTest2View::EdegeOrder()〃對邊表進行排序函數

(

Tl=HeadE;

if(Tl==NULL)

(

return;

)

if(Tl->next==NULL)〃如果該邊表沒有再連邊表

return;//桶結點只有一條邊,不需要排序

文檔僅供參考,不當之處,請聯系改正。

else

(

if(Tl->next->x<Tl->x)〃邊表按x值排序

(

T2=T1->next;

T1->next=T2->next;

T2->next=T1;

HeadE=T2;

}

T2=HeadE;

T1=HeadE->next;

while(Tl->next!=NULL)〃繼續兩兩比較相連的邊表的

x值,進行排序

(

if(T1->next->x<Tl->x)

(

T2->next=T1->next;

T1->next=T1->next->next;

T2->next->next=T1;

T2=T2->next;

)

文檔僅供參考,不當之處,請聯系改正。

else

(

T2=T1;

T1=T1->next;

)

)

}

)

voidCTest2View::PolygonFiH()〃多邊形填充函數

{

CClientDCdc(this);

COLORREFrgb=RGB(0,0,255);

HeadE=NULL;

for(CurrentB=HeadB;CurrentB!=NULL;CurrentB=CurrentB-

>next)〃訪問所有桶結點

(

for(CurrentE=CurrentB-

>p;CurrentE!=NULL;CurrentE=CurrentE->next)〃桶中所有結點

AET*TempEdge=newAET;

文檔僅供參考,不當之處,請聯系改正。

TempEdge->x=CurrentE->x;

TempEdge->yMax=CurrentE->yMax;

TempEdge->k=CurrentE->k;

TempEdge->next=NULL;

AddEdge(TempEdge);//將該邊插入臨時Aet表

}

EdegeOrder。;//邊表按照x遞增的順序存放

Tl=HeadE;〃根據ymax拋棄掃描完的邊結點

if(Tl==NULL)

(

return;

}

whiIe(CurrentB->Scanline>=Tl->yMax)〃放棄該結點,

Aet表指針后移,下閉上開

(

T1=T1->next;

HeadE=Tl;

if(HeadE==NULL)

return;

}

文檔僅供參考,不當之處,請聯系改正。

if(Tl->next!=NULL)

(

T2=T1;

Tl=T2->next;

}

while(Tl!=NULL)

(

if(CurrentB->Scanline>=T1->yMax)//跳過一個結

{

T2->next=Tl->next;

Tl->next=NULL;

T1=T2->next;

)

else

(

T2=T1;

T1=T2->next;

}

BOOLIn=false;〃設置一個BOOL變量In,初始值為假

doublexb,xe;〃掃描線的起點和終點

文檔僅供參考,不當之處,請聯系改正。

for(T1=HeadE;T1!=NULL;T1=Tl->next)//填充掃描線和

多邊形相交的區間

(

if(In==false)

(

xb=Tl->x;

In=true;〃,每訪問一個結點,把In值取反

一次

}

else//如果In值為真,則填充從當前結點的x值

開始到下一個結點的x值結束的區間

(

xe=Tl->x-l;//左閉右開

CClientDCdc(this);

for(doublex=xb;x<=xe;x++)

dc.SetPixel(int(x),CurrentB-

>Scanline,rgb);〃填充

Sleep(l);〃延時1ms,提高填充過程的可視性

In=FALSE;

)

)

for(Tl=HeadE;Tl!=NULL;T1=T1->next)〃邊連貫性

文檔僅供參考,不當之處,請聯系改正。

T1->x=Tl->x+T1->k;〃x=x+1/k

}

}

deleteHeadB;

deleteCurrentB;

deleteCurrentE;

deleteHeadE;

/!初始化桶

K|*K1>K1*K|>K|>

voidCTest2View::CreatBucket()

intScanMax,ScanMin;

ScanMax=ScanMin=Point[0].y;

for(inti=l;i<Number;i++)

if(Point[i].y<ScanMin)

ScanMin=Point[i].y;//掃描線的最小值

文檔僅供參考,不當之處,請聯系改正。

if(Point[i].y>ScanMax)

(

ScanMax=Point[i].y;〃掃描線的最大值

}

}

for(i=ScanMin;i<=ScanMax;i++)//建立桶節點

(

if(ScanMin==i)//桶頭結點

(

HeadB=newBucket;〃建立桶的頭結點

溫馨提示

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

評論

0/150

提交評論