[OpenGL]OpenGL坐标系和坐标变换
时间:2023-08-11 07:37:02
OpenGL三维计算机图形的重大现三维计算机图形的重大实现的几何变换(模型转换-查看转换(统称为几何转换))、投影、作物转型、口变换等等。OpenGL矩阵堆栈也实现了。即使你真的进入了一个精彩的三维世界,你也能理解和掌握坐标变换的内容。
坐标系统
OpenGL右手笛卡尔坐标系统,Z正轴垂直屏向外,X正轴从左到右。Y正轴从下到上。
世界坐标系:在现实世界中,所有的物体都有三维特征,但计算机本身只能处理数字。显示二维图形,连接三维物体和二维数据的唯一链接是坐标。为了数字显示的三维物体,在显示物体所在的空间中定义坐标系。坐标系的长度单元和坐标轴的方向应适合描述显示物体,称为世界坐标系。世界坐标系总是固定的。
世界坐标系以屏幕中心为原点(0,0,0),在OpenGL用来描述叙述场景的坐标。
例如,用这个坐标系来描述物体和光源的位置。世界坐标系,不会改变。
局部坐标系:OpenGL局部坐标系的概念也被定义为所谓的局部坐标系。也就是说,坐标系以物体的中心为坐标原点,物体的旋转或平移是围绕局部坐标系进行的,这当物体模型旋转或平移时。局部坐标系也操作相应的旋转或平移操作。
需要注意的是,假设物体模型缩放,局部坐标系也应对应缩放。假设每个坐标轴上的缩放比例不同。然后旋转后,局部坐标轴可能不再垂直。无论是在世界坐标系中转换还是在局部坐标系中转换更改。程序代码是一样的。只是不同的坐标系考虑不同的转换方法。
视坐标系:以视点为原点,以视线方向为Z轴正方向的坐标系。OpenGL世界坐标系将首先转换为视坐标系。然后切割,只有视觉体内的场景才会进入下一阶段。
屏幕坐标系:计算机处理数字显示物体后,应显示在图形显示器上。这需要在图形显示屏上定义一个二维直角坐标系。该坐标系称为屏幕坐标系。
坐标是坐标轴的方向通常将平行于屏幕边缘的坐标原点取在左下角,长度单往往取象素。
相机模拟三维物体
为了解释从三维物体到二维图像之间的变化,我们引入了相机(Camera)假设用相机拍摄世界,那么在相机的取景器中,人眼和现实世界之间就有一个变化的过程。
左图-相机模拟OpenGL各种坐标变换
从三维物体到二维图像。就像用相机拍照一样,通常要经历以下步骤:
1.将相机放在三角架上。让它瞄准三维景物。它相当于OpenGL调整视点的位置。也就是说,视点变换(ViewingTransformation)。
2.将三维物体放置在场景中的适当位置,相当于OpenGL中的模型变换(ModelingTransformation),即旋转、平移和缩放模型。
3.选择相机镜头并调焦,使三维物体投影到二维胶片上,相当于OpenGL将三维模型投影到二维屏幕上的过程。OpenGL的投影变换(ProjectionTransformation),OpenGL正投影和透视投影有两种方法。必须使显示的物体显示在适当的位置、大小和方向上通过投影。有时,为了突出图形的一部分,只显示图形的一部分。这时能够定义一个三维视景体(ViewingVolume)。正射投影通常是长方体的视觉场景。透视投影通常是棱台般的视觉场景。
只有视觉场景中的物体才能投影在显示平面上,而其他部分则不能投影。
4.冲洗底片,决定二维照片的大小。OpenGL中的视口变换(ViewportTransformation)(可以在屏幕窗口中定义矩形,称为视口(Viewport),视景体投影后的图形在视口内显示)规定屏幕上显示场景的范围和大小。
通过以上步骤。三维空间中的物体可以用相应的二维平面物体表示,也可以正确显示在二维计算机屏幕上。
一般来说,三维物体的显示步骤如下:
下图-三维物体的显示过程
OpenGL中几种变换
视点变换
视景中物体的视场景中物体的视点位置和方向,就向上边提到的,它象是相机放在场景中。让相机对准要拍摄的物体。
在确定时,相机(即视点)定位在坐标系的原点(相机的初始方向指向Z负轴),与物体模型的缺失位置是一致的,显然的。假设不改变视点,相机和物体重叠在一起。
运行视点转换的命令与运行模型转换的命令相同。想想看,用相机在拍摄物体时,我们可以保持物体的位置不动,并将相机移离物体。这相当于视觉转换。此外,我们还可以保持相机的固定位置,将物体移离相机,这相当于模型转换。
这样,在OpenGL在中间,逆时针旋转相机相当于顺时针旋转相机。因此。我们必须考虑视觉转换和模型转换。这两个转换是单独的考虑毫无意义。
除了模型转换命令操作视点转换外。OpenGL还提供了有用的库gluLookAt()函数有三个变量,分别定义了视点的位置、相机瞄准方向的参考点和相机的向上方向。函数的原型是:
voidgluLookAt(GLdoubleeyex,GLdoubleeyey,GLdoubleeyez,GLdoublecenterx,GLdoublecentery,GLdoubleupx,GLdoubleupy,GLdoubleupz); |
该函数定义了视点矩阵,并乘以当前矩阵。eyex,eyey,eyez定义了视点的位置。centerx、centery和centerz变量指定了参考点的位置。该点通常是相机瞄准的场景中心轴上的点。upx、upy、upz变量指定上向量。
通常。在模型转换操作发出视点转换操作,使模型转换首先对物体起作用。
模型转换后,场景中物体的顶点移动到所需位置,然后对场景进行视点定位等操作。模型视觉矩阵由模型转换和视点转换组成。
模型变换
在世界坐标系中进行标系中进行的。在缺失时,物体模型的中心位于坐标系的中心。OpenGL在这个坐标系中,有三个命令。可以改变模型。
1、模型平移
glTranslate{fd}(TYPEx,TYPEy,TYPEz); |
指定函数x,y,z值沿x轴,y轴、z轴平移物体(或根据相同的值移动局部坐标系)。
2、模型旋转
glRotate{fd}(TYPEangle,TYPEx,TYPE,y,TYPEz); |
函数中的第一个变量angle制定模型旋转角度,单位为度,后三个变量为原点(0、0、0)到点(x,y,z)轴线逆时针旋转物体。glRotatef(45.0,0.0,0.0,1.结果是绕z轴旋转45度。
3、模型缩放
glScale{fd}(TYPEx,TYPEy,TYPEz); |
这个函数可以沿着对象x,y,z轴分别放大和缩小。函数中的三个参数分别是x、y、z轴向方向的比例变换因子。
缺省时都为1.即物体没有变化。
程序中物体Y轴比例为2.0,其余都为1.0,即将立方体变成长方体。
投影变换
在模型视觉场景转换后,场景中的物体被放置在预期的位置。然而,由于显示器只能用二维图像显示三维物体,因此有必要依靠投影来减少维数(投影变化类似于选择相机的镜头)。
其实。投影变换的目的就是定义一个视景体,使得视景体外多余的部分裁剪掉,终于进入图像的仅仅是视景体内的有关部分。投影包含透视投影(Perspective Projection)和正视投影(Orthographic Projection)两种。
透视投影。符合人们心理习惯,即离视点近的物体大,离视点远的物体小,远到极点即为消失,成为灭点。
它的视景体类似于一个顶部和底部都被进行分割过的棱椎。也就是棱台。这个投影通经常使用于动画、视觉仿真以及其他很多具有真实性反映的方面。
OpenGL透视投影函数有两个。当中函数glFrustum()的原型为:
void glFrustum(GLdouble left,GLdouble Right,GLdouble bottom,GLdouble top,GLdouble near,GLdouble far); |
它创建一个透视视景体。其操作是创建一个透视投影矩阵,而且用这个矩阵乘以当前矩阵。这个函数的參数仅仅定义近裁剪平面的左下角点和右上角点的三维空间坐 标,即(left,bottom,-near)和(right,top,-near);最后一个參数far是远裁剪平面的Z负值。其左下角点和右上角点空 间坐标由函数依据透视投影原理自己主动生成。near和far表示离视点的远近,它们总为正值。该函数形成的视景体例如以下图——《透视投影视景体》所看到的。
函数缺省时,视点都在原点。视线沿Z轴指向负方向。
还有一函数:
void gluPerspective(GLdouble fovy,GLdouble aspect,GLdouble zNear,GLdouble zFar); |
作是创建一个对称的透视投影矩阵,而且用这个矩阵乘以当前矩阵。
參数fovy定义视野在X-Z平面的角度,范围是[0.0,180.0]。參数aspect是投影平面宽度与高度的比率;參数zNear和Far各自是远近裁剪面沿Z负轴到视点的距离,它们总为正值。
正射投影。又叫平行投影。这样的投影的视景体是一个矩形的平行管道,也就是一个长方体。例如以下图所看到的。正射投影的最大一个特点是不管物体距离相机多远,投影 后的物体大小尺寸不变。这样的投影通经常使用在建筑蓝图绘制和计算机辅助设计等方面,这些行业要求投影后的物体尺寸及相互间的角度不变,以便施工或制造时物体比 例大小正确。
例如以下图——《正射投影视景体》
OpenGL正射投影函数也有两个。一个函数是:
void glOrtho(GLdouble left,GLdouble right,GLdouble bottom,GLdouble top, GLdouble near,GLdouble far) |
它创建一个平行视景体。
实际上这个函数的操作是创建一个正射投影矩阵,而且用这个矩阵乘以当前矩阵。当中近裁剪平面是一个矩形,矩形左下角点三维空间坐 标是(left。bottom。-near),右上角点是(right。top,-near);远裁剪平面也是一个矩形,左下角点空间坐标是 (left,bottom。-far),右上角点是(right,top,-far)。全部的near和far值同一时候为正或同一时候为负。假设没有其它变换。 正射投影的方向平行于Z轴,且视点朝向Z负轴。这意味着物体在视点前面时far和near都为负值,物体在视点后面时far和near都为正值。
还有一个函数是:
void gluOrtho2D(GLdouble left,GLdouble right,GLdouble bottom,GLdouble top) |
它是一个特殊的正射投影函数,主要用于二维图像到二维屏幕上的投影。
它的near和far缺省值分别为-1.0和1.0,全部二维物体的Z坐标都为0.0。因此它的裁剪面是一个左下角点为(left,bottom)、右上角点为(right,top)的矩形。
视口变换
视口变换就是将视景体内投影的物体显示在二维的视口平面上。运用相机模拟方式,我们非常easy理解视口变换就是类 似于照片的放大与缩小。在计算机图形学中。它的定义是将经过几何变换、投影变换和裁剪变换后的物体显示于屏幕窗体内指定的区域内,这个区域通常为矩形。称 为视口。OpenGL中相关函数是:
glViewport(GLint x,GLint y,GLsizei width, GLsizei height); |
这个函数定义一个视口。函数參数(x, y)是视口在屏幕窗体坐标系中的左下角点坐标,參数width和height各自是视口的宽度和高度。缺省时,參数值即(0, 0, winWidth, winHeight) 指的是屏幕窗体的实际尺寸大小。全部这些值都是以象素为单位,全为整型数。
注意,在实际应用中,视口的长宽比率总是等于视景体裁剪面的长宽比率。假设两个比率不相等,那么投影后的图像显示于视口内时会发生变形,例如以下图所看到的。
另外,屏幕窗口的改变一般不明显影响视口的大小。因此,在调用这个函数时,最好实时检測窗体尺寸。及时修正视口的大小,保证视口内的图像能随窗体的变化而变化,且不变形。
裁剪变换
在OpenGL中,空间物体的三维裁剪变换包括两个部分:视景体裁剪和附加平面裁剪。视景体裁剪已经包括在投影变换里,前面已述,这里不再反复。以下简单讲一下平面裁剪函数的使用方法。
在OpenGL中,除了视景体定义的六个裁剪平面(上、下、左、右、前、后)外。用户还可自己再定义一个或多个附加裁剪平面,以去掉场景中无关的目标。例如以下图——《附加裁剪平面》所看到的。
附加平面裁剪函数为:
void glClipPlane(GLenum plane,Const GLdouble *equation); |
函数參数equation指向一个拥有四个系数值的数组,这四个系数各自是裁剪平面Ax+By+Cz+D=0的A、B、C、D值。
因此。由这四个系数就能确定一个裁剪平面。
參数plane是GL_CLIP_PLANEi(i=0,1,...),指定裁剪面号。
在调用附加裁剪函数之前,必须先启动glEnable(GL_CLIP_PLANEi),使得当前所定义的裁剪平面有效。当不再调用某个附加裁剪平面时,可用glDisable(GL_CLIP_PLANEi)关闭对应的附加裁剪功能。