計算機圖形學實驗報告模板_第1頁
計算機圖形學實驗報告模板_第2頁
計算機圖形學實驗報告模板_第3頁
計算機圖形學實驗報告模板_第4頁
計算機圖形學實驗報告模板_第5頁
已閱讀5頁,還剩63頁未讀, 繼續(xù)免費閱讀

下載本文檔

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

文檔簡介

計算機圖形學實驗報告

姓名:_________________

學號:___________________________

班級:___________________________

時間:20XX年XX月

實驗一OpenGL編程與圖形繪制

1.實驗目的

了解OpenGL編程,并熟悉OpenGL的主要功能、繪制流程和基本語法。學會配置

OpenGL環(huán)境,并在該環(huán)境中編程繪圖。

2.實驗內容

OpenGL的主要功能:模型繪制、模型觀察、顏色模式、光照應用、圖像效果增強、位

圖和圖像處理、紋理映射、實時動畫和交互技術。

OpenGL的繪制流程分為兩個方面:一個完整的窗口系統(tǒng)的OpenGL圖形處理系統(tǒng)的結

構為:最底層為圖形硬件,第二層為操作系統(tǒng),第三層為窗口系統(tǒng),第四層為OpenGL,最

上面的層為應用軟件;OpenGL命令將被放在一個命令緩沖區(qū)中,這樣命令緩沖區(qū)中包含了

大量的命令、頂點數(shù)據和紋理數(shù)據。當緩沖區(qū)被清空時,緩沖區(qū)中的命令和數(shù)據都將傳遞給

流水線的下一個階段。

OpenGL的基本語法中相關庫有:OpenGL核心庫:gl,OpenGL實用程序庫:glu、OpenG

編程輔助庫:aux、OpenGL實用程序工具包(OpenGLutilitytoolkit,GLUT):glut、Windows

專用庫:wgl,

OpenGL的基本語法中命名規(guī)則為:OpenGL函數(shù)都遵循一個命名約定,即采用以下格

式:〈庫前綴〉<根命令><可選的參數(shù)個數(shù)><可選的參數(shù)類型〉。

了解了上述基礎知識后,配置好OpenGL環(huán)境,然后在該環(huán)境中編程練習圖形的繪制,

本次實驗主要是對點的繪制、直線的繪制和多邊形面的繪制。

3.實驗代碼及結果

3.1點的繪制:

#include<gl/glul.h>

voidInitial(void)

{

glClearColor(1.Of,1.Of,1.Of,1.00;〃設置窗口背景顏色為白色

glMatrixMode(GL_PROJECTION);〃指定設置投影參數(shù)

gluOrtho2D(0.0,200.0,0.0,150.0);〃設置投影參數(shù)

voidDisplay(void)

glClear(GL_COLOR_BUFFER_BIT);〃用當前背景顏色填充窗口

glColor3f(1.0f,0.0f,0.0f);〃設置當前的繪圖顏色為紅

//glRectf(50.0f,100.0f,150.0f,50.0f);〃繪制一個矩形

glPointSize(lO);〃三個點

glBegin(GL_POINTS);

glColor3f(1.0f,0.0f,0.0f);

glVertex2i(2,148);

glVertex2i(100,75);

glVertex2i(198,2);

glEnd();

glFlush();〃清空OpenGL命令緩沖區(qū),執(zhí)行OpenGL程序

)

intmain(intargc,char*argv[J)

glutlnit(&argc,argv);

glutInitDisplayMode(GLUT_SINGLE|GLUT_RGB);〃初始化窗口的顯示模式

glutInitWindowSize(400,300);〃設置窗口的尺寸

glutInitWindowPosition(100,120);〃設置窗口位置

glutCreateWindow("矩形");//創(chuàng)建一個名為矩形的窗口

glutDisplayFunc(Display);〃設置當前窗口的顯示回調函數(shù)

Initial();〃完成窗口初始化

glutMainLoopO;〃完成窗口GLUT事件處理循環(huán)

return0;

運行結果:

■矩形□0B

3.2直線的繪制:

#include<gl/glut.h>

voidInitial(void)

(

glClear€olor(1.01;1.Of,1.Of,1.00;〃設置窗口背景顏色為白色

glMatrixMode(GL_PROJECTION);〃指定設置投影參數(shù)

gluOrtho2D(0.0,200.0,0.0,150.0);〃設置投影參數(shù)

voidDisplay(void)

(

glClear(GL_COLOR_BUFFER_BIT);〃用當前背景顏色填充窗口

glColor3f(1.0f,0.0f,0.0D;〃設置當前的繪圖顏色為紅色

//glRectf(50.0f,l()0.0f,150.0f,50.0f);〃繪制一個矩形

glBegin(GL_LINE_LOOP);〃五角星

glVertex2i(10,10);

glVertex2i(30,35);

glVertex2i(50,10);

glVertex2i(5,25);

glVertex2i(55,25);

glEnd();

glFlush();〃清空OpenGL命令緩沖區(qū),執(zhí)行OpenGL程序

intmain(mtargc,char*argv[])

(

glutlnit(&argc,argv);

glutInitDisplayMode(GLUT_SINGLE|GLUT_RGB);〃初始化窗口的顯示模式

glutInitWindowSize(400,300);〃設置窗口的尺寸

glutInitWindowPosition(100,120);〃設置窗口位置

glutCreateWindow("矩形");//創(chuàng)建一個名為矩形的窗口

glutDisplayFunc(Display);〃設置當前窗口的顯示回調函數(shù)

Initial();〃完成窗口初始化

glutMainLoopO;〃完成窗口GLUT事件處理循環(huán)

return0;

運行結果:

■矩形13回區(qū)

3.3多邊形面的繪制:

#include<gl/glut.h>

voidInitial(void)

glClearColor(1.Of,1.Of,1.Of,1.00;〃設置窗口背景顏色為白色

glMatrixMode(GL_PROJECTION);//指定設置投影參數(shù)

gluOrtho2D(0.0,200.0,0.0,150.0);〃設置投影參數(shù)

)

voidDisplay(void)

(

glClear(GL_COLOR_BUFFER_BIT);〃用當前背景顏色填充窗口

glColor3f(l.0f,0.0f,0.0f);〃設置當前的繪圖顏色為紅色

//glRectf(50.0f,100.0f,150.0f,50.0f);〃繪制一個矩形

glBegin(GL_TRIANGLES);〃等邊三角形

glVertex2f(0.0,0.0);

glVertex2f(15,25.95);

glVertex2f(30,0);

glEnd();

glFlush();〃清空OpenGL命令緩沖區(qū),執(zhí)行OpenGL程序

)

intmain(intargc,char*argv[])

(

glutlnit(&argc,argv);

glutInitDisplayMode(GLUT_SINGLE|GLUT_RGB);〃初始化窗口的顯示模式

glutInitWindowSize(400,300);〃設置窗口的尺寸

glutInitWindowPosition(100,120);〃設置窗口位置

glutCreateWindow("矩形”);〃創(chuàng)建一個名為矩形的窗口

glutDisplayFunc(Display);〃設置當前窗口的顯示回調函數(shù)

Initial();〃完成窗口初始化

glutMainLoopO;〃完成窗口GLUT事件處理循環(huán)

return0;

運行結果:

實驗二直線繪制實驗

1.實驗目的

為了進一步熟悉OpenGL編程,了解基本圖形生成算法中的直線繪制,學會直線繪制算

法中最常用的三種算法:數(shù)值微分法、中點畫線算法和Bresenham算法。

2.實驗內容

(-)數(shù)值微分法

數(shù)值微分法直接從直線的微分方程生成直線。給定直線的兩端點:P0(X0,Y0)和

P1(X1,Y1),得到直線的微分方程dy/dx=Ay/Ax=(Yl-YO)/(Xl-XO)=k。

數(shù)值微分算法的原理是,由于直線的一階導數(shù)是連續(xù)的,而且和是成比例的,

因此通過在當前位置(Xi,Yi)分別加上兩個小增量£和為無窮小的正數(shù))來

求下一點(X(i+1),Y(i+1))的x,y坐標。

(-)中點畫線算法

給定直線的兩端點:PO(XO,YO)和P1(X1,Y1),可得到直線方程F(x,y)=y-kx-b=O且k=A

y/Ax=(Yl-YO)/(Xl-XO)o

繪圖過程如下:

①.輸入直線的兩端點PO(XO,YO)和P1(X1,Y1)O

②.計算初始值Ax,Ay,d=Ax-2Ay,x=XO,y=YO.

③.繪制點(x,y)。判斷d的符號,若d<0,則(x,y)更新為(x+l,y+l),d更新為d+2Z\x-2

△y;否則(x,y)更新為(x+1,y),d更新為Ay。

④.當直線沒有畫完時,重復步驟③,否則結束。

(三)Bresenham算法

算法步驟如下:

①.輸入直線兩端點PO(XO,YO)和P1(X1,Y1)?

②.計算初始值△*,Ay,e=-Ax,x=XO,y=Y0o

③.繪制點(x,y)。

@.e更新為e+2Ayo判斷e的符號,若e>0,則(x,y)更新為(x+1,y+1),同樣將e更新為

e-2Ax;否則(x,y)更新為(x+1,y)。

⑤.當直線沒有畫完時,重復步驟③和④;否則結束。

3.實驗代碼及結果

3.1數(shù)值微分算法編程繪制直線代碼:

#include<gl/glul.h>

#include<windows.h>

voidInitial(void)

(

glClearColor(1.Of,1.Of,1.Of,1.00;〃設置窗口背景顏色為白色

glMatrixMode(GL_PROJECTION);〃指定設置投影參數(shù)

gluOrlho2D(0.0,200.0,0.0,150.0);//設置投影參數(shù)

}

voidDisplay(void)

glClear(GL_COLOR_BUFFER_BIT);〃用當前背景顏色填充窗口

glColor3f(1.0f,0.0f,0.0f);〃設置當前的繪圖顏色為紅色

g]Begin(GL_LINES);

intx0=10;inty0=20;intxl=30;intyl=40;intcolor=10;

intdx,dy,epsl,k;

floatx,y,xlncre,ylncre;

dx=xl-xO;

dy=yl-yO;

x=xO;

y=yO;//

if(abs(dx)>abs(dy))

epsl=abs(dx);

elseepsl=abs(dy);

xlncre=(float)dx/(float)epsl;

ylncre=(float)dy/(float)epsl;

for(k=0;k<=epsl;k++)

(

glVertex2i(int(x+0.5),(int)(y+0.5));

x+=xlncre;

y+=ylncre;

)

glEnd();

glFlush();〃清空OpenGL命令緩沖區(qū),執(zhí)行OpenGL程序

)

intmain(intargc,char*argv[])

glutlnit(&argc,argv);

glutInitDisplayMode(GLUT_SINGLE|GLUT_RGB);〃初始化窗口的顯示模式

glutInitWindowSize(400,300);〃設置窗口的尺寸

glutInitWindowPosition(100,120);//設置窗口位置

glutCreateWindow("矩形)〃創(chuàng)建一個名為矩形的窗口

glutDisplayFunc(Display);〃設置當前窗口的顯示回調函數(shù)

Initial();〃完成窗口初始化

glutMainLoop();〃完成窗口GLUT事件處理循環(huán)

return0;

實驗結果:

2.2中點畫線算法編程繪制直線代碼:

#include<gl/glut.h>

#include<windows.h>

voidInitial(void)

(

glClearColor(1.Of,1.Of,1.Of,1.Of);〃設置窗口背景顏色為白色

glMatrixMode(GL_PROJECTION);〃指定設置投影參數(shù)

gluOrtho2D(0.0,200.0,0.0,150.0);//設置投影參數(shù)

)

voidDisplay(void)

(

glClear(GL_COLOR_BUFFER_BIT);〃用當前背景顏色填充窗口

glColor3f(1.0f,0.0f,0.0D;〃設置當前的繪圖顏色為紅色

glBegin(GL_POINTS);

intx0=50;inty0=20;intxl=100;intyl=120;intcolor=10;

intdx,dy,d,UpIncre,DownIncre,x,y;

if(x0>xl)

(

x=xl;xl=x0;x0=x;

y=yl;yl=yO;yO=y;

)

x=x0;y=y0;

dx=x1-xO;dy=y1-yO;

d=dx-2*dy;

Uplncre=2*dx-2*dy;Downlncre=2*dy;

while(x<=xl)

(

glVertex2i(x,y);

x++;

if(d<0)

y++;

d十二Uplncre;

)

elsed+=DownIncre;

glEndO;

glFlush();〃清空OpenGL命令緩沖區(qū),執(zhí)行OpenGL程序

)

intmain(intargc,char*argv[])

(

glutlnit(&argc,argv);

glutInitDisplayMode(GLUT_SINGLE|GLUT_RGB);〃初始化窗口的顯示模式

glutInitWindowSize(400,300);〃設置窗口的尺寸

glutInitWindowPosition(100J20);〃設置窗口位置

glutCreateWindow(“矩形");〃創(chuàng)建一個名為矩形的窗口

glutDispIayFunc(Display);〃設置當前窗口的顯示回調函數(shù)

Initial();〃完成窗口初始化

glutMainLoopO;〃完成窗口GLUT事件處理循環(huán)

return0;

實驗結果:

■矩形目|回岡

2.3Bresenham算法編程繪制直線代碼:

#include<gl/glut.h>

#include<windows.h>

voidInitial(void){

glClearColor(1.Of,1.Of,1.Of,1.Of);〃設置窗口背景顏色為白色

glMatrixMode(GL_PROJECTION);〃指定設置投影參數(shù)

gluOrtho2D(0.0,200.0,0.0,150.0);〃設置投影參數(shù)

voidDisplay(void){

glClear(GL_COLOR_BUFFER_BIT);〃用當前背景色填充窗口

glColor3f(1.0f,0.0f,0.0D;〃設置當前的繪圖顏色為紅色

//Bresenham算法

glBegin(GL_POINTS);

intx0=10;intyO=20;intxl=90;intyl=90;intcolor=10;

intx,y,dx,dy,e;

dx=xl-x0;dy=yl-yO;

e=-dx;x=x0;y=y0;

while(x<=xl){

glVertex2i(x,y);

x++;

e=e+2*dy;

if(e>0){

y++;

e=e-2*dx;

)

}

glEnd();

glFlush();〃清空OpenGL命令緩沖區(qū),執(zhí)行OpenGL程序

)

intmain(intargc,char*argv[]){

glutlnit(&argc,argv);

glutInitDisplayMode(GLUT_SINGLE|GLUT_RGB);〃初始化窗口的現(xiàn)實模式

glutInitWindowSize(400,300);〃設置窗口的尺寸

glutInilWindowPosition(100,200);//設置窗口的位置

glutCreateWindow("點");〃創(chuàng)建一個名為矩形的窗口

glutDisplayFunc(Display);//設置當前窗口的顯示函數(shù)

Initial();〃完成窗口的初始化

glutMainLoop();〃啟動主GLUT事件處理循環(huán)

return0;

實驗結果:

?點□0?

實驗三圓繪制實驗

1.實驗目的

2.實驗內容

(一)八分法畫圓

圓心位于原點的圓有4條對稱軸x=O,y=O,y=x,y=-x。若已知圓上任一點(x,y),可以得到其

在圓周上關于四條對稱軸的另外7個點(y,x),(-x,y),(-x,-y),(-y,-x),(y,-x),(x,-y)。

(二)中點Bresenham畫圓算法

算法步驟如下:

①輸入圓的半徑R

②計算初始值d=l-R,x=O,y=R。

③繪制點(x,y)及其在八分圓中的另外7個對稱點。

④判斷d的符號。若d<0,則先將d更新為d+2x+3,再將(x,y)更新為(x+1,y);否則先將

d更新為d+2(x-y)+5,再將(x,y)更新為(x+1,y-1)?

⑤當x〈y時,重復步驟③和④;否則結束。

(三)橢圓的中點Bresenham算法

算法步驟如下:

①輸入橢圓的長半軸a和短半軸bo

0計算初始值d=b八2+a八2(-b+0.25),x=0,y=b。

③繪制點(x,y)及其在四分象限上的另外三個對稱點。

④判斷d的符號。若d<=0,則先將d更新為d+92(2x+3),再將(x,y)更新為(x+l,y);否則先

將d更新為d+b0(2x+3)+a八2(-2y+2),再將(x,y)更新為(x+l,y-l)。

③當bO(x+l)<a"2(y-0.5)時,重復步驟③和④;否則轉到步驟⑥。

⑥用上半部分計算的最后點(x,y)來計算下半部分中d的初值

d=bA2(x+0.5)A2+aA2(y-1)A2-aA2bA2

⑦繪制點(x,y)及其在四分象限上的另外三個對稱點。

⑧判斷d的符號。若d<=0,則先將d更新為d+a2(2x+2)+aA2(-2y+3),再將(x,y)更新為

(x+l,y-l);否則先將d更新為d+a0(-2y+3),再將(x,y)更新為(x,y-l)。

⑨當y>=0時,重復步驟⑦和⑧;否則結束。

3.實驗代碼及結果

3.1八分法畫圓程序代碼:

#include<gl/glut.h>

#include<windows.h>

voidInitial(void)

(

glClearColor(1.Of,1.Of,1.Of,1.Of);〃設置窗口背景顏色為白色

gIMatrixMode(GL_PROJECTION);〃指定設置投影參數(shù)

gluOrtho2D(0.0,200.0,0.0,150.0);〃設置投影參數(shù)

voidCirclePoint(intx,inty,intcolor){

glVertex2i(x+50,y+50);

glVertex2i(y+50,x+50);

glVertex2i(-y+50,x+50);

glVertex2i(-x+50,y+50);

glVertex2i(-x+50,-y+50);

glVertex2i(-y+50,-x+50);

gIVertex2i(y+50,-x+50);

glVertex2i(x+50,-y+50);

)

voidDisplay(void)

(

glClear(GL_COLOR_BUFFER_BIT);〃用當前背景顏色填充窗口

glColor3f(1.0f,0.0f,0.0f);〃設置當前的繪圖顏色為紅色

glPointSize(lO);

glBegin(GL_POINTS);

CirclePoint(10,20,20);

glEnd();

glFlush();〃清空OpenGL命令緩沖區(qū),執(zhí)行OpenGL程序

}

intmain(intargc,char*argv[])

(

glutlnit(&argc,argv);

glutInitDisplayMode(GLUT_SINGLE|GLUT_RGB);〃初始化窗口的顯示模式

glutInitWindowSize(400,300);〃設置窗口的尺寸

glutInitWindowPosition(100,120);〃設置窗口位置

glutCreateWindow("矩形");〃創(chuàng)建一個名為矩形的窗口

glutDisplayFunc(Display);〃設置當前窗口的顯示回調函數(shù)

Initial();//完成窗口初始化

glutMainLoopO;〃完成窗口GLUT事件處理循環(huán)

return0;

)

實驗結果:

■矩形□0?

3.2中點Bresenham算法繪制圓代碼

#include<gl/glut.h>

#include<windows.h>

voidInitial(void)

(

glClearColor(1.Of,1.Of,1.Of,1.Of);〃設置窗口背景顏色為白色

gIMatrixMode(GL_PROJECTION);〃指定設置投影參數(shù)

gluOrtho2D(0.0,200.0,0.0,150.0);〃設置投影參數(shù)

voidCirclePoint(intx,inty,intcolor){

glVertex2i(x+50,y+50);

glVertex2i(y+50,x+50);

glVertex2i(-y+50,x+50);

glVertex2i(-x+50,y+50);

g】Vertex2i(-x+50,-y+50);

glVertex2i(-y+50,-x+50);

glVertex2i(y+50,-x+50);

glVertex2i(x+50,-y+50);

)

voidMidBresenhamCircle(intr,intcolor)

(

intx,y,d;

x=0;y=r;d=l-r;

while(x<=y)

(

CirclePoint(x,y,color);

if(d<0)

d+=2*x+3;

else

(

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

y-;

)

x++;

)

)

voidDisplay(void)

(

glClear(GL_COLOR_BUFFER_BIT);〃用當前背景顏色填充窗口

glColor3f(l.Of,O.Of,O.OD;〃設置當前的繪圖顏色為紅色

glPointSize(3);

glBegin(GL_POINTS);

MidBresenhamCircle(20,10);

glEnd();

glFlush();〃清空OpenGL命令緩沖區(qū),執(zhí)行OpenGL程序

intmain(intargc,char*argv[])

(

glutlnit(&argctargv);

glut!nitDisplayMode(GLUT_SINGLE|GLUT_RGB);〃初始化窗口的顯示模式

glulInitWindowSize(400,300);〃設置窗口的尺寸

glut!nitWindowPosition(100,120);//設置窗口位置

glulCreateWindow("矩形");//創(chuàng)建一個名為矩形的窗口

glutDisplayFunc(Display);〃設置當前窗口的顯示回調函數(shù)

Initial();〃完成窗口初始化

glutMainLoop();〃完成窗口GLUT事件處理循環(huán)

return0;

實驗結果:

3.3中點Bresenham算法繪制橢圓代碼:

#include<gl/glut.h>

#include<windows.h>

voidInitial(void)

(

glClearColor(1.Of,1.Of,1.Of,1.00;〃設置窗口背景顏色為白色

glMatrixMode(GL_PROJECTION);〃指定設置投影參數(shù)

gluOrlho2D(0.0,200.0,0.0,150.0);〃設置投影參數(shù)

)

voidMidBresenhamEllipse(inta,intb,intcolor)

(

intx,y;

floatdl,d2;

x=0;y=b;

d1=b*b+a*a*(?b+0.25);

glVertex2i(x+50,y+50);glVertex2i(-x+50,-y+50);

glVertex2i(-x+50,y+50);glVertex2i(x+50,-y+50);

while(b*b*(x+l)<a*a*(y-0.5))

if(dl<=0)

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

x++;

)

else

(

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

x++;y??;

)

glVertex2i(x+50,y+50);glVertex2i(-x+50,-y+50);

glVertex2i(-x+50,y+50);gIVertex2i(x+50,-y+50);

)

d2=b*b*(x+0.5)*(x+0.5)+a*a*(y-l)-a*a*b*b;

while(y>0)

(

if(d2<=0)

(

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

x++;y-?;

)

else{

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

y-;

)

glVertex2i(x+50,y+50);glVertex2i(-x+50,-y4-50);

glVertex2i(-x+50,y+50);glVertex2i(x+50,-y+50);

)

)

voidDisplay(void)

(

glClear(GL_COLOR_BUFFER_BIT);〃用當前背景顏色填充窗口

glColor3f(l.Of,O.Of,O.Of);〃設置當前的繪圖顏色為紅色

glPointSize(3);

glBegin(GL_POINTS);

MidBresenhamEllipse(40,25,10);

glEnd();

glFlush();〃清空OpenGL命令緩沖區(qū),執(zhí)行OpenGL程序

}

intmain(intargc,char*argv[])

(

glutlnit(&argc,argv);

glutInitDisplayMode(GLUT_SINGLE|GLUT_RGB);〃初始化窗口的顯示模式

glutInitWindowSize(400,300);〃設置窗口的尺寸

glutInitWindowPosition(100,120);〃設置窗口位置

glutCreateWindow(H矩形,〃創(chuàng)建一個名為矩形的窗口

glutDisplayFunc(Display);〃設置當前窗口的顯示回調函數(shù)

Initial();〃完成窗口初始化

glutMainLoop();〃完成窗口GLUT事件處理循環(huán)

return0;

)

實驗結果:

■矩形目回區(qū))

實驗四填充算法實驗

1.實驗目的

掌握用掃描線種子填充法,實現(xiàn)掃描線種子填充算法填充任一多邊形區(qū)域的程序

2.實驗內容

算法步驟如下:

(1)種子像素入棧。

(2)執(zhí)行如下三步操作:

①棧頂像素出棧。

②填充出棧像素所在掃描線的連續(xù)像素段,從出棧的像素開始沿掃描線向左和向右填充,

直到遇到邊界像素為止,即每出棧一個像素,就對包含該像素的整個掃描線區(qū)間進行填充,

并且記錄下此時掃描線區(qū)間的x坐標范圍[xl,x2]。

③分別檢查上、下兩條掃描線上位于[xl,x2]坐標區(qū)間內的未被填充的連續(xù)水平像素段,

將每個連續(xù)像素段的最左像素取作種子像素壓人棧堆。

(3)檢查棧是否為空,若棧非空重復執(zhí)行步驟(2),若棧為非空則結束。

3.實驗代碼及結果

代碼:

#includengl/glut.hH

#includenmath.h"

#include"stdlib.h**

#include"conio.h',

#include<stack>

typedeffloatColor[3];

structPoint

(

GLintx;

GLinty;

);

std::stack<Point>stk;

voidinit(void)

(

glClearColor(1.0,1.0,1.0,1.0);//Setdisplay-windowcolorwhite.

glMatrixMode(GL_PROJECTION);

gluOrtho2D(0.0,400.0,0.0,400.0);

)

voidsetPixel(GLintx,GLinty);〃種子像素坐標

voidsetPixel(Pointcur_point)

(

glBegin(GL_POINTS);

glVertex2i(cur_point.x,cur_point.y);

glEnd();

glFlush();

}

voidgetPixel(Pointcur_point,Colorc)

(

glReadPixels(cur_point.x,cur_point.y,1,1,GL_RGB,GL_FLOAT,c);

1

boolrgbColorEqual(Colorc1,Colorc2)

(

//cl顏色數(shù)據與c2顏色數(shù)據,當正負誤差不超過0.0001時,返回值為1,否則為0

if((abs(cl[0]-c2[0])>0.001)||(abs(cl[l]-c2[l])>0.001)||(abs(cl[2]-c2[2])>0.001))

return0;

elsereturn1;

intFiIlLineRegion(Pointcur_point,ColoriillColor,ColorborderColorjntdirection)

!

intcount=0;

ColorinteriorColor;

glColor3f(fillColor[0],fillColor[l],fillColor[2]);

getPixel(cur_point,interiorColor);

while(!(rgbColorEqual(interiorColor,borderColor))&&!(rgbColorEqual(interiorColor,fillColor)))

〃這個判斷保證讀取的像素的顏色數(shù)據與邊界顏色還有填充顏色數(shù)據在數(shù)值上相差

較大

〃即當正讀取像素不是多邊形邊界,且也沒有被填充,則執(zhí)行以下花括號內的操作

(

setPixel(cur_poinl);//setcolotofpixeltofillColor.〃為坐標為(x,y)的像素上色

if(direction==0)

cur_point.x++;

else

cur_point.x—;

getPixel(cur_point,interiorColor);

count++;

)

returncount;

)

intIsPixelValid(Pointcur_point,ColorfillColor,Colorbordei*Color)

(

ColorinteriorColor;

getPixel(cur_point,interiorColor);

if(!(rgbColorEqual(interiorColor,borderColor))&&!(rgbColorEqual(interiorColor,fillColor)))

return1;

else

return0;

1

voidSearchLineNewSeed(intxLeft,intxRight,inty,ColorfillColor,ColorborderColor)〃在種子像

素所在掃描線上一條或下一條是掃描線尋找新種子像素

(

intxt=xLeft;

intseed_left=-1;

Pointseed_point;

Pointtemp_point;

while(xt<=xRight)

(

seed_left=-l;

temp_point.x=xt;

temp_point.y=y;

while(xt<=xRight)//findthefirstvalidpoint

(

if(IsPixelValid(temp_point,fillColor,borderColor))

(

seed_left=temp_point.x;

break;

)

else

(

xt++;

temp_point.x=xt;

}

while(xt<=xRight)//findthenextinvalidpoint

(

if(IsPixelValid(temp_point,fillColor,borderColor))

(

xt++;

temp_point.x=xt;

)

else

(

break;

)

)

if(seed_left!=-l)

(

seed_point.x=seed_left;

seed_point.y=y;

stk.push(seed_point);

)

)

)

)

voidscanLine(Pointcur_point,ColorfillColor,ColorborderColor)

(

intcount=0;

intright,left;

Pointtemp_point;

while(!stk.empty())

(

Pointseed_point=stk.top();

stk.popO;〃種子像素出棧

count=FillLineRegion(seed_point,fiHColor,borderColor,。);//填充種子像素所在的掃描

線右邊

right=seed_point.x+count-1;

temp_point.x=seed_point.x-1;

temp_point.y=seed_point.y;

count=FillLineRegion(temp_point,fiHColor,borderColor,1);〃填充種子像素所在掃描線

左邊

left=seed_point.x-count;

SearchLineNewSeed(left,right,seed_point.y?l,fllColor,borderColor);〃在種子?像素所在

掃描線上方一條掃描線尋找新種子像素

SearchLineNewSeed(left,right,seed_point.y+1,fillColor,borderColor);〃在種子像素所在

掃描線尋找新種子像素

)

return;

)

voidmyDraw(void)

(

glClear(GL_COLOR_BUFFER_BIT);

glColor3f(0.0,0.0,0.0);

glBegin(GL_LINE_LOOP);

glVertex2f(20.0f,80.0f);

glVertex2f(30.0f,95.0f);

glVertex2f(50.0f,95.0f);

glVertex2f(60.0f,80.01);

glVertex2f(70.0f,95.0f);

glVertex2f(90.0f,95.0f);

glVertex2f(100.0f,80.0f);

glVertex2f(60.0f,30.00;

glEnd();

//int乂=60,丫=60;//種子像素坐標為(60,60)

structPointseed_point={65,65);

ColorfillColonborderColor;

fillColor[0]=1.0;fillColor[1]=0.0;fillColor[2]=0.0;

borderColor[0]=0.0;borderColor[l]=0.0;borderColor[2]=0.0;//掃描的邊界的顏色要與上面的

繪圖顏色一致

stk.push(seed_point);〃種子像素入棧

scanLine(seed_point,fillColor,borderColor);

glFlush();

)

voidmain(intargc,char*argv[]){

glutlnit(&argc,argv);

glutInitDisplayMode(GLUT_SINGLE|GLUT_RGB);

glutInitWindowSize(400,400);

glutInitWindowPosition(50,100);

glutCreateWindow(“邊界”);

init();

giutDisplayFunc(myDraw);

glutMainLoopO;

實驗五裁剪算法實驗

1.實驗目的

掌握用Cohen-Sutherland法裁減直線,掌握用Sutherland-Hodgman算法裁剪多邊形的編

程方法,并編程實現(xiàn)

2.實驗內容

Cohen-Sutherland直線段裁剪算法的步驟如下:

①輸入直線段的兩端點坐標Pl(xl,yl),P2(x2,y2),及窗口的4條邊界坐標ywt.,ywb,ywi,ywr?

②對Pl,P2進行編碼,點Pl的編碼為codel,點P2的編碼為code2。

③若codel|code2=0,對直線段P1P2”簡取”之,轉⑥;否則,若codel&code2!=0,對

直線段“簡棄”之,轉⑦;當上述兩條均不滿足時,進行步驟④。

④確保P1在窗戶外部。若P1在窗口內,則交換P1和P2的坐標值和編碼。

⑤根據P1編碼從低位喀什找編碼值為1的地方,從而確定P1的窗口外的哪一側,然

后求出直線段與相應窗口邊界的交點S,并用交點S的坐標值替換P1的坐標值,即在交點

S處把線段一分為二,并去掉P1S這一段??紤]到P1是窗口外的一點,因此可以去掉P1S。

轉②。

⑥用直線掃描轉換算法畫出當前的直線段P1P2。

⑦算法結束。

Sutherland-Hodgman算法:

基本思想:將多邊形的邊界作為一個整體,每次用窗口的一條邊界對要裁剪的多邊形進

行裁剪,體現(xiàn)“分而治之”的思想。每次裁剪時把落在窗口外部區(qū)域的圖形去掉,只保留落

在窗口內部區(qū)域的圖形,并把它作為下一次裁剪的多邊形。依次用窗口的4條邊界對多邊形

進行裁剪,則原始多邊形即被裁剪完畢。

3.實驗代碼及結果

Cohen-Sutherland直線段裁剪算法代碼:

ttinclude“stdafx.h"

#defineLEFT_EDGE1

#defineRIGHT_EDGE2

#defineBOTTOM_EDGE4

#defineTOP_EDGE8

floatymin=100;

intymax=300;

intxmin=100;

intxmax=300;

typedefstructLinea

(

intxO;

intyO;

intxl;

intyl;

}Linea;

Linea11={11.xO=450,11.yO=0,11.xl=0,11.yl=450};

Linea12={12.xO=450,12.yO=200,12.xl=0,12.yl=200};

Linea13={13.xO=200,13.yO=0,13.xl=200,13.yl=450};

voidLineGL(Linea&li)〃沒有&,引用改變li的值

(

glBegin(GL_LINES);

glColor3f(1.Of,0.Of,0.Of);glVertex2f(li.xO,li.yO);

glColor3f(0.Of,1.Of,0.Of);glVertex2f(li.xl,li.yl);〃雖

然兩個點的顏色設置不同,但是最終線段顏色是綠色

glEnd();〃因為

glShadeModel(GL_FLAT)設置為最后一個頂點的顏色

)〃決定整個圖元的

顏色。

intCompCode(intx,inty)

(

intcode=0x00;〃此處是二進制

if(y<ymin)

code=code|4;

if(y>ymax)

code=code|8;

if(x>xmax)

code=code|2;

if(x<xmin)

code=code|1;

returncode;

)

intcohensutherlandlineclip(Linea&ii)

intaccept=0,done=0;

floatx=0,y=0;

inttotal=0,flag=0;〃total與flag是標志

intcodeO,codel,codeout;

codeO=CompCode(li.xO,li.yO);

//printf(zzcode0=%d\n,z,codeO);

codel=CompCode(li.xl,li.yl);

〃printf("codel二%d\n〃,codel);

do{

if(!(codeO|codel))〃code0&codel=0000B,線段完全在窗口內部,

全部顯示

(

accept=1;

done=1;

)

elseif(codeO&codel)

(

done=1;flag=1;

)

else

(

if(codeO!=0)

codeout=codeO;

else

codeout=codel;

if(codeout&LEFT.EDGE)

{

y=li.yO+(li.yl-li.y0)*(xmin-li.xO)/(li.xl-li.xO);

x=(float)xmin;

)

elseif(codeout&RIGHT_EDGE)

(

y=li.yO+(li.yl-li.y0)*(xmax-li.xO)/(li.xl-li.xO);

x=(float)xmax;

)

elseif(codeout&BOTTOMEDGE)

(

x=li.xO+(li.xl-li.x0)*(ymin-li.yO)/(li.yl-li.yO);

y=(float)ymin;

)

elseif(codeout&TOP_EDGE)

{

x=li.xO+(li.xl-li.x0)*(ymax-li.yO)/(li.yl-li.yO);

y二(float)ymax;

)

if(codeout二二codeO)

(

li.xO=x;li.yO=y;

codeO=CompCode(li.xO,li.yO);

)

else

(

li.xl=x;li.yl=y;

codel=CompCode(li.xl,li.yl);

)

total++;

if(total>3)〃total>3,執(zhí)行兩次后total又加一

(

done=1;flag=1;

)

)

}while(!done);

if(accept)〃線段位于窗口內或者線段剪裁過accepts;

(

LineGL(li);

)

else

(

li.xO=0;li.yO=0;li.xl=0;li.yl=0;

LineGL(li);

)

returnaccept;

)

voidmyDisplay()

(

glClear(GL_COLOR_BUFFER_BIT);

glColor3f(1.0f,0.Of,0.Of);

glBegin(GL_LINE_LOOP);

glVertex2f(100,100);

glVertex2f(300,100);

glVertex2f(300,300);

glVertex2f(100,300);

glEndO;

LineGL(ll);

LineGL(12);

LineGL(13);

glFlush();

)

voidInit()

glClearColor(0.0,0.0,0.0,0.0);

glShadeModel(GL_FLAT);

printf(/zPresskey'c'toClip!\nPresskey'r'toRestore!\n〃);

)

voidReshape(intw,inth)

(

glViewport(0,0,(GLsizei)w,(GLsizei)h);

glMatrixMode(GLPROJECTION);

glLoadldentity();

glu0rtho2D(0.0,(GLdouble)w,0.0,(GLdouble)h);

〃printf(〃######Reshape\n〃);

)

voidkeyboard(unsignedcharkey,intx,inty)

(

switch(key)

(

case'c:

cohensutherlandlinec1ip(11);

cohensutherlandlineclip(12);

cohensutherlandlineclip(13);

glutPostRedisplay();

break;

case'r:

ILxO=450;11.yO=0;11.xl=0;11.yl=450;

12.xO=450;12.yO=200;12.xl=0;12.yl=200;

13.xO=200;13.yO=0;13.xl=200;13.yl=450;

Init();

glutPostRedisplay();

break;

case'x':

exit(0);

break;

default:

break;

}

}

intmain(intargc,char*argv[])

(

glutlnit(ftargc,argv);

glutInitDisplayMode(GLUTRGB|GLUT_SINGLE);

glutlnitWindowPosition(100,100);

glutlnitWindowSize(640,480);

glutCreateWindow(,/Cohen-Sutherland,/);

Init();

glutDisplayFunc(myDisplay);

glutReshapeFunc(Reshape);

glutKeyboardFunc(&keyboard);〃按下鍵盤后會調用該函數(shù),鍵和鼠標點擊位置作

為變量傳給keyboard函數(shù)

glutMainLoopO;

return0;

)

實驗結果:

■'Cohen-Sutherland

溫馨提示

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

評論

0/150

提交評論