OpenGL图形变换:平移、旋转与缩放技巧详解

版权申诉
5星 · 超过95%的资源 4 下载量 161 浏览量 更新于2024-10-20 1 收藏 256KB ZIP 举报
资源摘要信息:"OpenGL程序平移、旋转、缩放变换" OpenGL(Open Graphics Library)是一个用于渲染2D、3D矢量图形的跨语言、跨平台的应用程序编程接口(API)。在计算机图形学中,变换是一种基本操作,它包括平移、旋转和缩放,用于对图形对象进行位置和方向的调整。掌握这些变换方法对于进行OpenGL图形编程至关重要。 1. 平移变换 在OpenGL中,平移是通过平移矩阵来实现的。平移矩阵是一种线性变换矩阵,可以将图形对象沿指定的方向移动特定的距离。在三维空间中,一个平移变换通常表示为以下形式的矩阵: ``` | 1 0 0 tx | | 0 1 0 ty | | 0 0 1 tz | | 0 0 0 1 | ``` 其中`tx`、`ty`、`tz`分别代表沿X、Y、Z轴的平移距离。通过与顶点坐标相乘,可以将顶点沿指定轴向移动。在OpenGL中,使用`glTranslatef(x, y, z)`函数来执行平移操作,其中x、y、z分别代表沿各轴的平移量。 2. 旋转变换 旋转是通过旋转矩阵来实现的。在三维空间中,旋转矩阵可以围绕一个轴将图形对象旋转特定的角度。OpenGL提供了一系列的函数来处理旋转操作: - `glRotatef(angle, x, y, z)`:这是执行旋转变换的函数,其中angle代表旋转角度,x、y、z代表旋转轴的单位向量方向。这个函数将创建一个旋转矩阵,并且与当前矩阵相乘。 - 三维空间中绕任意轴旋转的旋转矩阵可以用以下数学公式表示: ``` | xx(1-c)+c xy(1-c)-zs xz(1-c)+ys 0 | | yx(1-c)+zs yz(1-c)+c yz(1-c)-xs 0 | | zx(1-c)-ys zy(1-c)+xs zz(1-c)+c 0 | | 0 0 0 1 | ``` 其中,c = cos(θ),s = sin(θ),θ是旋转角度,而(x,y,z)是旋转轴的单位向量。 3. 缩放变换 缩放变换是通过缩放矩阵来实现的,用于在三维空间中对图形对象进行放大或缩小。缩放矩阵可以表示为: ``` | sx 0 0 0 | | 0 sy 0 0 | | 0 0 sz 0 | | 0 0 0 1 | ``` 其中`sx`、`sy`、`sz`分别代表沿X、Y、Z轴的缩放因子。当`sx`、`sy`、`sz`都等于1时,图形保持原样;如果它们大于1,则图形被放大;如果它们在0到1之间,则图形被缩小;如果它们为负,则图形会进行镜像变换。OpenGL中使用`glScalef(sx, sy, sz)`函数来进行缩放操作,其中`sx`、`sy`、`sz`是缩放因子。 理解并掌握这些基本的变换操作是进行OpenGL图形编程的基础。通过组合使用平移、旋转和缩放变换,可以实现对图形对象复杂的位置和方向控制,为创建更丰富的三维场景和动画打下坚实的基础。这些变换矩阵可以相乘,形成一个组合变换矩阵,然后应用到顶点数据上,实现连续的变换效果。此外,值得注意的是,OpenGL中使用的是右手坐标系,这意味着Z轴的方向与计算机图形学中常用的左手坐标系相反,这一点在进行三维图形设计时特别重要。
2023-03-10 上传
计算机图形学综合实验报告 烟台大学 计算机学院 软件工程专业 班 级: 计103-3 学 号: 201058503334 姓 名: 公茂华 指导教师: 孔繁茹 完成日期: 2012.11.10 综合试验:太阳系模型 1. 实验目的与要求 1、学习和掌握OpenGL的使用 2、掌握矩阵堆栈的实现方法 3、根据自己的创意实现实验内容,进一步掌握和理解OpenGL的使用 2. 实验内容 1、请编写地球围绕太阳自动旋转的方式 2、请再加上一个月亮, 并围绕地球旋转,并添加轨道 3、实现用户通过键盘或鼠标加入或减少行星和卫星 3. 实验结果 1. 开始运行 2. 增加地球和月亮(按键L或l)或其他任意行星及其若干卫星 3. 按照提示用鼠标和键盘增加或减少行星和卫星 转换视角: 4. 异常提示:要将Color.txt文件放到当前文件夹下 4. 体会 通过本次试验的实践,使我更加了解和初步掌握了OpenGL的用法,对使用OpenGl 绘制球体等图形有了充分认识,并对平移矩阵堆栈和旋转矩阵堆栈的使用有了初步的 掌握。虽然以前没有接触过OpenGl,但是通过学习计算机图形学这门课程的知识,以 及通过多次上机实验,已使我对OpenGL有了一定了解,不过具体使用和其它方面还需 要进一步理解和学习。最后,感谢老师的悉心指导。 5. 源程序 注:红色注释为新加 #include <windows.h> #include <gl/glut.h> #include <stdlib.h> #include <stdio.h> #include <math.h> static float fE = 0.0f; //绕太阳或行星旋转的角度 static int i=0, j=0, m; //for循环计数 static GLint x=7, y=3; //转换视角,以太阳为中心 static int a[8]; //计数第几颗行星的卫星的数量 static bool lag = false; //键盘L(l)增加行星的标志,true为增加 int k[8][3]; //读取文件数据 FILE *fp; void Initial() { glEnable(GL_DEPTH_TEST); //启用深度测试 glClearColor(0.0, 0.0, 0.0, 0.0);//设置背景颜色 } void Change(int w, int h) { glViewport(0, 0, (GLsizei) w, (GLsizei) h);//设置视区尺寸 glMatrixMode(GL_PROJECTION); //指定当前操作投影矩阵堆栈 glLoadIdentity(); //重置投影矩阵 GLfloat fAspect; fAspect = (float)w/(float)h; gluPerspective(45, fAspect, 1.0, 600.0);//设置透视投影矩阵 glMatrixMode(GL_MODELVIEW); glLoadIdentity(); } void Satellite() //增加卫星 { for (int n=0; n< a[i]; n++) { glPushMatrix(); glRotatef(30.0f+6*n, 0.0f, 0.0f, 1.0f); //绕z轴旋转30度 glRotatef(fE*10*(3*n+1), 0.0f, 1.0f, 0.0f); //公转速度fE*10*(3*n+1) glTranslated(-5.0f*m, 1.0f, 0.0f); glColor3f(256.0f, 256.0f, 0.0f); glutWireSphere(1.0f, 20, 20); //卫星 glColor3f(0.0f, 0.0f, 0.0f); glPopMatrix(); } } void Planet() //增加行星 { if (lag==true) //键盘L(l)增加行星 i=j-1; else i=0; for (;i<j;i++) { if (i<5) { if (i==3) m=1.9;//模拟火星 else m=i+1; } else m=9-i; glPushMatrix(); //保存当前的模型视图矩阵 glColor3f(0,0,9); glutWireTorus(20.0f*(i+1), 0, 100, 1); //轨道 glRotatef(fE*(9-i), 0.0f, 1.0f, 0.0f); //绕y轴旋转一定的角度 glTranslated(20.0f*(i+1), 0.0f, 0.0f); //平移一段距离 glColor3f(k[i][0], k[i][1], k[i][2]