计算机图形学OpenGL(第三版)第二章课件.ppt

上传人:小飞机 文档编号:1785480 上传时间:2022-12-18 格式:PPT 页数:48 大小:506KB
返回 下载 相关 举报
计算机图形学OpenGL(第三版)第二章课件.ppt_第1页
第1页 / 共48页
计算机图形学OpenGL(第三版)第二章课件.ppt_第2页
第2页 / 共48页
计算机图形学OpenGL(第三版)第二章课件.ppt_第3页
第3页 / 共48页
计算机图形学OpenGL(第三版)第二章课件.ppt_第4页
第4页 / 共48页
计算机图形学OpenGL(第三版)第二章课件.ppt_第5页
第5页 / 共48页
点击查看更多>>
资源描述

《计算机图形学OpenGL(第三版)第二章课件.ppt》由会员分享,可在线阅读,更多相关《计算机图形学OpenGL(第三版)第二章课件.ppt(48页珍藏版)》请在三一办公上搜索。

1、1,本章内容,编写图形程序学习OpenGL程序的基本组成开发绘制点、直线、折线和多边形的基本图形工具学会用鼠标和键盘控制程序,2,2.0 vc opengl 编程 指导例子,熟悉代码,多次练习见图形学第二课opengl-console.doc,创建一个控制台的应用程序,本书采用的编程方式见图形学第二课opengl-nehe-win.doc,创建一个win32的应用程序,nehe教程(共48课)采用的编程方式见图形学第三课opengl-nehe-mfc.doc,创建一个mfc的应用程序,本人推荐采用的编程方式,需要学习vc和mfc。,3,2.1 生成图像初步,通过练习(编写和测试各种不同图形的程

2、序)可以很快掌握计算机图形学。先从简单的任务开始,一旦掌握,就试着变变花样,看看有哪些变化,试着进一步绘制更复杂的场景。最好的学习办法是认真、仔细地学习每行代码或等式。当你这么做时,就能理解每个新概念。每个图形程序都以一些初始化工作为开始,由此建立程序所需要的显示模型和坐标系。,4,2.1 生成图像初步,初始化时,将显示器设置为“图形模式”,并且建立了坐标系,坐标x和y以像素为单位,x向右递增,y向下递增。,5,2.1.1 设备无关的编程 和OpenGL,OpenGL程序可以在不同的图形环境里编译和运行,即它是与设备无关的编程。OpenGL是一个开源图形库,可在http:/www.opengl

3、.org下载。OpenGL常被称为应用程序接口(API)。这个接口是程序员可以调用的例程,先从OpenGL绘制简单的二维物体开始,然后学习绘制三维图形。,6,2.1.2 窗口的编程,事件驱动编程:事件包括单击鼠标,按下键盘上的按键,或者重新调整窗口的大小。程序员将程序组织成回调函数的集合,这些回调函数一有事件发生就执行。即什么也不做,等待事件发生,事件发生后再做指定的事。OpenGL有一个GLUT库,它用来打开窗口,管理菜单和处理事件等。注册回调函数:有一种方法将每种类型的事件与要求的回调函数关联起来,这个方法称之为注册回调函数。程序中用到的每一个事件类型都必须用回调函数注册,该回调函数的名字

4、和定义由程序员选择。,7,2.1.2 窗口的编程,下面是使用GLUT库,名为myMouse的回调函数例子,它方便地注册了与鼠标关联的事件: glutMouseFunc(myMouse); glutMouseFunc是GLUT库的固有函数,但是回调函数myMouse是程序员定义的,并由程序员编写代码,处理每个可能感兴趣的鼠标动作。 4种主要的OpenGL库:1)基本GL库,OpenGL库的基础。它提供OpenGL的基本函数。每个OpenGL函数都以字符GL开头。,8,2.1.2 窗口的编程,2)GLUT库:GL实用工具包。它用来打开窗口,开发和管理菜单,以及管理事件等。3)GLU库:GL实用库,

5、它提供高级例程,处理矩阵操作和绘制二次曲面如球和圆柱体;4)GLUI库:用户接口库,提供控制工具和菜单。glutDisplayFunc(myDisplay):重绘窗口调用myDisplay回调函数;glutReshapeFun(myReshape):对屏幕窗口的形状进行调整;,void main()glutDisplayFunc(myDisplay); / 注册重绘函数glutReshapeFunc(myReshape); / 注册改变窗口形状函数glutMouseFunc(myMouse); / 注册鼠标动作函数glutMotionFunc(myMouse); / 注册鼠标移动函数glutK

6、eyboardFunc(myKeyboard); / 注册键盘动作函数/可能初始化其他工作glutMainLoop(); / 进入主循环等待事件发生,10,2.1.3 如何打开一个窗口画图,glutInit:该函数初始化工具包glutDisplayMode(GLUT_SINGLE | GLUT_RGB): 分配单个显示缓存glutInitWindowSize(640,480): 该函数指定屏幕的初始尺寸,宽640像素,高480像素。glutCreateWindow(“my first attempt”):该函数打开并显示屏幕窗口吗,并显示标题。代码如下:,void main(int argc,

7、 char* argv)glutInit( / 打开屏幕窗口,/ 注册回调函数glutDisplayFunc(myDisplay);glutReshapeFunc(myReshape);glutMouseFunc(myMouse);glutKeyboardFunc(myKeyboard);myInit(); / 必要的其他初始化工作glutMainLoop(); / 进入循环,13,2.2 OpenGL的基本图形元素,屏幕坐标系:宽为640,高为640。x坐标从左边界0增加到右边界639,y坐标从0增加到上边的479。,绘制三个点:glBegin(GL_POINTS);glVertex2i(1

8、00, 50);glVertex2i(100, 130);glVertex2i(150, 130);glEnd();或者用浮点值代替整数值:glBegin(GL_POINTS);glVertex2d(100.0, 50.0);glVertex2d(100.0, 130.0);glVertex2d(150.0, 130.0);glEnd();,OpenGL数据类型:命令后缀和参数数据类型OpenGL状态:OpenGL是由许多状态变量组成的状态机,这些状态包括点的大小、绘图的颜色额屏幕窗口大小等,点的大小可以用glPointSize()来设置,画图的颜色用这条语句设置: glColor3f(red

9、,green,blue);坐标系的建立:,void myInit(void)glMatrixMode(GL_PROJECTION);glLoadIdentity();gluOrtho2D(0, 640.0, 0, 480.0);myInit设置坐标系,设置透视投影变换。gluOrtho2D设置正交投影。组合在一起:建立起一个完整的OpenGL程序glFlush()函数保证所有的数据被完全处理并显示。,17,2.2.1 几个点丛绘制的例子,点丛是由大量点组成的某种图案。下面有几个点丛例子。,例子2.2.1 北斗星群 见计算机图形学课件2016计算机图形学(Opengl版第三版)书源代码word版

10、2.2.1-threeDots.doc例子2.2.2 Sierpinski(塞平斯基)垫片见计算机图形学课件2016计算机图形学(Opengl版第三版)书源代码word版2.2.1-threeDots.doc算法如下:第k个点表示为P(k)=(x(k),y(k),每一个点都依赖于前一个点P(k-1),过程如下:(1)选择三个固定的点T0,T1,T2,构成一个三角形,称为每个Sierpinski垫片的父三角形;(2)随机选择父三角形顶点T0,T1,T2中的一点作为要绘制的初始点P0。 迭代下面的(3)(5)步,直到图案填充完毕。(3)随机选择T0,T1,T2中的一点,称为T。(4)构造下一个点P

11、(k),作为T和前一个已建好的点P(k-1)之间的之间点,即P(k)=(P(k-1)+T)/2(5)用drawDot()绘制P(k)。,例子2.2.2 Sierpinski(塞平斯基)垫片/初始值P(0),在for循环外面GLintPoint point = Tindex; / 初始值drawDot(point.x, point.y); / 画初始点for(int i = 0; i 1000; i+) /画1000点index = rand()%3;/P(k)=(P(k-1)+T)/2point.x = (point.x + Tindex.x) / 2;point.y = (point.y +

12、 Tindex.y) / 2;drawDot(point.x,point.y);,例子2.2.3 用点集绘制函数 见计算机图形学课件2016计算机图形学(Opengl版第三版)书源代码word版2.2.1-threeDots.doc绘制某个数学函数f(x),当x在04变化时的曲线。当绘制曲线时,因为04之间的x值位于屏幕窗口左下角的前4个像素上,而且f(.)的负值位于窗口的下面,根本看不到。需要进行平移和缩放使曲线正好出现在合适的屏幕窗口。将世界坐标系转换为窗口坐标系。x方向缩放:假定屏幕窗口为screenWidth,单位为像素,现在x的范围为04,故sx = x * screenWidth

13、/4.0;y方向缩放:假定屏幕窗口为screenHeight,单位为像素,f(x) 的 取值在1.0 和 1.0之间,缩放screenHeight / 2 ,平移为 screenHeight / 2,sy = (y + 1.0) * screenHeight / 2.0;sx,sy为屏幕坐标,x,y为窗口坐标;转换方程为: sx= A * x + B sy =C * y + D,const int screenWidth = 640; / width of screen window in pixelsconst int screenHeight = 480; / height of scre

14、en window in pixelsGLdouble A, B, C, D; / values used for scaling and shiftingvoid myInit(void)glClearColor(1.0,1.0,1.0,0.0); / background color is whiteglColor3f(0.0f, 0.0f, 0.0f); / drawing color is blackglPointSize(2.0); / a dot is 2 by 2 pixelsglMatrixMode(GL_PROJECTION); / set camera shapeglLoa

15、dIdentity();gluOrtho2D(0.0, (GLdouble)screenWidth, 0.0, (GLdouble)screenHeight);A = screenWidth / 4.0; / x方向的缩放量AB = 0.0; /x方向的平移量BC = D = screenHeight / 2.0;/ y方向的缩放量C和平移量Dvoid myDisplay(void)glClear(GL_COLOR_BUFFER_BIT); / clear the screenglBegin(GL_POINTS);for(GLdouble x = 0; x 4.0 ; x += 0.005)G

16、ldouble func = exp(-x) * cos(2 * 3.14159265 * x);/sx= A * x + B, sy =C * y + DglVertex2d(A * x + B, C * func + D);glEnd();glFlush(); / send all output to display,例子2.2.3 用点集绘制函数 见计算机图形学课件2016计算机图形学(Opengl版第三版)书源代码word版2.2.1-threeDots.doc f(x)=sin(x),f(x)=sin(2x),x从-到,y从-1到1A = screenWidth / 6.28;/ x

17、方向的缩放量A,屏幕宽度/x方向的变化范围 B = screenWidth/2.0; /x方向的平移量B,屏幕宽度的一半 C = screenHeight / 2.0;/ y方向的缩放量C,屏幕高度/y方向的变化范围 D = screenHeight / 2.0;/ y方向的平移量D,屏幕的高度的一半for(GLdouble x = -3.14; x 3.14 ; x += 0.005)Gldouble func = sin(x);Gldouble func 1= sin(2x);/sx= A * x + B, sy =C * y + DglVertex2d(A * x + B, C * fu

18、nc + D);glVertex2d(A * x + B, C * func 1+ D);,23,2.3 OpenGL中的直线绘制,绘制线段glBegin(GL_LINES); / use constant GL_LINES here glVertex2i(40, 100); glVertex2i(202, 96);glEnd();或者编写一个函数void drawLineInt(GLint x1, GLint y1, GLint x2, GLint y2)glBegin(GL_LINES);glVertex2i(x1, y1);glVertex2i(x2, y2);glEnd();,2.3.

19、1 绘制折线和多边形折线就是一系列头尾相连的线段的集合,也称为线带。glBegin(GL_LINE_STRIP); / draw an open polyline glVertex2i(20,10); glVertex2i(50,10); glVertex2i(20,80); glVertex2i(50,80);glEnd();glFlush();绘制多边形,只需要用GL_LINE_LOOP替换GL_LINE_STRIP 即可,即是闭合的。 f(x) = 300 - 100 cos(2p x/100) + 30 cos(4p x/100) + 6 cos(6p x/100)glBegin(GL

20、_LINE_STRIP);for(x = 0; x = 300; x += 3)glVertex2d(A * x + B, C * f(x) + D);glEnd();glFlush;,例子2.3.2 绘制存储在文件中的折线 见计算机图形学课件2016计算机图形学(Opengl版第三版)书源代码word版2.2.1-threeDots.doc,文件dino.dat:21 /文件中折线的数量4 / 第一条折线的点数169 118 / /第一条折线的第一个点174 120 /179 124178 1265 / 第二条折线的点数298 86 / 第二条折线的第一个点304 92310 104314

21、114314 1192932 43510 439. . . 等等,例子2.3.3 参数化图形 void hardwiredHouse(void) glBegin(GL_LINE_LOOP);/ 绘制房子外形glVertex2i(40, 40); glVertex2i(40, 90); glVertex2i(70, 120); glVertex2i(100, 90); glVertex2i(100, 40);glEnd();glBegin(GL_LINE_STRIP); /绘制烟囱glVertex2i(50, 100);glVertex2i(50, 120);glVertex2i(60, 120

22、); glVertex2i(60, 110);glEnd();. . . / 绘制门. . . / 绘制窗户void parameterizedHouse(GLintPoint peak, GLint width, GLint height)/ 房子的顶点由peak给定,房子的大小由width和height给定glBegin(GL_LINE_LOOP);glVertex2i(peak.x, peak.y); / 绘制房子外形glVertex2i(peak.x + width / 2, peak.y - 3 * height /8);glVertex2i(peak.x + width / 2 p

23、eak.y - height);glVertex2i(peak.x - width / 2, peak.y - height);glVertex2i(peak.x - width / 2, peak.y - 3 * height /8);glEnd();draw chimney in the same fashiondraw the doordraw the window第一个方法将由几条折线组成的简易房子的每个端点位置被强制写入代码中,而第二种方法则是利用参数来绘制,用参数指定房屋顶点的位置和房子的宽度和高度,比较灵活。,例子2.3.4 构造一个折线绘图器 一些应用程序需要用一个列表存储折线

24、的顶点。这个列表可能是数组或者链表,可以采用类或者结构体保存数组,对于大量数据,c+ STL(标准模板库)容器可能是一个安全的数据结构。struct GLintPointGLint x,y;class GLintPointArrayconst int MAX_NUM = 100;public:int num;GLintPoint ptMAX_NUM;void drawPolyLine(GlintPointArray poly, int closed)glBegin(closed ? GL_LINE_LOOP : GL_LINE_STRIP);for(int i = 0; i poly.num;

25、 i+)glVertex2i(poly.pti.x, poly.pti.y);glEnd();glFlush();,2.3.2 使用moveTo()和lineTo()绘制线段 OpenGL绘制线段很容易。可以用一组命令GL_LINES,.,GL_END,也可以用drawLine()函数。moveTo和lineTo函数可以管理一个虚拟画笔,它的位置叫当前位置或CP(current position)。CP像一个OpenGL的状态变量,如画画的颜色和背景一样,它在程序的控制之下。moveTo(x,y)/设定CP到(x,y)lineTo(x,y)/在CP和(x,y)之间画一条线,更新CP。使用下面的

26、代码,容易绘制基于点的列表(x0, y0), (x1, y1), . , (xn-1, yn-1)的折线。moveto(x0, y0);for(int i = 1; i n; i+)lineto(xi, yi);可以直接在OpenGL建立moveTo和lineTo这两个函数,并保持CP,moveTo和lineTo函数实现为: GLintPoint CP; / 全局位置变量/void moveto(GLint x, GLint y)CP.x = x; CP.y = y; / 更新CP/void lineto(GLint x, GLint y)glBegin(GL_LINES); / 绘制曲线gl

27、Vertex2i(CP.x, CP.y);glVertex2i(x, y);glEnd();glFlush();CP.x = x; CP.y = y; / 更新 CP,2.3.3 绘制边校正的矩形 多边形的特例是边校正的矩形,因为它的边与坐标轴平行,OpenGL提供了一个现成的函数glRecti()。 glRecti(GLint x1, GLint y1, GLint x2, GLint y2); / 以对角点(x1, y1) and (x2, y2)绘制矩形该函数基于两个给定点绘制边校正矩形,并以当前颜色填充矩形。glClearColor(1.0,1.0,1.0,0.0); / 白色背景gl

28、Clear(GL_COLOR_BUFFER_BIT); / 清除glColor3f(0.6,0.6,0.6); / 浅灰glRecti(20,20,100,70);glColor3f(0.2,0.2,0.2); / 深灰glRecti(70, 50, 150, 130);glFlush();a)随机生成的矩形雪花b)不同灰度等级的棋盘void drawFlurry(int num, int numColors, int Width, int Height)/ draw num random rectangles in a Width by Height rectanglefor (int i

29、= 0; i num; i+)GLint x1 = random(Width); / place corner randomlyGLint y1 = random(Height);GLint x2 = random(Width); / pick the size so it fitsGLint y2 = random(Height);GLfloat lev = random(10)/10.0; / random value, in range 0 to 1glColor3f(lev,lev,lev); / set the gray levelglRecti(x1, y1, x2, y2); /

30、 draw the rectangleglFlush();,练习练习2.3.1 画棋盘写出例程checkerboard(int size),这64个正方形的边长都设为size个像素。为这些正方形选择两种好看的颜色。解:第ij个正方形的左下角位于(i*size, j*size)处( i =0,.,7 ; j = 0.7). 使用下面的代码,可以将颜色在(r1, g1, b1) 和(r2, g2, b2) 间变换。if(i + j)%2 =0) / 如果i + j 是偶数 glColor3f( r1, g1, b1);else glColor3f(r2, g2, b2);,练习练习2.3.1 画棋

31、盘写出例程checkerboard(int size),这64个正方形的边长都设为size个像素。为这些正方形选择两种好看的颜色。解:第ij个正方形的左下角位于(i*size, j*size)处( i =0,.,7 ; j = 0.7). 使用下面的代码,可以将颜色在(r1, g1, b1) 和(r2, g2, b2) 间变换。if(i + j)%2 =0) / 如果i + j 是偶数 glColor3f( r1, g1, b1);else glColor3f(r2, g2, b2);,2.3.5 填充多边形 OpenGL支持用图案或色彩填充一般的多边形,那么这个多边形是凸的。 凸多边形:如果

32、多边形中任意两点的连线完全位于多边形内部,那么这个多边形是凸的。要绘制凸多边形,使用顶点列表,把顶点列表放在glBegin(GL_POLYGON)和glEnd()之间。可以用点画线图案填充多边形,会把图像贴在多边形上,作为应用纹理的。C,E,F是凸的多边形。,2.3.6 OpenGL中的其他图形元素 除了点、线和多边形,OpenGL还支持绘制五种其他元素,/ 使用鼠标指定一个矩形static GLintPoint corner2;static int numCorners = 0; / initial value is 0if(button = GLUT_LEFT_BUTTON ,2.4 与鼠

33、标和键盘的交互当用户按下或释放鼠标按钮、移动鼠标或者松开或按下键盘时,就会产生一个相关事件。程序员可以用每类事件注册一个回调函数 glutMouseFunc(myMouse) :利用按下或者鼠标按钮时发生事件来注册 myMouse() glutMotionFunc(myMovedMouse) 利用鼠标移动注册函数 myMovedMouse() glutKeyboardFunc(myKeyboard) 利用按下或者松开键盘按键时注册函数 myKeyBoard() 2.4.1 用鼠标交互注册一个函数到glutMouseFunc(myMouse),myMouse()的名字可以任意,有四个参数:voi

34、d myMouse(int button, int state, int x, int y);button的值如下:GLUT_LEFT_BUTTON, GLUT_MIDDLE_BUTTON, 或 GLUT_RIGHT_BUTTON;而state的值可能为:GLUT_UP 或GLUT_DOWN。x和y为事件发生时鼠标的位置。,2.4.1 用鼠标绘制点当用户每次按下鼠标时,就会在屏幕窗口上鼠标所在的位置绘制出一个点。由于鼠标位置的y值是距离屏幕顶端的像素值,故不在(x, y), 而是在 (x,screenHeight y)上绘制,其中screenHeight 为屏幕的高度。void myMouse

35、(int button, int state, int x, int y)if(button = GLUT_LEFT_BUTTON 2.4.2 用鼠标指定一个矩形想让用户画尺寸大小由鼠标输入的长方形。用户在两个点上单击鼠标,指定边校正矩形的两个角点,就可以画出矩形。用户右键点击鼠标即可清屏。,/ 使用鼠标指定一个矩形static GLintPoint corner2;static int numCorners = 0; / initial value is 0if(button = GLUT_LEFT_BUTTON ,2.4.3 用鼠标控制Sierpinski垫片使用户用鼠标指定初始三角形的三

36、个顶点,并置于数组corners中,代码为static GLintPoint corners3;static int numCorners = 0;if(button = GLUT_LEFT_BUTTON / back to 0 corners ,鼠标移动鼠标移动会产生一个鼠标事件:glutMotionFunc(myMovedMouse);注册函数myMovedMouse(int x, int y);有两个参数,即事件发生时鼠标所在的位置。glutPassiveMotionFunc(myPassiveMotion);这个函数是没有按下鼠标按钮的情况下,鼠标在窗口内移动时调用。该函数可以绘制并显

37、示橡皮矩形:随着用户移动鼠标,矩形将相应地变大或变小。下面的程序是用户单击鼠标建立矩形的一个角点,然后不按下鼠标时移动鼠标,调用myPassiveMotion(int x, int y),这决定了矩形的第二个角点。glutPostRedisplay()调用myDisplay()函数。 代码见见计算机图形学课件2016计算机图形学(Opengl版第三版)书源代码word版2.2.1-threeDots.doc,2.4.2 键盘交互按下键盘上的某个按键时就会产生一个键盘事件,并放入消息队列。回调函数myKeyboard()通过glutKeyboardFunc(myKeyboard)来注册这种事件,

38、该函数的原型为:void myKeyboard(unsigned int key, int x, int y); key 值就是键的ASCII 值, x 和y为鼠标所在的位置。实例代码为:void myKeyboard(unsigned char theKey, int mouseX, int mouseY)GLint x = mouseX;GLint y = screenHeight - mouseY; / 反转y的值switch(theKey)case p:drawDot(x, y); / draw a dot at the mouse positionbreak;case GLUT_KE

39、Y_LEFT: List+last.x = x; / add a pointList last.y = y;break;case E:exit(-1); /terminate the programdefault:break; / do nothing,41,2.5 程序中的菜单设计与使用,如果一个图形程序能够提供菜单功能,对用户来说,使用就比较方便了。建议使用vc。 设计代码和使用GLUT菜单 创建菜单使用void glutCreateMenu(),菜单项使用一个带参数的函数glutCreateMenu(ProcessMenuEvents)来定义,必须编写ProcessMenuEvents函

40、数。使用函数glutAddMenuEntry()可以在菜单中添加选项,一旦菜单设计好,可以用glutAttachMenu(GLUT_RIGHT_BUTTON)建立与鼠标按钮的联系。代码见书P69.,案例分析 为了巩固所学知识,最好的方式就是使用学过的知识,在最初的学习中更是如此,因为一开始学习计算机图形学,不了解程序的编写是必须克服的障碍。为了强调这一点,每章都有案例,其中介绍的编程项目不仅本身有趣,而且浓缩了该章中所提及的知识。 难易程度: I: 简单的练习,课堂即可完成。. II: 教难任务,可能需要几天才能完成。 III: 复杂任务,可能需要两周完成。案例2.1 伪随机点云(难度 II)

41、rand()函数不是随机产生的,而是通过一个很有规律的机制产生的:每个数ni 都是由它前一个数 ni-1,通过一个等式确定 : ni = (ni-1 * A + B) mod N 其中 A, B, 和 N 是适当选择的常数。 一组有效的值为: A =1103515245, B = 12345, 和 N = 32767. 这个数限制在 0 到 N-1. 散乱点图,调用rand(N),它会返回一个0,.,N-1之间的数。glBegin(GL_POINTS);for(int i = 0; i num; i+) / do it num timesglVertex2i(random(N), random

42、(N);glEnd();选择不同的A,B,N的值生成(x,y)对。,案例分析 案例2.2 迭代函数系统介绍(难度 II)绘制Sierpinski垫片时的操作就是迭代函数(IFS)的一个例子。许多计算机生成的有趣图形(如分形、Mandelbrot集合等)都是基于迭代函数变化生成的。如: f(.) = 2(.); 倍增器,倍增它的参数; f(.) = cos(.); f(.) = 4 (.) (1 - (.) f(.) = (.)2 + c IFS 产生的数字序列:d0d1 = f(d0)d2 = f(f(d0)d3 = f(f(f(d0)dk = fk(d0)dk = f(d(k-1)对于给定的

43、 d0 , k = 1,2,3,., .项目1:预报冰雹系列写一个程序,绘制上面公式对k所产生的数值序列。用户给出 1 到 4,000,000,000之间的初始值y0。 每个 yk 值被画成点图(k, yk)。,案例2.2 迭代函数项目2: 姜饼人这是混沌理论中的常见图形。 glLoadIdentity();glTranslatef(-30,-30,-90); glScaled(0.15, 0.15, 0.15);float x, y; static float old_x=115, old_y=121;static float R=40, S=3;glBegin(GL_POINTS);for

44、 (int i=0; i1000; i+)x = R*(1 + 2*S) - old_y + abs(int(old_x - S*R);/ The IFS for xy = old_x; old_x = x;old_y = y;glVertex2f(x,y);/ Output that magic vertexglEnd();glFlush(); 这里R=M=40,S=L=3,p_x=old_x, p_y=old_y, q_x=x, q_y=y;,案例2.3 黄金分割(难度 I)部分代码:1)phi0=1.0;for(i=0;i5000;i+) phi=sqrt(1+sqrt(phi0); p

45、hi0=phi;2)phi0=1.0;for(i=0;i5000;i+) phi=1.0+1.0/(1.0+phi0); phi0=phi;,案例2.4 如何创建和使用折线段文件(难度 I) 复杂图形恐龙dino.dat由一个很大的折线集合构成。折线数据一般都是存在一个文件里。(1)编写一个程序,可以从文件中读取折线数据并依次绘制每条折线。编写一个折线数据,将文件中的数据用你编写的程序绘制出来。设计你的程序,确保画折线时不需要每次都读取折线数据文件,可以用数组或链表存储折线数据;(2)扩展上面的程序,使其能够接受其他文件格式。例如程序可以接受差分编码的x和y坐标。(3)对前面的文件作修改,使文件中每条折线都和一个颜色值相关,使颜色值与折线包含点数的数值在一行上。(4)修改折线例程,使它在折线的点数为负数时绘制一个封闭多边形。,案例2.5 迷宫(难度 III) 绘制一个100行和150列的长方形迷宫,目标是从左边界的开口穿过迷宫到达右边界的开口。(1)生成并显示一个具有R行和C列的矩形迷宫;(2)找到并显示一条从迷宫起点通向终点的路径。怎样表示一个迷宫呢?一种方法是,对每个单元格都做出声明,无论其北墙完整还是其东墙完整,建议使用下面的数据结构: char northWallRC, eastWallRC;见书P79,48,

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 生活休闲 > 在线阅读


备案号:宁ICP备20000045号-2

经营许可证:宁B2-20210002

宁公网安备 64010402000987号