计算机图形学-OpenGL投影变换
- 格式:doc
- 大小:157.50 KB
- 文档页数:2
OpenGL两种投影方式投影变换是一种很关键的图形变换,OpenGL中只提供了两种投影方式,一种是正射投影,另一种是透视投影。
不管是调用哪种投影函数,为了避免不必要的变换,其前面必须加上以下两句:glMatrixMode(GL_PROJECTION);glLoadIdentity();事实上,投影变换的目的就是定义一个视景体,使得视景体外多余的部分裁剪掉,最终图像只是视景体内的有关部分。
本节将详细讲述投影变换的概念以及用法。
1 正射投影(Orthographic Projection)正射投影,又叫平行投影。
这种投影的视景体是一个矩形的平行管道,也就是一个长方体。
正射投影的最大一个特点是无论物体距离相机多远,投影后的物体大小尺寸不变。
这种投影通常用在建筑蓝图绘制和计算机辅助设计等方面,这些行业要求投影后的物体尺寸及相互间的角度不变,以便施工或制造时物体比例大小正确。
此种模式下,不需要设定照相机位置、方向以及视点的位置,也就是说不需要gluLookAt函数。
OpenGL正射投影函数共有两个。
一个函数是:glOrtho(left, right, bottom, top, near, far),left表示视景体左面的坐标,right表示右面的坐标,bottom表示下面的,top表示上面的。
这个函数简单理解起来,就是一个物体摆在那里,你怎么去截取他,先单独理解glOrtho的功能。
假设有一个球体,半径为1,圆心在(0, 0, 0),那么,我们设定glOrtho(-1.5, 1.5,-1.5, 1.5, -10, 10);就表示用一个宽高都是3的框框把这个球体整个都装了进来。
如果设定glOrtho(0.0, 1.5, -1.5, 1.5, -10, 10);就表示用一个宽是1.5,高是3的框框把整个球体的右面装进来;如果设定glOrtho(0.0, 1.5, 0.0, 1.5, -10, 10);就表示用一个宽和高都是1.5的框框把球体的右上角装了进来。
计算机图形学实验报告
在计算机图形学课程中,实验是不可或缺的一部分。
通过实验,我们可以更好地理解课程中所学的知识,并且在实践中掌握这些
知识。
在本次实验中,我学习了如何使用OpenGL绘制三维图形,并了解了一些基本的图形变换和视图变换。
首先,我们需要通过OpenGL的基本命令来绘制基本图形,例
如线段、矩形、圆等。
这些基本的绘制命令需要首先设置OpenGL 的状态,例如绘制颜色、线段宽度等,才能正确地绘制出所需的
图形。
然后,在实验中我们学习了图形的变换。
变换是指通过一定的
规则将图形的形状、位置、大小等进行改变。
我们可以通过平移、旋转、缩放等变换来改变图形。
变换需要按照一定的顺序进行,
例如先进行旋转再进行平移等。
在OpenGL中,我们可以通过设
置变换矩阵来完成图形的变换。
变换矩阵包含了平移、旋转、缩
放等信息,通过矩阵乘法可以完成图形的复合变换。
最后,视图变换是指将三维场景中的图形投影到二维平面上,
成为我们所见到的图形。
在实验中,我们学习了透视投影和正交
投影两种方式。
透视投影是指将场景中的图形按照视点不同而产
生不同的远近缩放,使得图形呈现出三维感。
而正交投影则是简单地将场景中的图形按照平行投影的方式呈现在屏幕上。
在OpenGL中,我们可以通过设置视图矩阵和投影矩阵来完成视图变换。
通过本次实验,我对于计算机图形学有了更深入的了解,并掌握了一些基本的图形绘制和变换知识。
在今后的学习中,我将继续学习更高级的图形绘制技术,并应用于实际的项目中。
第四章 OpenGL 图形变换OpenGL 图形变换是OpenGL 技术体系的核心内容之一,它的最主要功能是让虚拟世界里的物体动起来,是虚拟世界的动力驱动系统,也可以称之三维图形系统的引擎!OpenGL 图形变换的主要内容包括几何变换、投影变换、裁剪变换、视口变换等,本章尽量以通俗易懂的方式来讲解各技术要点。
4. 1 图形变换浅说OpenGL 图形变换和照相是非常相似的,它们之间的关系大致描述如下。
1、视点变换(View Transformation ) 视点变换相当于把相机放到一定的位置上,镜头对准场景。
如图4-1所示。
图4-1 视点变换与相机定位在OpenGL中,默认情况下,视点变换相当于把相机放到世界坐标系的原点(0,0,0),镜头指向Z轴的负方向,相当于从世界坐标系的原点向屏幕内部的虚拟场景观察。
2、模型变换(Model Transformation)模型变换相当于场景中人物或对象位置的变化、角度的改变和大小的改变。
图4-2 虚拟照相场景中的人物YXZ观察方向X照相时场景中的人物或对象需要作调整,以便他们位于场景中合适的位置上。
有此时候人物不在视野范围内时,还要走动一下,进入镜头场景内,方向不对时,还要转动一下,眼睛转向镜头。
比如图4-2所示,照相时,警察不在镜头场景内,他需要向后向移动。
中间的企鹅背对镜头,他需要转过向来面向镜头。
企鹅向左边的气球中吹气,气球变大。
调整后的场景如图4-3所示。
图4-3 虚拟照相场景中的调整后人物或对象上述调整过程中的人员移动 和企鹅的转身动作 和气球充气变大 都属于模型变换。
3、投影变换(Projection Transformation ) 投影变换相当于调整相机镜头焦距,放大或缩小景物(如图4-4所示)。
图4-4 投影变换与相机焦距调整OpenGL 中投影变换的本质功能是定义一个视景体,使视景体外的多余部分被裁剪掉,再把景物变换到一个规则投影体(高、宽、深均为2个单位的立方体)。
详解OpenGL的坐标系、投影和几何变换作者:charlee 按:我也是在迷茫中走过来的,初学OpenGL时,略微了解了一些有关变换的基本知识,但是却不知道具体的使用方法,因此经常需要在布置场景时反复调整各种参数。
当我终于有一天明白了它们的用法时,就觉得应该把这些心得体会写下来,让那些和我一样曾经迷茫过的人能够迅速地找到出路。
本文的读者对象为那些初学OpenGL,了解了一些坐标系、几何变换等基本知识,但是又不知道具体应该如何运用这些操作的人。
如果你对OpenGL一无所知,建议你先去学学OpenGL的基本知识。
1 坐标系OpenGL中使用的坐标系有两种,分别为世界坐标系和屏幕坐标系。
世界坐标系即OpenGL内部处理时使用的三维坐标系,而屏幕坐标系即为在计算机屏幕上绘图时使用的坐标系。
通常,OpenGL所使用的世界坐标系为右手型,如下图所示。
从计算机屏幕的角度来看,x轴正方向为屏幕从左向右,y轴正方向为屏幕从下向上,z轴正方向为屏幕从里向外。
而进行旋转操作时需要指定的角度θ的方向则由右手法则来决定,即右手握拳,大拇指直向某个坐标轴的正方向,那么其余四指指向的方向即为该坐标轴上的θ角的正方向(即θ角增加的方向),在上图中用圆弧形箭头标出。
2 投影将世界坐标系中的物体映射到屏幕坐标系上的方法称为投影。
投影的方式包括平行投影和透视投影两种。
平行投影的投影线相互平行,投影的结果与原物体的大小相等,因此广泛地应用于工程制图等方面。
透视投影的投影线相交于一点,因此投影的结果与原物体的实际大小并不一致,而是会近大远小。
因此透视投影更接近于真实世界的投影方式。
B 平行投影B透视投影xzy 02.1 平行投影OpenGL 中使用下面的函数来设置投影方式为平行投影。
glOrtho(xleft, xright, ybottom, ytop, znear, zfar); 各参数的含义如下图所示。
注意,只有位于立方体之内的物体才可见。
第四讲 OpenGL 变换OpenGL 变换包括:几何变换、投影变换、裁剪变换和视口变换,想要真正走进三维世界,必须对这些知识有所了解。
三维图形的显示流程:三维图形的显示流程首先将世界坐标系中的三维物体经过一系列的几何变换(平移、旋转和伸缩),为了使显示的物体能以合适的位置、大小和方向显示出来,必须要通过投影,然后定义一个三维视景体,对物体进行裁剪,仅使投影在视景体内的部分显示出来;第二步在屏幕窗口内定义一个矩形,称为视口(Viewport),视景体投影后的图像就在视口内显示;最后做一些适当 变换,使图形在屏幕坐标系下显示。
比如你要照相,首先你会站到一个合适的位置,并摆好一个姿势,这个过程相当于几何变换;选择相机(相机正对的方向相当于构造了一个视景体),不在相机前方视景体内的物体被裁剪;拍照相片最后要在计算机上显示出来,还要经过一个视口变换,这就是说相片上的那部分要在窗口内进行显示。
1、模型变换模型变换在世界坐标系中进行的,OpenGL 在这个坐标系中有3个函数可以进行模型变换。
(1)模型平移glTranslate{fd}( x, y, z);该函数用指定的x,y,z 值沿着x 轴、y 轴和 z 轴平移物体(2)模型旋转glRotate{fd}( angle, x, y, z);angle 指定旋转的角度,单位为度( °),后3个变量表示以原点(0,0,0)到点(x, y, z)的连线为轴线逆时针旋转物体。
例如,glRotatef(45,0,0,1)的结果是饶z 轴旋转45度。
(3)模型缩放glScale{fd}( x, y, z);(x, y, z)分别表示物体在x,y,z 轴方向的缩放变换比例因子,默认为1.0,即物体没有变化。
每一步的变换在没有经过处理时,是在前一步的基础上叠加的,也即OpenGL中的所有变换都会叠加。
glTranslatef(1.0f,0.0f,0.0f);glutWireCube(1.0f); //将立方体物体向x轴正向移动1个单位距离。
《计算机图形学基础》实验6 OpenGL中的变换一、实验目的及要求1.理解OpenGL中的各种变换的实现原理;2.掌握OpenGL中模型视图矩阵的操作方法。
3.掌握OpenGL中投影变换的实现方法。
二、实验环境主要是软件开发环境VC 6.0三、实验内容1、分子动画示例2、深度测试示例四、实验结果1、分子动画五、程序代码1.分子动画#include <gl/glut.h>void Initial(){glEnable(GL_DEPTH_TEST); // 启用深度测试glClearColor(1.0f, 1.0f, 1.0f, 1.0f ); //背景为白色}void ChangeSize(int w, int h){if(h == 0) h = 1;glViewport(0, 0, w, h); // 设置视区尺寸glMatrixMode(GL_PROJECTION); // 指定当前操作投影矩阵堆栈glLoadIdentity(); // 重置投影矩阵GLfloat fAspect;fAspect = (float)w/(float)h; // 计算视区的宽高比gluPerspective(45.0, fAspect, 1.0, 500.0); // 指定透视投影的观察空间glMatrixMode(GL_MODELVIEW);glLoadIdentity();}void Display(void){static float fElect1 = 0.0f; // 绕原子旋转的角度glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); //清除颜色和深度缓冲区glMatrixMode(GL_MODELVIEW); // 指定当前操作模型视图矩阵堆栈glLoadIdentity(); // 重置模型视图矩阵glTranslatef(0.0f, 0.0f, -250.0f); //将图形沿z轴负向移动glColor3f(1.0f, 0.0f, 0.0f);glutSolidSphere(12.0f, 15, 15); // 绘制红色的原子glColor3f(0.0f, 0.0f, 0.0f);glPushMatrix(); // 保存当前的模型视图矩阵glRotatef(fElect1, 0.0f, 1.0f, 0.0f); // 绕y轴旋转一定的角度glTranslatef(90.0f, 0.0f, 0.0f); // 平移一段距离glutSolidSphere(6.0f, 15, 15); // 画出第一个电子glPopMatrix(); // 恢复模型视图矩阵glPushMatrix(); // 保存当前的模型视图矩阵glRotatef(45.0f, 0.0f, 0.0f, 1.0f); //绕z轴旋转45°glRotatef(fElect1, 0.0f, 1.0f, 0.0f);glTranslatef(-70.0f, 0.0f, 0.0f);glutSolidSphere(6.0f, 15, 15); // 画出第二个电子glPopMatrix(); // 恢复模型视图矩阵glPushMatrix(); // 保存当前的模型视图矩阵glRotatef(-45.0f,0.0f, 0.0f, 1.0f); //绕z轴旋转-45°glRotatef(fElect1, 0.0f, 1.0f, 0.0f);glTranslatef(0.0f, 0.0f, 60.0f);glutSolidSphere(6.0f, 15, 15); // 画出第三个电子glPopMatrix();fElect1 += 10.0f; // 增加旋转步长,产生动画效果if(fElect1 > 360.0f) fElect1 = 10.0f;glutSwapBuffers();}void TimerFunc(int value){glutPostRedisplay();glutTimerFunc(100, TimerFunc, 1);}int main(int argc, char* argv[]){glutInit(&argc, argv);glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);glutCreateWindow("分子动画示例");glutReshapeFunc(ChangeSize);glutDisplayFunc(Display);glutTimerFunc(500, TimerFunc, 1); //指定定时器回调函数Initial();glutMainLoop();return 0;}六、心得体会这次的分子动画实验比较有意思,就是对代码的理解性不是很高。
OpenGL图形变换OpenGL图形软件包是为三维应用设计的,其中包含了大量的有关三维变换的操作,二维变换则可以看作是三维变换的特例。
OpenGL中常用的变换包括模型视图变换、投影变换和视见区变换。
一、矩阵堆栈在计算机图形学中,所有的变换都是通过矩阵乘法来实现的,即将三维形体顶点构成的齐次坐标矩阵乘以三维变换矩阵就得到了变换后的形体顶点的齐次坐标矩阵,这样只要求出形体的三维变换矩阵,就可以得到变换后的形体。
在OpenGL中,对象的坐标变换也是通过矩阵来实现的。
OpenGL中包含了两个重要的矩阵:模型视图矩阵和投影矩阵,其中模型视图矩阵用于物体的模型视图变换,投影矩阵用于投影变换。
一般来说,在进行矩阵操作之前,需要指定当前操作的矩阵对象,这可以使用函数:glMatrixMode(GLenum mode);定义。
其中当mode取GL_MODELVIEW时,表示对模型视图矩阵进行操作;当mode取GL_PROJECTION时表示对投影矩阵进行操作,并且一旦设置了当前操作矩阵,它就将保持为当前的矩阵对象,直到再次调用函数glMatrixMode修改它为止。
默认情况下,系统处理的当前矩阵是模型视图矩阵。
OpenGL为模型视图矩阵和投影矩阵各维护着一个“矩阵堆栈”,其中堆栈的栈顶矩阵就是当前的模型视图矩阵或投影矩阵。
在调用变换函数的时候,系统自动计算变换函数对应的变换矩阵与当前操作的矩阵堆栈栈顶矩阵的乘积,并置为栈顶矩阵,绘制图形时使用栈顶矩阵作为图形的变换矩阵。
矩阵堆栈主要用来保存和恢复矩阵的状态。
OpenGL中利用函数:void glPushMatrix(void);void glPopMatrix(void);实现矩阵堆栈的操作。
其中函数glPushMatrix将当前矩阵堆栈的栈顶矩阵复制一个,并将其压入当前矩阵堆栈,以保存当前变换矩阵。
函数glPopMatrix用于将当前矩阵堆栈的栈顶矩阵弹出,这样,堆栈中的下一个矩阵变为栈顶矩阵(当前变换矩阵),用来恢复当前变换矩阵原先的状态。
Win32 OpenGL编程(9) 投影变换收藏Win32 OpenGL编程(9) 投影变换write by 九天雁翎(JTianLing) -- /vagrxie讨论新闻组及文件提要在前文(系列文章(7),以下简称XO7,系列其他文章类似)中的照相机比喻中提到了4种3D变换,如下:1.确定照相机的位置的过程对应于“视图变换”(Viewing Transformations)2.确定物体位置的过程对应于“模型变换”(Modeling Transformations)3.确定照相机放大倍数的过程对应于“投影变换”(Projection Transformations)4.确定照片大小的过程对应于“视口变换”(Viewport Transformations)XO7中我们讲的是第一种变换视图变换,即改变观察者本身的位置,视角等的变换效果,XO8中讲的是第二种变换模型变换,本文开始继续按顺序讲解下一个3D 变换过程,投影变换。
正投影投影变换的过程就像是照相机选镜头的过程,目的是确定视野,其实说起来投影一词,我在学习工程制图的时候就接触过了,不知道大家是否学过这门课程,工程制图就是一种将三维空间的事物设想投影在二维空间中,然后画下来,工程中应用非常广泛,那时候学的那些剖面图什么的,也是累死我了-_-!OpenGL 就可以模拟这样的过程,并且名字和工程制图中的名字是一样的,叫正投影。
OpenGL以glOrtho来指定一个正交平行的矩形,屏幕上显示的就是此物体在此矩形的正面的投影。
在XO2中用过的gluOrtho2D实际上是此函数的一个去掉Z 轴坐标的简化版,而glOrtho包括的参数 nearVal,farVal表示此矩形的前,后两面,超出此矩形范围的图形将会被裁掉。
《OpenGL Programming Guide》:glOrtho — multiply the current matrix with an orthographic matrixC Specificationvoid glOrtho( GLdouble left,GLdouble right,GLdouble bottom,GLdouble top,GLdouble nearVal,GLdouble farVal);Parametersleft, rightSpecify the coordinates for the left and right vertical clipping planes.bottom, topSpecify the coordinates for the bottom and top horizontal clipping planes.nearVal, farValSpecify the distances to the nearer and farther depth clipping planes.These values are negative if the plane is to be behind the viewer.用此函数,通过调整nearVal与farVal我们可以实现类似工程制图中的剖面的效果,见下例:GLfloat gfNear = 1.0;//这里进行所有的绘图工作void SceneShow(GLvoid){glClear(GL_COLOR_BUFFER_BIT);glColor3f(1.0, 0.0, 0.0);glMatrixMode(GL_PROJECTION);glLoadIdentity();glOrtho(-1.0, 1.0, -1.0, 1.0, gfNear, -1.0);glPushMatrix();DrawSmoothColorPyramid(0.5);glPopMatrix();glFlush();}///////////////////////////////////////////////////////////int Game_Main(void *parms = NULL, int num_parms = 0){DWORD dwStartTime;dwStartTime = GetTickCount();// this is the main loop of the game, do all your processing // here// for now test if user is hitting ESC and send WM_CLOSEif (KEYDOWN(VK_ESCAPE))SendMessage(ghWnd,WM_CLOSE,0,0);if (KEYDOWN(VK_UP)){gfNear -= 0.01;}if (KEYDOWN(VK_DOWN)){gfNear += 0.01;}SceneShow();// 控制帧率while(GetTickCount() - dwStartTime < TIME_IN_FRAME){Sleep(1);}// return success or failure or your own return code herereturn(1);} // end Game_Main以下就是当nearVal为0.8时的效果,也就是说,Z轴坐标大于0.8的,一律被截掉了,在工程制图中,我们老师常将,此时假设在此用一刀将物体切掉。
计算机图形学之投影变换使用WPF学习计算机图形学——一个古老的绘制器一文中介绍了德国画家丢勒绘画时使用的一种装置,线的一端固定到墙面上,另外一端放置在待绘制物体表面的某个点,记录线穿过木框的位置,并在画纸关闭时标记到画纸上,通过不断变动线末端物体上的点最终就可以绘制出一幅准确的物体画像,丢勒使用的其实就是一种透视投影装置,使用这种方式可以绘制出真实立体感的图形。
在计算机图形学中,投影变换目的就是把场景世界中的3D物体转换为2D平面图形的过程,转换后降了一维,相对于前面的绘图装置,线末端固定点的可以认为是观察者的视点或者摄像机的位置。
依据这个目的,我们的目标本质上就是已知物体表面的点坐标(x,y,z)计算出投影的某个固定面的2D坐标(x',y',1),可以根据三角形的比例关系轻松的计算出x'=x/z,y'=y/z。
假定物体投射到z=1的平面上,因为投影是把3D降维转换为2D,所以z的坐标是固定不变的就这么简单?然而,在计算机图形学中透视投影变换是一种比较复杂的变换,实际的计算远远比刚才的计算复杂得多,那么是什么增加了计算的复杂度哪?首先,实际的图形学投影变换需要考虑摄像机的视域体,下图中从相机出发的金字塔形的锥体区域为视域体,其中只有近裁切面和远裁切面之间范围内的物体才会进行绘制,之外的物体需要进行忽略或裁切;另外,由于绘制图形的屏幕有各种各样的规格尺寸,为了简化计算大部分的图形库都会首先变换到规范化立方体内(各坐标轴坐标范围为-1~1)进行处理,因为这样就无需考虑屏幕的尺寸,最终输出图形时还会再通过反变换输出到屏幕坐标系中。
这两种因素导致了实际的投影变换比较复杂,接下来我们来一步步推导出透视投影变换矩阵。
正交投影首先,从简单的正交投影矩阵推导开始,正交投影矩阵也叫平行投影,投影的方向和坐标轴要么平行要么垂直。
正交投影可以有下面两个步骤组合来完成:1.把下图左侧由前后、上下、左右裁切面组成的长方体盒型视域体的中心点平移到右侧规范化立方体的坐标原点,这一步为平移变换。
opengl算法学习---图形⼏何变换图形⼏何变换图形变换是计算机图形学中的⼀个重要内容。
通过对简单图形进⾏多种变换和组合,可以形成⼀个复杂图形,这些操作也⽤于将世界坐标系中的场景描述转换为输出设备上的观察显⽰中。
应⽤于对象⼏何描述并改变它的位置、⽅向或⼤⼩等⼏何信息的操作称为⼏何变换(Geometric Transformation)。
这种变换⼀般维持图形的拓扑关系(构成规则)不变,只改变图形的⼏何关系(⼤⼩、形状及相对位置),主要包括平移、放缩、旋转及投影等操作。
平移变换\[P=\begin{bmatrix} x \\ y \end{bmatrix} {P}'=\begin{bmatrix} {x}' \\ {y}' \end{bmatrix} T=\begin{bmatrix} t_{x} \\ t_{y} \end{bmatrix}\]\[{P}'=P+T \]通过齐次坐标变换矩阵表⽰\[{P}'=\begin{bmatrix}{x}'\\ {y}' \\ 1 \end{bmatrix} =\begin{bmatrix}1 & 0 & t_{x}\\ 0 & 1 & t_{y} \\ 0 & 0& 1 \end{bmatrix}\cdot\begin{bmatrix}x\\ y \\ 1 \end{bmatrix}= T(t_{x},t_{y})\cdot P \]绕坐标原点的旋转变换旋转⾓定向:逆时针为正,顺时针为负\[cos(\alpha + \theta )= cos(\alpha)cos(\theta) - sin(\alpha)sin(\theta) \]\[sin(\alpha + \theta )= sin(\alpha)cos(\theta) + cos(\alpha)sin(\theta) \]\[OA=\begin{bmatrix} rcos(\alpha) \\ rsin(\alpha) \end{bmatrix} OB=\begin{bmatrix} rcos(\alpha + \theta ) \\ rsin(\alpha + \theta ) \end{bmatrix} T=\begin{bmatrix} cos\theta & -sin\theta \\ sin\theta & cos\theta \end{bmatrix}\]\[OB=OA \cdot T \]通过齐次坐标变换矩阵表⽰\[{P}'=\begin{bmatrix}{x}'\\ {y}' \\ 1 \end{bmatrix} =\begin{bmatrix}cos \theta & -sin \theta & 0\\ sin \theta & cos \theta & 0 \\ 0 & 0& 1\end{bmatrix}\cdot\begin{bmatrix}x\\ y \\ 1 \end{bmatrix}= R(\theta) \cdot P \]以坐标原点为基准点的缩放变换\[{x}'=x \cdot s_{x} \]\[{y}'=y \cdot s_{y} \]\[{P}'=\begin{bmatrix}{x}'\\ {y}' \end{bmatrix} =\begin{bmatrix}s_{x} & 0\\ 0 & s_{y} \end{bmatrix}\cdot\begin{bmatrix}x\\ y \end{bmatrix}= s \cdot P\]通过齐次坐标变换矩阵表⽰\[{x}'=x \cdot s_{x} \]\[{y}'=y \cdot s_{y} \]\[{P}'=\begin{bmatrix}{x}'\\ {y}' \\ 1 \end{bmatrix} =\begin{bmatrix} s_{x} & 0 & 0\\ 0 & s_{y} & 0 \\ 0 & 0& 1 \end{bmatrix}\cdot\begin{bmatrix}x\\ y \\ 1 \end{bmatrix}= S(S_{x},s_{y}) \cdot P \]反射变换产⽣对象镜像的变换称为反射(reflection),变换通过将对象绕反射轴旋转180°来⽣成反射镜像1 相对于x轴的反射\[ \begin{bmatrix} {x}' \\ {y}' \end{bmatrix} =\begin{bmatrix} 1 & 0 \\ 0 & -1 \end{bmatrix} \cdot \begin{bmatrix} x \\ y \end{bmatrix} \]2 相对于y轴的反射\[ \begin{bmatrix} {x}' \\ {y}' \end{bmatrix}= \begin{bmatrix} -1 & 0 \\ 0 & 1 \end{bmatrix} \cdot \begin{bmatrix} x \\ y \end{bmatrix} \]3 相对于坐标原点的反射\[ \begin{bmatrix} {x}' \\ {y}' \end{bmatrix}= \begin{bmatrix} -1 & 0 \\ 0 & -1 \end{bmatrix} \cdot \begin{bmatrix} x \\ y \end{bmatrix} \]通过齐次坐标变换矩阵表⽰\[{P}'=\begin{bmatrix}{x}'\\ {y}' \\ 1 \end{bmatrix} =\begin{bmatrix} a & b & 0\\ c & d & 0 \\ 0 & 0& 1 \end{bmatrix} \cdot \begin{bmatrix}x\\ y \\ 1 \end{bmatrix} =R(a,b,c,d) \cdot P \]4 相对于任意点的反射\[{P}'=\begin{bmatrix}{x}'\\ {y}' \\ 1 \end{bmatrix} =\begin{bmatrix} -1 & 0 & 2u\\ 0 & -1 & 2v \\ 0 & 0& 1 \end{bmatrix} \cdot \begin{bmatrix}x\\ y \\ 1 \end{bmatrix} =T \cdot P \]5 关于对⾓线 y= x 的反射\[ \begin{bmatrix} {x}' \\ {y}' \end{bmatrix}= \begin{bmatrix} 0 & 1 \\ 1 & 0 \end{bmatrix} \cdot \begin{bmatrix} x \\ y \end{bmatrix} \]6 关于对⾓线 y= -x 的反射\[ \begin{bmatrix} {x}' \\ {y}' \end{bmatrix}= \begin{bmatrix} 0 & -1 \\ -1 & 0 \end{bmatrix} \cdot \begin{bmatrix} x \\ y \end{bmatrix} \]7 相对于任意直线 y=mx+b 的反射\[p'= \begin{bmatrix} x'\\ y' \\ 1 \end{bmatrix} = \frac{1}{1+m^{2}} \begin{bmatrix} 1-m^{2} & 2m & -2mb\\ 2m & m^{2}-1 & 2b\\ 0 & 0 & 1+m^{2} \end{bmatrix} \cdot \begin{bmatrix} x\\ y \\ 1 \end{bmatrix} =T\cdot P \]错切变换错切(shear)是⼀种使对象形状发⽣变化的变换,经过错切的对象好像是由相互滑动的内部夹层组成相对于x轴的x⽅向错切由下列变换产⽣\[ \begin{bmatrix} {x}' \\ {y}' \end{bmatrix} =\begin{bmatrix} 1 & sh_{x} \\ 0 & 1 \end{bmatrix} \cdot \begin{bmatrix} x \\ y \end{bmatrix} \]该变换对应的坐标转换为\[{x}'=x+sh_{x} \cdot y \]\[{y}'=y \]通过齐次坐标变换矩阵表⽰相对于线\(y=y_{ref}\)的x⽅向错切\[ \begin{bmatrix}{x}'\\ {y}' \\ 1 \end{bmatrix} =\begin{bmatrix} 1 & sh_{x} & -sh_{x} \cdot y_{ref} \\ 0 & 1 & 0 \\ 0 & 0& 1 \end{bmatrix} \cdot\begin{bmatrix}x\\ y \\ 1 \end{bmatrix} \]相对于线\(x=x_{ref}\)的y⽅向错切\[ \begin{bmatrix}{x}'\\ {y}' \\ 1 \end{bmatrix} =\begin{bmatrix} 1 & 0 & 0 \\ sh_{y} & 1 & -sh_{y} \cdot x_{ref}\\ 0 & 0& 1 \end{bmatrix} \cdot\begin{bmatrix}x\\ y \\ 1 \end{bmatrix} \]逆变换通过齐次坐标变换矩阵表⽰平移逆变换\[T^{-1} =\begin{bmatrix} 1 & 0 & -t_{x} \\ 0 & 1 & -t_{y} \\ 0 & 0& 1 \end{bmatrix} \]旋转逆变换\[R^{-1} =\begin{bmatrix} cos \theta & -sin \theta & 0 \\ sin \theta & cos \theta & 0 \\ 0 & 0& 1 \end{bmatrix} \]缩放逆变换\[S^{-1} =\begin{bmatrix} \frac{1}{s_{x}} & 0 & 0 \\ 0 & \frac{1}{s_{y}} & 0 \\ 0 & 0& 1 \end{bmatrix} \]⼆维复合变换利⽤矩阵表达式,可以通过计算单个变换的矩阵乘积,将任意的变换序列组成复合变换矩阵。
opengl投影变换与逆变换⼀个新⼿都在问的:opengl中如何将2d窗⼝坐标转换为3d空间坐标。
以下是测试代码,需⽤到glm库。
#include <string>#include <cstdlib>#include <iostream>#include <glm/glm.hpp>#include <glm/ext.hpp>using namespace std;using namespace glm;void print(const vec4& v) {cout << v[0] << "" << v[1] << "" << v[2] << "" << v[3] << endl;}void print(const mat4& m) {print(glm::column(m, 0));print(glm::column(m, 1));print(glm::column(m, 2));print(glm::column(m, 3));}int main(int argc, char** argv) {//投影变换mat4 proj = glm::perspective(45.0f, 1.0f, 0.1f, 10.0f);{vec4 pos = vec4(3, 3, -9, 1);pos = proj*pos;print(pos);pos /= pos.w;print(pos);}cout<<endl;//投影逆变换{float x=0.5,y=0.5,z=-1;vec4 pos=vec4(x,y,z,1);mat4 invProj=glm::inverse(proj);pos=invProj*pos;print(pos);pos/=pos.w;print(pos);}return0;}⽂中忽略模型视图矩阵,就当相机固定在世界中⼼往负z轴⽅向观察。
实验5 OpenGL模型视图变换一、实验目的:理解掌握OpenGL程序的模型视图变换。
二、实验内容:(1)阅读实验原理,运行示范实验代码,理解掌握OpenGL程序的模型视图变换;(2)根据示范代码,尝试完成实验作业;三、实验原理:在代码中,视图变换必须出现在模型变换之前,但可以在绘图之前的任何时候执行投影变换和视口变换。
1.display()程序中绘图函数潜在的重复性强调了:在指定的视图变换之前,应该使用glLoadIdentity()函数把当前矩阵设置为单位矩阵。
2.在载入单位矩阵之后,使用gluLookAt()函数指定视图变换。
如果程序没有调用gluLookAt(),那么照相机会设定为一个默认的位置和方向。
在默认的情况下,照相机位于原点,指向Z轴负方向,朝上向量为(0,1,0)。
3.一般而言,display()函数包括:视图变换 + 模型变换 + 绘制图形的函数(如glutWireCube())。
display()会在窗口被移动或者原来先遮住这个窗口的东西被一开时,被重复调用,并经过适当变换,保证绘制的图形是按照希望的方式进行绘制。
4.在调用glFrustum()设置投影变换之前,在reshape()函数中有一些准备工作:视口变换 + 投影变换 + 模型视图变换。
由于投影变换,视口变换共同决定了场景是如何映射到计算机的屏幕上的,而且它们都与屏幕的宽度,高度密切相关,因此应该放在reshape()中。
reshape()会在窗口初次创建,移动或改变时被调用。
OpenGL中矩阵坐标之间的关系:物理坐标*模型视图矩阵*投影矩阵*透视除法*规范化设备坐标——〉窗口坐标(1)视图变换函数gluLookAt(0.0,0.0,5.0,0.0,0.0,0.0,0.0,1.0,0.0,)设置照相机的位置。
把照相机放在(0,0,5),镜头瞄准(0,0,0),朝上向量定为(0,1,0)朝上向量为照相机指定了一个唯一的方向。
实验名称:OpenGL投影变换(实验四)
班级:信09-1
学号:2108190911211
姓名:王杰
【实验目的】
1、掌握GLUT中多面体和二次曲面的生成
2、掌握正交投影及透视投影变换
【实验内容】
1、源程序
#include <glut.h>
GLsizei winWidth = 500, winHeight = 500;
void init(void)
{
glClearColor(1.0,1.0,1.0,0.0);
}
void display(void)
{
glClear(GL_COLOR_BUFFER_BIT);
glColor3f(0.0,0.0,0.0);
glTranslatef(0.0,0.0,-5.0);
glRotatef(30,2,2,2);
glutWireOctahedron ( );//八面体
glFlush();
}
void winReshapeFcn(GLint newWidth,GLint newHeight) {
glViewport(0,0,newWidth,newHeight);
glMatrixMode(GL_PROJECTION);
//glFrustum(-2.0,2.0,-2.0,2.0,2.0,20.0);//透视投影
glOrtho(-2.0,2.0,-2.0,2.0,2.0,20.0);//正交投影
glMatrixMode(GL_MODELVIEW);
glClear(GL_COLOR_BUFFER_BIT);
}
void main(int argc,char** argv)
{
glutInit(&argc,argv);
glutInitDisplayMode(GLUT_SINGLE|GLUT_RGB);
glutInitWindowPosition(100,100);
glutInitWindowSize(winWidth,winHeight);
//glutCreateWindow("投影变化—透视投影");
glutCreateWindow("投影变化—正交投影");
init();
glutDisplayFunc(display);
glutReshapeFunc(winReshapeFcn);
glutMainLoop();
}
2、运行结果截图(两幅)
3、正交及透视投影函数功能及使用说明
glFrustum(-2.0,2.0,-2.0,2.0,2.0,20.0);//透视投影glOrtho(-2.0,2.0,-2.0,2.0,2.0,20.0);//正交投影
glutCreateWindow("投影变化—透视投影");
glutCreateWindow("投影变化—正交投影");。