计算机图形学实验内容.doc_第1页
计算机图形学实验内容.doc_第2页
计算机图形学实验内容.doc_第3页
计算机图形学实验内容.doc_第4页
计算机图形学实验内容.doc_第5页
已阅读5页,还剩52页未读 继续免费阅读

下载本文档

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

文档简介

计算机图形学实验肖加清 实验一 图形学实验基础1、 实验目的(1) 掌握VC+绘图的一般步骤;(2) 掌握OpenGL软件包的安装方法;(3) 掌握OpenGL绘图的一般步骤;(4) 掌握OpenGL的主要功能与基本语法。二、实验内容1、VC+绘图实验(1)实验内容:以下是绘制金刚石图案。已给出VC+参考程序,但里面有部分错误,请改正,实现以下图案。N=3 N=4N=5N=10N=30N=50(2)参考程序/自定义的一个类/此代码可以放在视图类的实现文件(.cpp) 里class CP2 public:CP2();virtual CP2();CP2(double,double);double x;double y;CP2:CP2()this-x=0.0;this-y=0.0;CP2:CP2()CP2:CP2(double x0,double y0)this-x=x0;this-y=y0;/视图类的一个成员函数,这个成员函数可以放在OnDraw函数里调用。/在视图类的头文件(.h)里定义此函数void Diamond();/在视图类的实现文件(.cpp)里实现此函数void CTestView:Diamond()CP2 *P;int N;double R;R=300;N=10; P=new CP2N;CClientDC dc(this);CRect Rect;GetClientRect(&Rect); double theta;theta=2*PI/N;for(int i=0;iN;i+)Pi.x=R*cos(i*theta);Pi.y=R*sin(i*theta);for(i=0;i=N-2;i+)for(int j=i+1;j=N-1;j+) /其中ROUND函数需要自己实现,实现四舍五入的功能。dc.MoveTo(ROUND(Pi.x+Rect.right/2),ROUND(Pi.y+Rect.bottom/2); dc.LineTo(ROUND(Pj.x+Rect.right/2),ROUND(Pj.y+Rect.bottom/2);delete P;2、OpenGL绘图(1)以下是用OpenGL绘制茶壶的代码,请在OpenGL环境下运行,分析OpenGL程序的结构#include #include #include #include /定义输出窗口的大小#define WINDOW_HEIGHT 300#define WINDOW_WIDTH 500/用户初始化函数void myninit(void);/窗口大小变化时的回调函数void CALLBACK myReshape(GLsizei w,GLsizei h);/每帧OpenGL都会调用这个函数,应该把显示代码放在这个函数中void CALLBACK display(void);int window_width=WINDOW_WIDTH;int window_height=WINDOW_HEIGHT;/视点离物体的距离float distance=3.6f;/初始化,此时为空,可以在这里进行初始化操作void myinit(void)void CALLBACK display(void)/设置清屏的颜色,并清屏和深度缓冲glClearColor(0.0f,0.0f,0.0f,0.0f);glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);/设置成模型矩阵模式glMatrixMode(GL_MODELVIEW);/载入单位化矩阵glLoadIdentity();/坐标中心向Z轴平移-distance,这样使坐标中心位于视点前方glTranslatef(0.0,0.0,-distance);/在坐标中心显示一个茶壶auxWireTeapot(1.0);/等待现有的OpenGL命令执行完成glFlush();/交换前后缓冲区auxSwapBuffers();void CALLBACK myReshape(GLsizei w,GLsizei h)if(!h) return ;/这定视区glViewport(0,0,w,h);/设定透视方式glMatrixMode(GL_PROJECTION);glLoadIdentity();gluPerspective(60.0,1.0*(GLfloat)w/(GLfloat)h,1.0,30.0);window_width=w;window_height=h;/移近移远的回调函数void CALLBACK MoveNear(void)distance-=0.3f;void CALLBACK MoveFar(void)distance +=0.3f;/主函数int main(int argc,char *argv)/初始化OpenGL的显示方式auxInitDisplayMode(AUX_DOUBLE|AUX_RGB|AUX_DEPTH16);/设定OpenGL窗口位置和大小auxInitPosition(0,0,WINDOW_WIDTH,WINDOW_HEIGHT);/打开窗口auxInitWindow(OpenGL的一个简单的例子!);/调用初始化函数myinit();/设定窗口大小变化的回调函数auxReshapeFunc(myReshape);/设定移动视点的回调函数auxKeyFunc(A,MoveNear); /按A键变大auxKeyFunc(a,MoveFar); /按a键变小/使display函数一直被调用auxIdleFunc(display);/开始OpenGL的循环auxMainLoop(display);/结束程序return (0);其运行结果如图所示:(2)OPENGL绘制矩形的简单例子参考程序:#include void Initial(void)glClearColor(1.0f, 1.0f, 1.0f, 1.0f); /设置窗口背景颜色为白色glMatrixMode(GL_PROJECTION); /设置投影参数gluOrtho2D(0.0,200.0,0.0,150.0);void Display(void)glClear(GL_COLOR_BUFFER_BIT); /用当前背景色填充窗口glColor3f(1.0f, 0.0f, 0.0f); /设置当前的绘图颜色为红色glRectf(50.0f, 100.0f, 150.0f, 50.0f); /绘制一个矩形glFlush(); /处理所有的OpenGL程序int main(int argc, char* argv)glutInit(&argc, argv);glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB); /初始化窗口的显示模式glutInitWindowSize(400,300); /设置窗口的尺寸glutInitWindowPosition(100,120); /设置窗口的位置glutCreateWindow(矩形); /创建一个名为矩形的窗口glutDisplayFunc(Display); /设置当前窗口的显示回调函数Initial(); /完成窗口初始化glutMainLoop(); /启动主GLUT事件处理循环return 0;三、实验结果分析 实验二 直线生成算法与用户接口与交互式技术一、实验目的1、 掌握直线生成算法 (1) DDA算法 (2)Bresenham算法2、 掌握交互式技术 (1)鼠标 (2)键盘数字键、字母键、功能键和特殊键3、实现拾取操作二、实验内容1、以下给出了DDA算法的C+代码,请参考用Visual C+实现Bresenham算法。实现DDA画线程序实验步骤: 1 建立一个DDALine的工程文件; 2 添加ddaline()成员函数 方法:在工作区中选择CLASSVIEW类窗口,右击CDDAlineView类,选择“add member function”,定义如下的成员函数: void ddaline(CDC* pDC,int x0,int y0,int x1,int y1,COLORREF color); 3 编写自定义的成员函数ddaline()程序 void CDDALineView:ddaline(CDC* pDC, int x0, int y0, int x1, int y1, COLORREF color) int length,i; float x,y,dx,dy; length=abs(x1-x0); if (abs(y1-y0)length) length=abs(y1-y0); dx=(x1-x0)/length; dy=(y1-y0)/length; x=x0+0.5;y=y0+0.5; for (i=1;iSetPixel(int)x,(int)y,color); x=x+dx;y=y+dy; 4编写OnDraw()函数 void CDDALineView:OnDraw(CDC* pDC) CDDALineDoc* pDoc = GetDocument(); ASSERT_VALID(pDoc); / TODO: add draw code for native data here ddaline(pDC,100,100,400,100,RGB(255,0,0); ddaline(pDC,400,100,400,400,RGB(0,255,0); ddaline(pDC,400,400,100,400,RGB(0,0,255); ddaline(pDC,100,400,100,100,RGB(255,255,0); ddaline(pDC,100,100,400,400,RGB(255,0,255); ddaline(pDC,100,400,400,100,RGB(0,255,255); 5编译、调试和运行程序,查看程序结果。2、以下是利于鼠标和字母键实现用户接口与交互式技术,请参照利用特殊键实现,写出其代码。(1)OPENGL中利用鼠标实现橡皮筋技术的例子#include int iPointNum = 0; /已确定点的数目int x1=0,x2=0,y1=0,y2=0; /确定的点坐标int winWidth = 400, winHeight = 300; /窗口的宽度和高度void Initial(void)glClearColor(1.0f, 1.0f, 1.0f, 1.0f); void ChangeSize(int w, int h)winWidth = w;winHeight = h;glViewport(0, 0, w, h); /指定窗口显示区域glMatrixMode(GL_PROJECTION); /设置投影参数glLoadIdentity();gluOrtho2D(0.0,winWidth,0.0,winHeight);void Display(void)glClear(GL_COLOR_BUFFER_BIT);glColor3f(1.0f, 0.0f, 0.0f); if(iPointNum = 1)glBegin(GL_LINES); /绘制直线段glVertex2i(x1,y1);glVertex2i(x2,y2);glEnd();glutSwapBuffers(); /交换缓冲区void MousePlot(GLint button, GLint action, GLint xMouse, GLint yMouse)if(button = GLUT_LEFT_BUTTON & action = GLUT_DOWN)if(iPointNum = 0 | iPointNum = 2)iPointNum = 1;x1 = xMouse;y1 = winHeight - yMouse;else iPointNum = 2;x2 = xMouse;y2 = winHeight - yMouse;glutPostRedisplay(); /指定窗口重新绘制if(button = GLUT_RIGHT_BUTTON & action = GLUT_DOWN)iPointNum = 0;glutPostRedisplay();void PassiveMouseMove (GLint xMouse, GLint yMouse)if(iPointNum = 1)x2 = xMouse;y2 = winHeight - yMouse;glutPostRedisplay();int main(int argc, char* argv)glutInit(&argc, argv);glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB); /使用双缓存及RGB模型glutInitWindowSize(400,300); glutInitWindowPosition(100,100);glutCreateWindow(橡皮筋技术); glutDisplayFunc(Display); glutReshapeFunc(ChangeSize); /指定窗口在整形回调函数glutMouseFunc(MousePlot); /指定鼠标响应函数glutPassiveMotionFunc(PassiveMouseMove); /指定鼠标移动响应函数Initial(); glutMainLoop(); return 0;(2)OPENGL中利用键盘实现橡皮筋技术的例子#include int iPointNum = 0; /已确定点的数目int x1=0,x2=0,y1=0,y2=0; /确定的点坐标int winWidth = 400, winHeight = 300; /窗口的宽度和高度void Initial(void)glClearColor(1.0f, 1.0f, 1.0f, 1.0f); void ChangeSize(int w, int h)winWidth = w;winHeight = h;glViewport(0, 0, w, h); /指定窗口显示区域glMatrixMode(GL_PROJECTION); /设置投影参数glLoadIdentity();gluOrtho2D(0.0,winWidth,0.0,winHeight);void Display(void)glClear(GL_COLOR_BUFFER_BIT);glColor3f(1.0f, 0.0f, 0.0f); if(iPointNum = 1)glBegin(GL_LINES); /绘制直线段glVertex2i(x1,y1);glVertex2i(x2,y2);glEnd();glutSwapBuffers(); /交换缓冲区void PassiveMouseMove (GLint xMouse, GLint yMouse)if(iPointNum = 1)x2 = xMouse;y2 = winHeight - yMouse;glutPostRedisplay();void Key(unsigned char key, int x, int y)switch(key)case p:if(iPointNum = 0 | iPointNum = 2)iPointNum = 1;x1 = x;y1 = winHeight - y;elseiPointNum = 2;x2 = x;y2 = winHeight - y;glutPostRedisplay();break;default: break;int main(int argc, char* argv)glutInit(&argc, argv);glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB); /使用双缓存及RGB模型glutInitWindowSize(400,300); glutInitWindowPosition(100,100);glutCreateWindow(橡皮筋技术); glutDisplayFunc(Display); glutReshapeFunc(ChangeSize); /指定窗口在整形回调函数glutKeyboardFunc(Key); /指定键盘响应函数glutPassiveMotionFunc(PassiveMouseMove); /指定鼠标移动响应函数Initial(); glutMainLoop(); return 0;3、以下OPENGL实现拾取操作的例子,请掌握实现拾取操作的方法。#include #include stdio.hconst GLint pickSize = 32;int winWidth = 400, winHeight = 300;void Initial(void)glClearColor(1.0f, 1.0f, 1.0f, 1.0f); void DrawRect(GLenum mode)if(mode = GL_SELECT) glPushName(1); /压入堆栈glColor3f(1.0f,0.0f,0.0f);glRectf(60.0f,50.0f,150.0f,150.0f);if(mode = GL_SELECT) glPushName(2); /压入堆栈glColor3f(0.0f,1.0f,0.0f);glRectf(230.0f,50.0f,330.0f,150.0f);if(mode = GL_SELECT) glPushName(3); /压入堆栈glColor3f(0.0f,0.0f,1.0f);glRectf(140.0f,140.0f,240.0f,240.0f);void ProcessPicks(GLint nPicks, GLuint pickBuffer)GLint i;GLuint name, *ptr;printf(选中的数目为%d个n,nPicks);ptr=pickBuffer;for(i=0;inPicks; i+)name=*ptr; /选中图元在堆栈中的位置ptr+=3; /跳过名字和深度信息ptr+=name-1; /根据位置信息获得选中的图元名字if(*ptr=1) printf(你选择了红色图元n);if(*ptr=2) printf(你选择了绿色图元n);if(*ptr=3) printf(你选择了蓝色图元n);ptr+;printf(nn);void ChangeSize(int w, int h)winWidth = w;winHeight = h;glViewport(0, 0, w, h);glMatrixMode(GL_PROJECTION); glLoadIdentity();gluOrtho2D(0.0,winWidth,0.0,winHeight);void Display(void)glClear(GL_COLOR_BUFFER_BIT);DrawRect(GL_RENDER);glFlush();void MousePlot(GLint button, GLint action, GLint xMouse, GLint yMouse)GLuint pickBufferpickSize;GLint nPicks, vp4;if(button = GLUT_LEFT_BUTTON & action = GLUT_DOWN)glSelectBuffer(pickSize,pickBuffer); /设置选择缓冲区glRenderMode(GL_SELECT); /激活选择模式glInitNames(); /初始化名字堆栈glMatrixMode(GL_PROJECTION);glPushMatrix();glLoadIdentity();glGetIntegerv(GL_VIEWPORT, vp);/定义一个1010的选择区域gluPickMatrix(GLdouble(xMouse), GLdouble(vp3-yMouse),10.0,10.0,vp);gluOrtho2D(0.0,winWidth,0.0,winHeight);DrawRect(GL_SELECT);/恢复投影变换glMatrixMode(GL_PROJECTION);glPopMatrix();glFlush();/获得选择集并输出nPicks = glRenderMode(GL_RENDER);ProcessPicks(nPicks, pickBuffer);glutPostRedisplay();int main(int argc, char* argv)glutInit(&argc, argv);glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB); glutInitWindowSize(400,300); glutInitWindowPosition(100,100); glutCreateWindow(拾取操作); glutDisplayFunc(Display);glutReshapeFunc(ChangeSize);glutMouseFunc(MousePlot);Initial(); glutMainLoop(); return 0;三、实验结果分析 实验三 圆和椭圆及其它基本图形的生成算法一、实验目的(1)掌握和利用VC+实现Bresenham算法;(2)掌握利用OPENGL绘制简单多面体、二次及三次曲线的方法;(3)掌握利用OPENGL层次建模的方法。二、实验内容(1)用Visual C+实现圆和椭圆的Bresenham算法;(2)利用OPENGL绘制简单多面体、二次及三次曲线;(3)利用OPENGL层次建模1、Visual C+ 实现圆的Bresenham生成算法的参考程序如下,请在MFC环境下实现程序实现步骤: (1) 建立MidPointCircle工程文件; (2) 右击CMidPointCircleView类,建立成员函数 void MidpointCircle(CDC *pDC,int x0, int y0, int r, COLORREF color) int CirPot(CDC *pDC,int x0, int y0, int x, int y, COLORREF color) (3) 编写成员函数代码,程序如下: void CMidPointCircleView:MidpointCircle(CDC *pDC,int x0, int y0, int r, COLORREF color) int x,y; float d; x=0;y=r;d=1.25-r; CirPot(pDC,x0,y0,x,y,color); while (x=y) if(dSetPixel(x0+x),(y0+y),color); pDC-SetPixel(x0+y),(y0+x),color); pDC-SetPixel(x0+y),(y0-x),color); pDC-SetPixel(x0+x),(y0-y),color); pDC-SetPixel(x0-x),(y0-y),color); pDC-SetPixel(x0-y),(y0-x),color); pDC-SetPixel(x0-y),(y0+x),color); pDC-SetPixel(x0-x),(y0+y),color); return 0; (4)编写OnDraw(CDC* pDC)函数,程序如下: void CMidPointCircleView:OnDraw(CDC* pDC) CMidPointCircleDoc* pDoc = GetDocument(); ASSERT_VALID(pDoc); / TODO: add draw code for native data here MidpointCircle(pDC,100, 100, 10, RGB(255,0,0); MidpointCircle(pDC,500, 300, 60, RGB(255,255,0); (6) 编译、运行程序,查看结果。 2、编写画椭圆法的扫描转换程序,请在MFC 环境下实现程序实现步骤: (1) 建立MidPointEllise工程文件; (2)右击CMidPointElliseView类,建立成员函数 void MidpointEllise(CDC *pDC, int x0, int y0, int a, int b, COLORREF color) (3) 编写成员函数代码,程序如下: void CMidPointEllipseView:MidpointEllise(CDC *pDC, int x0, int y0, int a, int b, COLORREF color) int x,y; float d1,d2; x=0;y=b; d1=b*b+a*a*(-b+0.25); pDC-SetPixel(x+x0,y+y0,color); while (b*b*(x+1)a*a*(y-0.5) if (d1SetPixel(x0+x,y0+y,color); pDC-SetPixel(x0+x,y0-y,color); pDC-SetPixel(x0-x,y0+y,color); pDC-SetPixel(x0-x,y0-y,color); / 上半部分 d2=(b*(x+0.5)*(b*(x+0.5)+(a*(y-1)*(a*(y-1)-(a*b)*(a*b); while (y0) if (d2SetPixel(x0+x,y0+y,color); pDC-SetPixel(x0+x,y0-y,color); pDC-SetPixel(x0-x,y0+y,color); pDC-SetPixel(x0-x,y0-y,color); /下半部分 (4) 编写OnDraw()函数 void CMidPointEllipseView:OnDraw(CDC* pDC) CMidPointEllipseDoc* pDoc = GetDocument(); ASSERT_VALID(pDoc); / TODO: add draw code for native data here MidpointEllise(pDC, 300, 200, 50, 20, RGB(255,0,0); (5) 编译、运行程序。3、用OPENGL绘制简单多面体、二次及三次曲线的例子#include static GLsizei iMode = 1;static GLfloat xRot = 0.0f; /x方向旋转参数static GLfloat yRot = 0.0f; /y方向旋转参数GLUquadricObj *obj; /二次曲面对象void Initial(void)glClearColor(1.0f, 1.0f, 1.0f, 1.0f); glColor3f(0.0f, 0.0f, 0.0f);obj = gluNewQuadric( );gluQuadricDrawStyle(obj, GLU_LINE); /以线框方式绘制二次曲面对象void ChangeSize(int w, int h)glViewport(0, 0, w, h);glMatrixMode(GL_PROJECTION);glLoadIdentity();gluOrtho2D (-1.5f, 1.5f, -1.5f, 1.5f);void Display(void)glClear(GL_COLOR_BUFFER_BIT); glMatrixMode(GL_MODELVIEW);glLoadIdentity();glRotatef(xRot, 1.0f, 0.0f, 0.0f); /旋转图形glRotatef(yRot, 0.0f, 1.0f, 0.0f); /旋转图形/指定需要绘制的图元switch(iMode)case 1:glutWireTetrahedron();break;case 2:glutSolidTetrahedron();break;case 3:glutWireOctahedron();break;case 4:glutSolidOctahedron();break;case 5:glutWireSphere(1.0f,15,15); break;case 6:glutSolidSphere(1.0f,15,15); break;case 7:glutWireTeapot(1.0f); break;case 8:glutSolidTeapot(1.0f); break;case 9:gluSphere(obj, 1.0f, 15, 15); break;case 10:gluCylinder(obj,1.0f,0.0f,1.0f,15,15);break;case 11:gluPartialDisk(obj,0.3f,0.8f,15,15,30.0f,260.0f);break;default: break;glFlush(); void ProcessMenu(int value)iMode = value; glutPostRedisplay();void SpecialKeys(int key, int x, int y)if(key = GLUT_KEY_UP)xRot-= 5.0f;if(key = GLUT_KEY_DOWN)xRot += 5.0f;if(key = GLUT_KEY_LEFT)yRot -= 5.0f;if(key = GLUT_KEY_RIGHT)yRot += 5.0f;if(xRot 356.0f)xRot = 0.0f;if(xRot 356.0f)yRot = 0.0f;if(yRot -1.0f)yRot = 355.0f;glutPostRedisplay();int main(int argc, char* argv)glutInit(&argc, argv);glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB); glutInitWindowSize(400,400); glutInitWindowPosition(100,100); glutCreateWindow(OpenGL模型绘制函数示例); /创建菜单并定义菜单回调函数int nGlutPolyMenu = glutCreateMenu(ProcessMenu); glutAddMenuEntry(线框正四面体,1); /创建GLUT多面体绘制菜单glutAddMenuEntry(实体正四面体,2);glutAddMenuEntry(线框正八面体,3);glutAddMenuEntry(实体正八面体,4);int nGlutCurveMenu = glutCreateMenu(ProcessMenu); /创建GLUT曲面绘制菜单glutAddMenuEntry(线框球面,5);glutAddMenuEntry(实体球面,6);glutAddMenuEntry(线框茶壶,7);glutAddMenuEntry(实体茶壶,8);int nGluCurveMenu = glutCreateMenu(ProcessMenu); /创建GLU曲面绘制菜单glutAddMenuEntry(线框球面,9);glutAddMenuEntry(线框圆锥面,10);glutAddMenuEntry(线框圆环面,11);int nMainMenu = glutCreateMenu(ProcessMenu); /创建主菜单glutAddSubMenu(GLUT多面体, nGlutPolyMenu);glutAddSubMenu(GLUT曲面, nGlutCurveMenu);glutAddSubMenu(GLU曲面, nGluCurveMenu);glutAttachMenu(GLUT_RIGHT_BUTTON);glutDisplayFunc(Display);glutReshapeFunc(ChangeSize);glutSpecialFunc(SpecialKeys);Initial(); glutMainLoop(); return 0;4、用OPENGL实现绘制奥运五环标志#include GLuint OlympicRings;void Initial(void)glClearColor(1.0f, 1.0f, 1.0f, 1.0f); OlympicRings = glGenLists(1);glNewList(OlympicRings, GL_COMPILE);glColor3f(1.0, 1.0, 0.0);glTranslatef(-22.0, 0.0, 0.0);glutSolidTorus(0.5, 20.0, 15, 50); /绘制黄色环glColor3f(0.0, 1.0, 0.0);glTranslatef(44.0, 0.0, 0.0);glutSolidTorus(0.5, 20.0, 15, 50); /绘制绿色环glColor3f(0.0, 0.0, 0.0);glTranslatef(-22.

温馨提示

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

评论

0/150

提交评论