-计算机图形学实验报告_第1页
-计算机图形学实验报告_第2页
-计算机图形学实验报告_第3页
-计算机图形学实验报告_第4页
-计算机图形学实验报告_第5页
已阅读5页,还剩28页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、计算机图形学实验报告姓名:学号:班级:时间:2016年12月_实验一OpenGL编程与图形绘制1实验目的了解OpenGL编程,并熟悉OpenGL的主要功能、绘制流程和基本语法。学会配置OpenGL环境,并在该环境中编程绘图。2实验内容OpenGL的主要功能:模型绘制、模型观察、颜色模式、光照应用、图像效果增强、位图和图像处理、纹理映射、实时动画和交互技术。OpenGL的绘制流程分为两个方面:一个完整的窗口系统的OpenGL图形处理系统的结构为:最底层为图形硬件,第二层为操作系统,第三层为窗口系统,第四层为OpenGL,最上面的层为应用软件;OpenGL命令将被放在一个命令缓冲区中,这样命令缓冲

2、区中包含了大量的命令、顶点数据和纹理数据。当缓冲区被清空时,缓冲区中的命令和数据都将传递给流水线的下一个阶段。OpenGL的基本语法中相关库有:OpenGL核心库:gl、OpenGL实用程序库:glu、OpenG编程辅助库:aux、OpenGL实用程序工具包(OpenGLutilitytoolkit,GLUT):glut、Windows专用库:wgl。OpenGL的基本语法中命名规则为:OpenGL函数都遵循一个命名约定,即采用以下格式:库前缀根命令可选的参数个数可选的参数类型。了解了上述基础知识后,配置好OpenGL环境,然后在该环境中编程练习图形的绘制,本次实验主要是对点的绘制、直线的绘制

3、和多边形面的绘制。3实验代码及结果3.1点的绘制:#includegl/glut.hvoidInitial(void)glClearColor(1.0f,1.0f,1.0f,1.0f);/设置窗口背景颜色为白色glMatrixMode(GL_PROJECTION);/指定设置投影参数gluOrtho2D(0.0,200.0,0.0,150.0);/设置投影参数voidDisplay(void)glClear(GL_COLOR_BUFFER_BIT);/用当前背景颜色填充窗口glColor3f(1.0f,0.0f,0.0f);/设置当前的绘图颜色为红/glRectf(50.0f,100.0f,1

4、50.0f,50.0f);/绘制一个矩形glPointSize(10);/三个点glBegin(GL_POINTS);glColor3f(1.0f,0.0f,0.0f);glVertex2i(2,148);glVertex2i(100,75);glVertex2i(198,2);glEnd();glFlush();/清空OpenGL命令缓冲区,执行OpenGL程序intmain(intargc,char*argv)glutInit(&argc,argv);glutInitDisplayMode(GLUT_SINGLE|GLUT_RGB);/初始化窗口的显示模式glutInitWindowSiz

5、e(400,300);glutInitWindowPosition(100,120);glutCreateWindow(glutInitWindowSize(400,300);glutInitWindowPosition(100,120);glutCreateWindow(矩形”);glutDisplayFunc(Display);Initial();glutMainLoop();/设置窗口的尺寸/设置窗口位置/创建一个名为矩形的窗口/设置当前窗口的显示回调函数/完成窗口初始化完成窗口GLUT事件处理循环return0;运行结果:3.2直线的绘制:运行结果:3.2直线的绘制:#includev

6、oidInitial(void)glClearColor(1.0f,1.0f,1.0f,1.0f);/设置窗口背景颜色为白色glMatrixMode(GL_PROJECTION);/指定设置投影参数gluOrtho2D(0.0,200.0,0.0,150.0);/设置投影参数voidDisplay(void)glClear(GL_COLOR_BUFFER_BIT);/用当前背景颜色填充窗口glColor3f(1.0f,0.0f,0.0f);/设置当前的绘图颜色为红色/glRectf(50.0f,100.0f,150.0f,50.0f);/绘制一个矩形glBegin(GL_LINE_LOOP);

7、/五角星glVertex2i(10,10);glVertex2i(30,35);glVertex2i(50,10);glVertex2i(5,25);glVertex2i(55,25);glEnd();glFlush();清空OpenGL命令缓冲区,执行OpenGL程序intmain(intargc,char*argv)glutInit(&argc,argv);glutInitDisplayMode(GLUT_SINGLE|GLUT_RGB);/初始化窗口的显示模式glutInitWindowSize(400,300);glutInitWindowPosition(100,120);glutC

8、reateWindow(glutInitWindowSize(400,300);glutInitWindowPosition(100,120);glutCreateWindow(,矩形”);glutDisplayFunc(Display);Initial();glutMainLoop();/设置窗口的尺寸/设置窗口位置/创建一个名为矩形的窗口/设置当前窗口的显示回调函数/完成窗口初始化完成窗口GLUT事件处理循环return0;运行结果:3.3多边形面的绘制:#includevoidInitial(void)glClearColor(1.0f,1.0f,1.0f,1.0f);/设置窗口背景颜色

9、为白色glMatrixMode(GL_PROJECTION);/指定设置投影参数gluOrtho2D(0.0,200.0,0.0,150.0);/设置投影参数voidDisplay(void)glClear(GL_COLOR_BUFFER_BIT);/用当前背景颜色填充窗口glColor3f(1.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(3

10、0,0);glEnd();glFlush();/清空OpenGL命令缓冲区,执行OpenGL程序intmain(intargc,char*argv)glutInit(&argc,argv);glutInitDisplayMode(GLUT_SINGLE|GLUT_RGB);/初始化窗口的显示模式glutInitWindowSize(400,300);/设置窗口的尺寸glutInitWindowPosition(100,120);/设置窗口位置glutCreateWindow(矩形”);glutDisplayFunc(Display);Initial();glutMainLoop();retur

11、n0;/创建一个名为矩形的窗口/创建一个名为矩形的窗口/设置当前窗口的显示回调函数/完成窗口初始化完成窗口GLUT事件处理循环实验二直线绘制实验实验目的为了进一步熟悉OpenGL编程,了解基本图形生成算法中的直线绘制,学会直线绘制算法中最常用的三种算法:数值微分法、中点画线算法和Bresenham算法。实验内容数值微分法数值微分法直接从直线的微分方程生成直线。给定直线的两端点:P0(X0,Y0)和P1(X1,Y1),得到直线的微分方程dy/dx=Ay/Ax=(Yl-YO)/(Xl-XO)=k。数值微分算法的原理是,由于直线的一阶导数是连续的,而且&和Ay是成比例的,因此通过在当前位置(Xi,Y

12、i)分别加上两个小增量ex和&(&为无穷小的正数)来求下一点(X(i+l),Y(i+l)的x,y坐标。中点画线算法给定直线的两端点:PO(XO,YO)和P1(X1,Y1),可得到直线方程F(x,y)=y-kx-b=O且k=A/x=(YlYO)/(XlXO)。绘图过程如下:O输入直线的两端点P0(X0,Y0)和P1(X1,Y1)。Q.计算初始值Ax,y,d=Ax-2Ay,x=X0,y=Y0.Q.绘制点(x,y)。判断d的符号,若d0,贝Hx,y)更新为(x+l,y+l),d更新为d+2Ax-2y;否则(x,y)更新为(x+1,y),d更新为Ay。Q.当直线没有画完时,重复步骤,否则结束。Bres

13、enham算法算法步骤如下:Q.输入直线两端点P0(X0,Y0)和P1(X1,Y1)。Q.计算初始值Ax,y,e=-Ax,x=X0,y=Y0。Q.绘制点(x,y)。Q.e更新为e+2Ay。判断e的符号,若e0,则(x,y)更新为(x+l,y+l),同样将e更新为e-2Ax;否则(x,y)更新为(x+l,y)。Q.当直线没有画完时,重复步骤Q和Q;否则结束。实验代码及结果3.1数值微分算法编程绘制直线代码:#include#includevoidInitial(void)glClearColor(1.0f,1.0f,1.0f,1.0f);/设置窗口背景颜色为白色glMatrixMode(GL_P

14、ROJECTION);/指定设置投影参数gluOrtho2D(0.0,200.0,0.0,150.0);/设置投影参数voidDisplay(void)glClear(GL_COLOR_BUFFER_BIT);/用当前背景颜色填充窗口glColor3f(1.0f,0.0f,0.0f);/设置当前的绘图颜色为红色glBegin(GL_LINES);intx0=10;inty0=20;intx1=30;inty1=40;intcolor=10;intdx,dy,epsl,k;floatx,y,xIncre,yIncre;dx=x1-x0;dy=y1-y0;x=x0;y=y0;/if(abs(dx)

15、abs(dy)epsl=abs(dx);elseepsl=abs(dy);xIncre=(float)dx/(float)epsl;yIncre=(float)dy/(float)epsl;for(k=0;k=epsl;k+)glVertex2i(int(x+0.5),(int)(y+0.5);x+=xIncre;y+=yIncre;glEnd();glFlush();/清空OpenGL命令缓冲区,执行OpenGL程序intmain(intargc,char*argv)glutInit(&argc,argv);glutInitDisplayMode(GLUT_SINGLE|GLUT_RGB);

16、/初始化窗口的显示模式glutInitWindowSize(400,300);glutInitWindowPosition(100,120);glutCreateWindow(glutInitWindowSize(400,300);glutInitWindowPosition(100,120);glutCreateWindow(,矩形”);glutDisplayFunc(Display);Initial();glutMainLoop();/设置窗口的尺寸/设置窗口位置/创建一个名为矩形的窗口/设置当前窗口的显示回调函数/完成窗口初始化完成窗口GLUT事件处理循环return0;实验结果:2.2

17、中点画线算法编程绘制直线代码:#include#includevoidInitial(void)glClearColor(1.0f,1.0f,1.0f,1.0f);/设置窗口背景颜色为白色glMatrixMode(GL_PROJECTION);/指定设置投影参数gluOrtho2D(0.0,200.0,0.0,150.0);/设置投影参数voidDisplay(void)glClear(GL_COLOR_BUFFER_BIT);/用当前背景颜色填充窗口glColor3f(1.0f,0.0f,0.0f);/设置当前的绘图颜色为红色glBegin(GL_POINTS);intx0=50;inty0

18、=20;intx1=100;inty1=120;intcolor=10;intdx,dy,d,UpIncre,DownIncre,x,y;if(x0 x1)x=x1;x1=x0;x0=x;y=y1;y1=y0;y0=y;x=x0;y=y0;dx=x1-x0;dy=y1-y0;d=dx-2*dy;UpIncre=2*dx-2*dy;DownIncre=2*dy;while(x=x1)glVertex2i(x,y);x+;if(d0)y+;d+=UpIncre;elsed+=DownIncre;/清空/清空OpenGL命令缓冲区,执行OpenGL程序glFlush();intmain(intarg

19、c,char*argv)glutInit(&argc,argv);glutInitDisplayMode(GLUT_SINGLE|GLUT_RGB);/初始化窗口的显示模式glutInitWindowSize(400,300);glutInitWindowPosition(100,120);glutCreateWindow(glutInitWindowSize(400,300);glutInitWindowPosition(100,120);glutCreateWindow(,矩形”);glutDisplayFunc(Display);Initial();glutMainLoop();/设置窗

20、口的尺寸/设置窗口位置/创建一个名为矩形的窗口/设置当前窗口的显示回调函数/完成窗口初始化完成窗口GLUT事件处理循环return0;实验结果:2.3Bresenham算法编程绘制直线代码:#include#includevoidInitial(void)glClearColor(1.0f,1.0f,1.0f,1.0f);/设置窗口背景颜色为白色glMatrixMode(GL_PROJECTION);/指定设置投影参数gluOrtho2D(0.0,200.0,0.0,150.0);/设置投影参数voidDisplay(void)glClear(GL_COLOR_BUFFER_BIT);/用当前

21、背景色填充窗口glColor3f(1.0f,0.0f,0.0f);/设置当前的绘图颜色为红色/Bresenham算法glBegin(GL_POINTS);intx0=10;inty0=20;intx1=90;inty1=90;intcolor=10;intx,y,dx,dy,e;dx=x1-x0;dy=y1-y0;e=-dx;x=x0;y=y0;while(x0)y+;e=e-2*dx;glEnd();glFlush();/清空OpenGL命令缓冲区,执行OpenGL程序intmain(intargc,char*argv)glutInit(&argc,argv);glutInitDisplay

22、Mode(GLUT_SINGLE|GLUT_RGB);/初始化窗口的现实模式glutInitWindowSize(400,300);/设置窗口的尺寸glutInitWindowPosition(100,200);设置窗口的位置glutCreateWindow(点);创建一个名为矩形的窗口glutDisplayFunc(Display);/设置当前窗口的显示函数Initial();/完成窗口的初始化glutMainLoop();/启动主GLUT事件处理循环return0;实验结果:实验三圆绘制实验实验目的实验内容八分法画圆圆心位于原点的圆有4条对称轴x=O,y=O,y=x,y=-x。若已知圆上任

23、一点(x,y),可以得到其在圆周上关于四条对称轴的另外7个点(y,x),(-x,y),(-x,-y),(-y,-x),(y,-x),(x,-y)。中点Bresenham画圆算法算法步骤如下:Q输入圆的半径RQ计算初始值d=l-R,x=O,y=R。绘制点(x,y)及其在八分圆中的另外7个对称点。Q判断d的符号。若d0,则先将d更新为d+2x+3,再将(x,y)更新为(x+l,y);否则先将d更新为d+2(x-y)+5,再将(x,y)更新为(x+l,y-l)。Q当xy时,重复步骤和Q;否则结束。椭圆的中点Bresenham算法算法步骤如下:输入椭圆的长半轴a和短半轴bo计算初始值d=b人2+a人2

24、(-b+0.25),x=0,y=b。绘制点(x,y)及其在四分象限上的另外三个对称点。判断d的符号。若d=0,则先将d更新为d+bA2(2x+3),再将(x,y)更新为(x+1,y)否则先将d更新为d+bA2(2x+3)+aA2(-2y+2),再将(x,y)更新为(x+l,y-l)。当匕人2(x+1)a人2(丫-0.5)时,重复步骤和;否则转到步骤。6用上半部分计算的最后点(x,y)来计算下半部分中d的初值d=bA2(x+0.5)A2+aA2(y-1)A2-aA2bA2绘制点(x,y)及其在四分象限上的另外三个对称点。判断d的符号。若d=0时,重复步骤0和;否则结束。实验代码及结果八分法画圆程

25、序代码:#include#includevoidInitial(void)glClearColor(1.0f,1.0f,1.0f,1.0f);/设置窗口背景颜色为白色glMatrixMode(GL_PROJECTION);/指定设置投影参数gluOrtho2D(0.0,200.0,0.0,150.0);/设置投影参数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

26、,-y+50);glVertex2i(-y+50,-x+50);glVertex2i(y+50,-x+50);glVertex2i(x+50,-y+50);voidDisplay(void)glClear(GL_COLOR_BUFFER_BIT);/用当前背景颜色填充窗口glColor3f(1.0f,0.0f,0.0f);/设置当前的绘图颜色为红色glPointSize(10);glBegin(GL_POINTS);CirclePoint(10,20,20);glEnd();glFlush();/清空OpenGL命令缓冲区,执行OpenGL程序intmain(intargc,char*argv

27、)glutInit(&argc,argv);glutInitDisplayMode(GLUT_SINGLE|GLUT_RGB);/初始化窗口的显示模式glutInitWindowSize(400,300);/设置窗口的尺寸glutInitWindowPosition(100,120);/设置窗口位置glutCreateWindow(矩形”);glutDisplayFunc(Display);Initial();glutMainLoop();return0;/创建一个名为矩形的窗口/创建一个名为矩形的窗口/设置当前窗口的显示回调函数/完成窗口初始化完成窗口GLUT事件处理循环中点Bresenha

28、m算法绘制圆代码#include#includevoidInitial(void)glClearColor(1.0f,1.0f,1.0f,1.0f);/设置窗口背景颜色为白色glMatrixMode(GL_PROJECTION);/指定设置投影参数gluOrtho2D(0.0,200.0,0.0,150.0);/设置投影参数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(-

29、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=1-r;while(x=y)CirclePoint(x,y,color);if(d0)d+=2*x+3;elsed+=2*(x-y)+5;y-;x+;voidDisplay(void)glClear(GL_COLOR_BUFFER_BIT);/用当前背景颜色填充窗口glColor3f(1.0f,0.0f,0.0f);/设置

30、当前的绘图颜色为红色glPointSize(3);glBegin(GL_POINTS);MidBresenhamCircle(20,10);/清空/清空OpenGL命令缓冲区,执行OpenGL程序glFlush();intmain(intargc,char*argv)glutInit(&argc,argv);glutInitDisplayMode(GLUT_SINGLE|GLUT_RGB);/初始化窗口的显示模式glutInitWindowSize(400,300);glutInitWindowPosition(100,120);glutCreateWindow(,glutInitWindow

31、Size(400,300);glutInitWindowPosition(100,120);glutCreateWindow(,矩形”);glutDisplayFunc(Display);Initial();/设置窗口的尺寸/设置窗口位置/创建一个名为矩形的窗口/设置当前窗口的显示回调函数/完成窗口初始化glutMainLoop();return0;完成窗口glutMainLoop();return0;完成窗口GLUT事件处理循环中点Bresenham算法绘制椭圆代码:#include#includevoidInitial(void)glClearColor(1.0f,1.0f,1.0f,1.

32、0f);/设置窗口背景颜色为白色glMatrixMode(GL_PROJECTION);/指定设置投影参数gluOrtho2D(0.0,200.0,0.0,150.0);/设置投影参数voidMidBresenhamEllipse(inta,intb,intcolor)intx,y;floatd1,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+1)a*a*(y-0.5)

33、if(d10)if(d2=0)d2+=b*b*(2*x+2)+a*a*(-2*y+3);x+;y-;elsed2+=a*a*(-2*y+3);y-;glVertex2i(x+50,y+50);glVertex2i(-x+50,-y+50);glVertex2i(-x+50,y+50);glVertex2i(x+50,-y+50);voidDisplay(void)glClear(GL_COLOR_BUFFER_BIT);/用当前背景颜色填充窗口glColor3f(1.0f,0.0f,0.0f);/设置当前的绘图颜色为红色glPointSize(3);glBegin(GL_POINTS);Mid

34、BresenhamEllipse(40,25,10);glEnd();glFlush();/清空OpenGL命令缓冲区,执行OpenGL程序intmain(intargc,char*argv)glutInit(&argc,argv);glutInitDisplayMode(GLUT_SINGLE|GLUT_RGB);/初始化窗口的显示模式glutInitWindowSize(400,300);/设置窗口的尺寸glutInitWindowPosition(100,120);/设置窗口位置glutCreateWindow(,矩形”);创建一个名为矩形的窗口glutDisplayFunc(Displ

35、ay);Initial();glutMainLoop();return0;/设置当前窗口的显示回调函数/设置当前窗口的显示回调函数/完成窗口初始化完成窗口GLUT事件处理循环实验四填充算法实验实验目的掌握用扫描线种子填充法,实现扫描线种子填充算法填充任一多边形区域的程序实验内容算法步骤如下:种子像素入栈。执行如下三步操作:Q栈顶像素出栈。Q填充出栈像素所在扫描线的连续像素段,从出栈的像素开始沿扫描线向左和向右填充,直到遇到边界像素为止,即每出栈一个像素,就对包含该像素的整个扫描线区间进行填充,并且记录下此时扫描线区间的x坐标范围xl,x2。Q分别检查上、下两条扫描线上位于xl,x2坐标区间内的

36、未被填充的连续水平像素段,将每个连续像素段的最左像素取作种子像素压人栈堆。检查栈是否为空,若栈非空重复执行步骤(2),若栈为非空则结束。实验代码及结果代码:#includegl/glut.h#includemath.h#includestdlib.h#includeconio.h#includetypedeffloatColor3;structPointGLintx;GLinty;std:stackstk;voidinit(void)glClearColor(l.0,l.0,l.0,l.0);/Setdisplay-windowcolorwhite.glMatrixMode(GL_PROJEC

37、TION);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,l,l,GL_RGB,GL_FLOAT,c);boolrgbColorEqual(Colorcl,Color

38、c2)/cl颜色数据与c2颜色数据,当正负误差不超过0.0001时,返回值为1,否则为0if(abs(cl0-c20)0.00l)|(abs(cll-c2l)0.00l)|(abs(cl2-c22)0.00l)return0;elsereturn1;intFillLineRegion(Pointcur_point,ColorfillColor,ColorborderColor,intdirection)intcount=0;ColorinteriorColor;glColor3f(fillColor0,fillColor1,fillColor2);getPixel(cur_point,inte

39、riorColor);while(!(rgbColorEqual(interiorColor,borderColor)&!(rgbColorEqual(interiorColor,fillColor)/这个判断保证读取的像素的颜色数据与边界颜色还有填充颜色数据在数值上相差较大/即当正读取像素不是多边形边界,且也没有被填充,则执行以下花括号内的操作setPixel(cur_point);/setcolotofpixeltofillColor./为坐标为(x,y)的像素上色if(direction=0)cur_point.x+;elsecur_point.x-;getPixel(cur_point

40、,interiorColor);count+;returncount;intIsPixelValid(Pointcur_point,ColorfillColor,ColorborderColor)ColorinteriorColor;getPixel(cur_point,interiorColor);if(!(rgbColorEqual(interiorColor,borderColor)&!(rgbColorEqual(interiorColor,fillColor)return1;elsereturn0;voidSearchLineNewSeed(intxLeft,intxRight,in

41、ty,ColorfillColor,ColorborderColor)/在种子像素所在扫描线上一条或下一条是扫描线寻找新种子像素intxt=xLeft;intseed_left=-1;Pointseed_point;Pointtemp_point;while(xt=xRight)seed_left=-1;temp_point.x=xt;temp_point.y=y;while(xt=xRight)/findthefirstvalidpointif(IsPixelValid(temp_point,fillColor,borderColor)seed_left=temp_point.x;break

42、;elsext+;temp_point.x=xt;while(xt=xRight)/findthenextinvalidpointif(IsPixelValid(temp_point,fillColor,borderColor)xt+;temp_point.x=xt;elsebreak;if(seed_left!=-1)seed_point.x=seed_left;seed_point.y=y;stk.push(seed_point);voidscanLine(Pointcur_point,ColorfillColor,ColorborderColor)intcount=0;intright,

43、left;Pointtemp_point;while(!stk.empty()Pointseed_point=stk.top();stk.pop();/种子像素出栈count=FillLineRegion(seed_point,fillColor,borderColor,0);/Z填充种子像素所在的扫描线右边right=seed_point.x+count-1;temp_point.x=seed_point.x-1;temp_point.y=seed_point.y;count=FillLineRegion(temp_point,fillColor,borderColor,l);/填充种子像素

44、所在扫描线左边left=seed_point.x-count;SearchLineNewSeed(left,right,seed_point.y-l,fillColor,borderColor);/在种子像素所在扫描线上方一条扫描线寻找新种子像素SearchLineNewSeed(left,right,seed_point.y+l,fillColor,borderColor);/在种子像素所在扫描线寻找新种子像素return;voidmyDraw(void)glClear(GL_COLOR_BUFFER_BIT);glColor3f(0.0,0.0,0.0);glBegin(GL_LINE_L

45、OOP);glVertex2f(20.0f,80.0f);glVertex2f(30.0f,95.0f);glVertex2f(50.0f,95.0f);glVertex2f(60.0f,80.0f);glVertex2f(70.0f,95.0f);glVertex2f(90.0f,95.0f);glVertex2f(l00.0f,80.0f);glVertex2f(60.0f,30.0f);glEnd();/intx=60,y=60;种子像素坐标为(60,60)structPointseed_point=65,65;ColorfillColor,borderColor;fillColor0=

46、l.0;fillColorl=0.0;fillColor2=0.0;borderColor0=0.0;borderColorl=0.0;borderColor2=0.0;/扫描的边界的颜色要与上面的绘图颜色一致stk.push(seed_point);/种子像素入栈scanLine(seed_point,fillColor,borderColor);glFlush();voidmain(intargc,char*argv)glutInit(&argc,argv);glutInitDisplayMode(GLUT_SINGLE|GLUT_RGB);glutInitWindowSize(400,4

47、00);glutInitWindowPosition(50,l00);glutCreateWindow(边界”);init();glutDisplayFunc(myDraw)glutMainLoop()实验五裁剪算法实验实验目的掌握用Cohen-Sutherland法裁减直线,掌握用Sutherland-Hodgman算法裁剪多边形的编程方法,并编程实现实验内容Cohen-Sutherland直线段裁剪算法的步骤如下:Q输入直线段的两端点坐标Pl(xl,yl),P2(x2,y2),及窗口的4条边界坐标ywt,ywb,ywl,ywroQ对Pl,P2进行编码,点Pl的编码为codel,点P2的编码

48、为code2。Q若codel|code2=0,对直线段PlP2“简取”之,转Q;否则,若codel&code2!=0,对直线段“简弃”之,转当上述两条均不满足时,进行步骤QoQ确保Pl在窗户外部。若Pl在窗口内,则交换Pl和P2的坐标值和编码。Q根据Pl编码从低位喀什找编码值为1的地方,从而确定Pl的窗口外的哪一侧,然后求出直线段与相应窗口边界的交点S,并用交点S的坐标值替换Pl的坐标值,即在交点S处把线段一分为二,并去掉PlS这一段。考虑到Pl是窗口外的一点,因此可以去掉PlSo转QQ用直线扫描转换算法画出当前的直线段PlP2oQ算法结束。Sutherland-Hodgman算法:基本思想:

49、将多边形的边界作为一个整体,每次用窗口的一条边界对要裁剪的多边形进行裁剪,体现“分而治之”的思想。每次裁剪时把落在窗口外部区域的图形去掉,只保留落在窗口内部区域的图形,并把它作为下一次裁剪的多边形。依次用窗口的4条边界对多边形进行裁剪,则原始多边形即被裁剪完毕。实验代码及结果Cohen-Sutherland直线段裁剪算法代码:#includestdafx.h#defineLEFT_EDGE1#defineRIGHT_EDGE2#defineBOTTOM_EDGE4#defineTOP_EDGE8floatymin=100;intymax=300;intxmin=100;intxmax=300;

50、typedefstructLineaintx0;inty0;intx1;inty1;Linea;Lineal1=l1.x0=450,l1.y0=0,l1.x1=0,l1.y1=450;Lineal2=l2.x0=450,l2.y0=200,l2.x1=0,l2.y1=200;Lineal3=l3.x0=200,l3.y0=0,l3.x1=200,l3.y1=450;voidLineGL(Linea&li)/没有&,引用改变li的值glBegin(GL_LINES);glColor3f(1.0f,0.0f,0.0f);glVertex2f(li.x0,li.y0);glColor3f(0.0f,

51、1.0f,0.0f);glVertex2f(li.x1,li.y1);/虽然两个点的颜色设置不同,但是最终线段颜色是绿色glEnd();/因为glShadeModel(GL_FLAT)设置为最后一个顶点的颜色/决定整个图元的颜色。intCompCode(intx,inty)intcode=0 x00;/此处是二进制if(yymax)code=code|8;if(xxmax)code=code|2;if(x3)/total3,执行两次后total又加一done=1;flag=1;while(!done);if(accept)/线段位于窗口内或者线段剪裁过accept=l;LineGL(li);e

52、lseli.x0=0;li.y0=0;li.x1=0;li.y1=0;LineGL(li);returnaccept;voidmyDisplay()glClear(GL_COLOR_BUFFER_BIT);glColor3f(1.0f,0.0f,0.0f);glBegin(GL_LINE_LOOP);glVertex2f(100,100);glVertex2f(300,100);glVertex2f(300,300);glVertex2f(100,300);glEnd();LineGL(l1);LineGL(l2);LineGL(l3);glFlush();voidInit()glClearC

53、olor(0.0,0.0,0.0,0.0);glShadeModel(GL_FLAT);printf(PresskeyctoClip!nPresskeyrtoRestore!n);voidReshape(intw,inth)glViewport(0,0,(GLsizei)w,(GLsizei)h);glMatrixMode(GL_PROJECTION);glLoadIdentity();gluOrtho2D(0.0,(GLdouble)w,0.0,(GLdouble)h);/printf(#Reshapen);voidkeyboard(unsignedcharkey,intx,inty)swi

54、tch(key)casec:cohensutherlandlineclip(l1);cohensutherlandlineclip(l2);cohensutherlandlineclip(l3);glutPostRedisplay();break;caser:l1.x0=450;l1.y0=0;l1.x1=0;l1.y1=450;l2.x0=450;l2.y0=200;l2.x1=0;l2.y1=200;l3.x0=200;l3.y0=0;l3.x1=200;l3.y1=450;Init();glutPostRedisplay();break;casex:exit(0);break;defau

55、lt:break;intmain(intargc,char*argv)glutInit(&argc,argv);glutInitDisplayMode(GLUT_RGB|GLUT_SINGLE);glutInitWindowPosition(100,100);glutInitWindowSize(640,480);glutCreateWindow(Cohen-Sutherland);Init();glutDisplayFunc(myDisplay);glutReshapeFunc(Reshape);glutKeyboardFunc(&keyboard);/按下键盘后会调用该函数,键和鼠标点击位

56、置作为变量传给keyboard函数glutMainLoop();return0;实验结果:Sutherland-Hodgman算法代码:/Sutherland-Hodgmantypedefstructdoublex,y;vec_t,*vec;inlinedoubledot(veca,vecb)returna-x*b-x+a-y*b-y;inlinedoublecross(veca,vecb)returna-x*b-y-a-y*b-x;inlinevecvsub(veca,vecb,vecres)res-x=a-x-b-x;res-y=a-y-b-y;returnres;intleft_of(v

57、eca,vecb,vecc)vec_ttmp1,tmp2;doublex;vsub(b,a,&tmp1);vsub(c,b,&tmp2);x=cross(&tmp1,&tmp2);returnx0;intline_sect(vecx0,vecx1,vecy0,vecy1,vecres)vec_tdx,dy,d;vsub(x1,x0,&dx);vsub(y1,y0,&dy);vsub(x0,y0,&d);doubledyx=cross(&dy,&dx);if(!dyx)return0;dyx=cross(&d,&dx)/dyx;if(dyx=1)return0;res-x=y0-x+dyx*dy

58、.x;res-y=y0-y+dyx*dy.y;return1;typedefstructintlen,alloc;vecv;poly_t,*poly;/activeedgetablepolypoly_new()return(poly)calloc(1,sizeof(poly_t);voidpoly_free(polyp)free(p-v);free(p);voidpoly_append(polyp,vecv)if(p-len=p-alloc)p-alloc*=2;if(!p-alloc)p-alloc=4;p-v=(vec)realloc(p-v,sizeof(vec_t)*p-alloc);

59、p-vp-len+=*v;intpoly_winding(polyp)returnleft_of(p-v,p-v+1,p-v+2);voidpoly_edge_clip(polysub,vecx0,vecx1,intleft,polyres)inti,side0,side1;vec_ttmp;vecv0=sub-v+sub-len-1,v1;res-len=0;side0=left_of(x0,x1,v0);if(side0!=-left)poly_append(res,v0);for(i=0;ilen;i+)v1=sub-v+i;side1=left_of(x0,x1,v1);if(side0+side1=0&side0)/*lastpointandcurrentstraddletheedge*/if(line_sect(x0,x1,v0,v1,&tmp)poly_append(res,&tmp);if(i=sub-len-1)break;if(side1!=-left)poly_append(res,v1);v0=v1;side0=side1;polypoly_clip(polysub,polyclip)inti;polyp1=poly_new(),p2=poly_n

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论