资源描述
三维图形变换包括三维图形几何变换和投影变换。 三维图形几何变换是指对三维图形的几何信息经过平移、比例、旋转等变换后产生新的图形。三维图形几何变换实现从不同位置观察三维物体的模拟。 投影变换就是将三维立体(或物体)投射到投影面上得到二维平面图形。其实质是用二维图形表达三维对象。,与二维几何变换类似,三维图形几何变换也是通过对顶点坐标做矩阵变换来实现。 在定义了规范化齐次坐标系之后,三维图形变换可以表示为图形点集的规范化齐次坐标矩阵与某一变化矩阵相乘的形式。,三维变换的基本概念,三维齐次坐标变换矩阵简称为三维变换矩阵。 其形式为:,三维变换的基本概念,三维空间点的三维变换可以表示为点的规范化齐次坐标矩阵与三维变换矩阵相乘的形式。,三维变换的基本概念,T3D按功能可划分为4个子矩阵。,3x3阶子矩阵,作用是对点进行比例、对称、旋转和错切变换。,1x3阶子矩阵,作用是对点进行平移变换。,3x1阶子矩阵,作用是对点进行透视变换。,1x1阶子矩阵,作用是产生整体比例变换。,三维变换的基本概念,常见的几种三维齐次坐标变换矩阵:,一、比例变换:,二、平移变换:,矩阵中的a e j分别为x y z三个方向的比例因子。,矩阵中的l m n分别为x y z三个方向的平移量。,三维几何变换,三、旋转变换:,旋转角度正负向定义符合右手螺旋定则。即大拇指表示坐标轴正向,四指握拳的方向为旋转角的正向。,三维几何变换,常见的几种三维齐次坐标变换矩阵:,当物体分别绕x、y、 z轴旋转时,旋转变换矩阵分别为:,绕x轴旋转,旋转前后坐标变换的关系为:,三维几何变换,绕y轴旋转,旋转前后坐标变换的关系为:,三维几何变换,绕z轴旋转,旋转前后坐标变换的关系为:,三维几何变换,四、三维复合变换变换:,三维复合变换是指图形作一次以上的变换,变换结果是每次变换矩阵的乘积。,三维几何变换,三维齐次坐标变换矩阵,四、三维复合变换变换绕任意轴的三维旋转变换,假设已知空间有任意轴AB,点A的坐标为(xA, yA, zA),AB矢量的方向系数为(a, b, c)。现有空间点P(x, y, z),绕AB轴逆时针方向旋转角后为P(x, y, z),若旋转变换矩阵为TrAB,则有:,三维齐次坐标变换矩阵,变换步骤: 平移将点A平移至原点。 旋转将平移后的轴OB绕y轴旋转a角,使OB变换成位于zoy面内的矢量B”。 旋转再绕x轴旋转b角,使矢量与oz轴重合。 点P旋转点P绕oz轴旋转q角。 逆变换按上述步骤做逆变换,使AB回到原来位置。,三维齐次坐标变换矩阵,四、三维复合变换变换绕任意轴的三维旋转变换,上述变换过程用矩阵表示为:,要推导出7个矩阵相乘后的结果矩阵,是一项复杂且易出错的工作。OpenGL通过操作矩阵堆栈完成多个矩阵相乘。,平面几何投影,计算机图形显示的核心是创建三维物体的二维图像,因为计算机的屏幕是二维平面。 投影即是三维物体通过投射,在投影面上生成二维平面图形。投影分为平面几何投影和观察投影。,平面几何投影主要指平行投影和透视投影。 观察投影是指在观察空间下进行的图形投影变换。 投影的过程实质上是一种变换,在计算机内部,不同的变换可以用不同的矩阵表示。,平面几何投影,平行投影:互相平行的投射线照射物体,在投影面内产生三维物体的影像。平行投影体系生成物体的三视图和轴测图。,透视投影:点光源发出的光线照射物体,在投影面上产生三维物体的影像。 透视图分为单点透视、两点透视和三点透视。,透视投影和平行投影的本质区别在于透视投影的投影中心到投影面之间的距离是有限的;平行投影的投影中心到投影面之间的距离是无限的。,透视投影属于中心投影,正投影和斜投影属于平行投影,平面几何投影,平面几何投影,三维投影变换平行正投影三视图,三视图包括主视图、俯视图和左视图,由三维形体经投影变换得到。要绘制三视图,需求得变换矩阵,经投影变换得到三维形体上各顶点的投影坐标,即可绘制出三视图。 三维投影变换的实质是将三维形体上各点投影到同一个平面上,得到的是一个二维的投影视图。,三维投影变换平行正投影三视图,主视图投影矩阵为:,三维投影变换平行正投影三视图,俯视图:三维形体向xoy面(又称H面)作垂直投影得到俯视图。,三维投影变换平行正投影三视图,俯视图投影矩阵:,立体向XOY面投影,三维投影变换平行正投影三视图,俯视图投影矩阵:,XOY面绕OX轴向下旋转90度,三维投影变换平行正投影三视图,俯视图投影矩阵:,水平投影图形向下移动,三维投影变换平行正投影三视图,俯视图投影矩阵:,三维投影变换平行正投影三视图,侧视图:获得侧视图是将三维形体往yoz面(侧面W)作垂直投影。,三维投影变换平行正投影三视图,侧视图投影矩阵:,立体向YOZ面投影,三维投影变换平行正投影三视图,侧视图投影矩阵:,YOZ面绕OZ轴旋转,三维投影变换平行正投影三视图,侧视图投影矩阵:,侧投影图形沿水平方向平移,三维投影变换平行正投影三视图,侧视图投影矩阵:,三维投影变换平行正投影三视图,最终得到立体的三视图,三维投影变换正轴测图,正轴测图简介: 选不平行于基本投影面的平面为投影面,以垂直于投影面的矢量为投影矢量,得到的三维形体的图形,称为正轴测图。如右图示。,三维投影变换正轴测图,正轴测投影是以任意平面为投影面所做的投影。如图,若以ABC为投影面,投影矢量OF垂直于ABC平面,点E为原点O在ABC上的投影。产生正轴测投影的思路为:,将投影矢量OF通过两次旋转变化至与Z轴重合,此时ABC平面变化至与XOY面平行,三维向XOY面做投影即可。,三维投影变换正轴测图,用矩阵表示正轴测变换的过程:,矢量OF绕Y轴旋转a角,三维投影变换正轴测图,用矩阵表示正轴测变换的过程:,矢量OF绕X轴旋转 角,三维投影变换正轴测图,用矩阵表示正轴测变换的过程:,再将三维形体向XOY面投影,三维投影变换正轴测图,将上述三个变换矩阵相乘得到正轴测变换矩阵:,三维投影变换正等轴测图,正等轴测投影是x、y、z三个方向的轴向伸缩系数相等的正轴测投影,此时有:OA=OB=OC。 推导可得:,三维投影变换正等轴测图,正等轴测投影变换矩阵可写为:,三维投影变换 透视投影,透视投影是中心投影。下图为一点透视投影原理图,XOY为投影面,点P为空间点,p为点p在投影面上的投影。投影中心在Z轴上,且距投影面为d。透视投影的大小与距离d的大小成反比。,三维投影变换 透视投影,透视投影分为一点透视、两点透视和三点透视,通过调整变换矩阵中的p、q、r的取值,可以得到不同的透视图和不同的透视效果。,透视投影由变换矩阵中的透视因子实现。,OpenGL中的变换,OpenGL图形软件包是为三维应用而设计的,包含了大量的有关三维变换的操作。OpenGL中常用的变换包括模型视图变换、投影变换和视见区(视景体)变换。 模型视图变换用于确定场景的位置,实现用户在任意位置、任意方向上进行观察。通过设定观察参考坐标系实现视图变换;通过对模型进行平移、旋转、缩放等,实现模型变换。 投影变换定义了一个观察空间,指定已完成的场景转换成屏幕上显示的最终图像的过程。常用的投影包括平行投影和透视投影。,OpenGL中的变换矩阵堆栈,计算机图形学中,所有的变换都是通过矩阵相乘来实现的。OpenGL中,对象的坐标变换也是通过矩阵来实现的。 OpenGL中包含两个重要的矩阵:模型视图矩阵和投影矩阵。模型视图矩阵用于物体的模型视图变换,投影矩阵用于投影变换。 通过使用函数glMatrixMode(Glenum mode);指定当前操作的矩阵对象的类型。,OpenGL中的变换矩阵堆栈,指定矩阵类型函数的参数mode有两个值: GL_MODELVIEW:表示对模型矩阵进行操作; GL_PROJECTION:表示对投影矩阵进行操作; 一旦设置了当前操作矩阵,它就将保持为当前的矩阵对象,直到再次调用函数glMatrixMode进行修改为止。 默认情况下,系统处理的当前矩阵是模型视图矩阵。,OpenGL中的变换矩阵堆栈,在构造复杂模型时,常常需要通过多个变换调整各部分的大小、方位;或者模拟一个运动机构,需要用不同的变换矩阵来实现各部分自己的运动规律。 为了能保存多次变换的中间过程,以便在进行一些变换后能恢复到某些变换前的状态,OpenGL为模型视图矩阵和投影矩阵各维护着一个矩阵堆栈,栈顶矩阵就是当前的模型视图矩阵或投影矩阵。 矩阵堆栈用于保存和恢复矩阵的状态,主要用于具有层次结构的模型绘制,以提高绘图效率。,层次模型的概念: 在大多数的应用中,都需要方便的创建和操作许多复杂的对象。通常,可以将这些复杂的对象分成一些相对独立的子对象,然后描述这些对象组合成完整对象时需要的规则,据此可以方便地描述、创建和操作复杂对象。,OpenGL中的变换矩阵堆栈,右图为AS3.0中的显示对象的等级结构,是一个典型的层次结构。 在AS中,是通过容器构建显示对象的层次结构的,而在OpenGL中,则是通过矩阵堆栈实现层次结构的模型绘制。,OpenGL中的变换矩阵堆栈,OpenGL中的变换矩阵堆栈,OpenGL实现矩阵堆栈操作的函数: void glPushMatrix(void); void glPopMatrix(void); 函数glPushMatrix将当前堆栈的栈顶矩阵复制一个,并将其压入当前矩阵堆栈。该函数用来保存当前变换矩阵。 函数glPopMatrix用于将当前矩阵堆栈的栈顶矩阵弹出,堆栈中的下一个矩阵变为栈顶矩阵(即当前变换矩阵)。该函数用来恢复当前变换矩阵原先的状态。,OpenGL中的变换模型视图变换,模型视图矩阵是一个4G4阶矩阵,用于指定场景的视图变换(如生产三视图、轴测图等)和几何变换(模型的缩放、旋转、平移等)。 在进行模型视图矩阵操作之前,必须先调用函数 glMatrixMode(GL_MODELVIEW); 指定变换只能影响模型视图矩阵。,OpenGL中的变换模型视图变换,模型视图变换的实现主要有两种方法。 一、直接定义矩阵(p221) 利用函数 void glLoadMatrixfd(const TYPE *m); 将m指定的矩阵置为当前矩阵堆栈的栈顶矩阵。其中,m是指向一个4x4矩阵的指针。 注意:如果矩阵m作用的模型是OpenGL库函数定义的模型,则m矩阵以列优先顺序保存变换矩阵的数据;即前面推导的变换矩阵要转秩。如果模型以顶点数组定义,而顶点数组是按行存储点坐标,则矩阵m以行优先顺序保存变换矩阵的数据。,OpenGL中的变换模型视图变换,设置自定义矩阵的步骤: glfloat m=; glMatrixMode(GL_MODELCIEW); glLoadMatrixf(m); 实例分析:轴测图,mysolid旋转,注意:OpenGL坐标系的XOY平面是正立投影面,因此生成三视图的矩阵与课本中的矩阵有所不同。,OpenGL中的变换模型视图变换,OpenGL坐标系如图所示,在该坐标下下,三视图变换矩阵如下。,1. 主视图,所有点的z坐标为0,变换矩阵为:,OpenGL中的变换模型视图变换,2. 俯视图变换矩阵推导过程如下。 (1) 向XOZ面投影:,OpenGL中的变换模型视图变换,2. 俯视图变换矩阵推导过程如下。 (2)绕X轴旋转90:,OpenGL中的变换模型视图变换,2. 俯视图变换矩阵推导过程如下。 (3) 沿Y轴移动m:,OpenGL中的变换模型视图变换,2. 俯视图变换矩阵推导过程如下。 (4) 三步复合变换后得到在OpenGL屏幕坐标系中俯视图变换矩阵:,OpenGL中的变换模型视图变换,3. 右视图变换矩阵推导过程如下。 (1) 向YOZ面投影:,OpenGL中的变换模型视图变换,3. 右视图变换矩阵推导过程如下。 (2) 绕Y轴旋转-90:,OpenGL中的变换模型视图变换,3. 右视图变换矩阵推导过程如下。 (3)沿x轴移动-l:,OpenGL中的变换模型视图变换,3. 右视图变换矩阵推导过程如下。 (4) 三步复合变换后得到在OpenGL屏幕坐标系中右视图变换矩阵:,OpenGL中的变换模型视图变换,二、利用高级矩阵函数 在OpenGL中,还可以通过一些高级矩阵函数实现模型的平移、旋转和缩放。高级矩阵包括: glTranslategf(TYPE x, TYPE y, TYPE z); glRotate df(TYPE angle, TYPE x, TYPE y, TYPE z); glScale df(TYPE x, TYPE y, TYPE z);,glTranslatedf(x, y, z,): 把当前矩阵(如顶点坐标矩阵)与平移变换矩阵相乘。三个参数为x, y, z三个方向的平移量。如果参数值为浮点数,则函数名写为glTranslatef;参数值为双精度数,则函数名写为glTranslated; glRotatedf(angle, x, y, z): 把当前矩阵(如顶点坐标矩阵)与旋转变换矩阵相乘。Angle参数表示旋转角度,从原点到点(x, y, z)的有向连线为旋转轴,逆时针方向为正角度方向。,OpenGL中的变换模型视图变换,glScalefd(x, y, z,): 把当前矩阵(如顶点坐标矩阵)与比例变换矩阵相乘。三个参数分别为x, y, z三个方向的比例因子。,OpenGL中的变换模型视图变换,OpenGL中的变换模型视图变换,调用矩阵函数绘制模型视图时,后调用的矩阵将成为新的当前模型视图矩阵,并影响此后绘制的图形,会造成变换效果的累积。如果不需要这样的累积,可以调用重置矩阵函数: glLoadIdentity(void); 该函数将单位矩阵设置为当前变换矩阵。一般在指定当前操作矩阵对象后,都要调用重置矩阵函数,将之前变换的影响消除。,视图变换主要用于确定观察参考坐标系,即确定视点的位置和观察方向。 也可以通过函数gluLookAt调整视点位置,以达到观察立体不同侧面的效果。 gluLookAt(xe, ye, ze, xo, yo, zo, xu, yu, zu) 该函数有3组共9个参数,第一组3个参数,指定视点(相机镜头)在x、y、z三个方向的坐标;第二组3个参数指定视点(镜头)瞄准的点坐标;第三组3个参数,指定朝上的向量。(注意:朝上矢量不能与视线矢量重叠),OpenGL中的变换模型视图变换,OpenGL中的变换投影变换,OpenGL提供了两种投影方式:一种是正投影,一种是透视投影。通过调用不同的函数实现不同的投影变换。 为避免不必要的变换发生,必须调用 glMatrixMode(GL_PROJECTION) 指定当前处理的矩阵是投影变换矩阵。 例如: glMatrixMode (GL_PROJECTION); glLoadIdentity(); glOrtho (-3.0, 3.0, -3.0, 3.0, -10.0, 10.0);,OpenGL中的变换投影变换,一、正投影变换 正投影变换由函数glOrtho()实现。该函数创建一个正交平行的视景体。在该视景体中产生三维物体的平行投影。如果没有其它变换,比如旋转等,投影方向为z轴负方向。 glOrtho()函数创建了一个有限的观察空间,空间的六个边界面为裁剪面。,“轴测图”例程修改视景体裁剪面观察裁剪效果。,OpenGL中的变换投影变换,二、透视投影变换 透视投影的特点是物体的视图有近大远小的效果。OpenGL透视投影函数有两个: 1. glFrustum(): 该函数指定的透视视景体 如图为所示。,glFrustum(left, right, bottom, top, near, far); 函数的六个参数分别定义了该视景体的left, right, bottom, top, near及 far的数值。 视点位于坐标系原点。,2. gluPerspective(): gluPerspective()函数指定投影变换方式为透视变换,通过不同的参数定义透视视景体。 下图为gluPerspective()函数指定的透视视景体。 视点位于坐标原点。,OpenGL中的变换投影变换,gluPerspective()有4个参数: gluPerspective(fovy, aspect, near, far); fovy:为yoz平面上的视角,取值范围为0.0, 180.0; aspect:为视景体的纵横比; near和far:分别是观察点与视景体的前后裁剪面的距离。,OpenGL中的变换投影变换,投影变换OpenGL的三维坐标变换,例:太阳系(变换矩阵堆栈实现模型变换),glMatrixMode(GL_MODELVIEW); glLoadIdentity(); gluLookAt (0.0, 0.0, 5.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0); glPushMatrix(); glutWireSphere(1.0, 20, 20); /* draw sun */ glRotatef (GLfloat) year, 0.0, 1.0, 0.0); glTranslatef (2.0, 0.0, 0.0); glRotatef (GLfloat) day, 0.0, 1.0, 0.0); glutWireSphere(0.2, 10, 10); /* draw earth*/ glPopMatrix();,投影变换OpenGL的三维坐标变换,例:太阳系(投影变换),glMatrixMode (GL_PROJECTION); glLoadIdentity (); glOrtho (-3.0, 3.0, -3.0, 3.0, 1.0, 20.0); /*或者 gluPerspective(60.0, (GLfloat) w/(GLfloat) h, 1.0, 20.0); 观察:视点位置不变时,平行投影和透视投影的视觉效果的不同。在两种投影方式时修改gluLookAt函数视点坐标的效果。,投影变换OpenGL的三维坐标变换,例:机械臂 机械臂由两部分(上、下臂)组成,希望实现上下臂的共同旋转和下臂的独立旋转。 1. 设定投影矩阵参数和调整物体的基本位置: glMatrixMode (GL_PROJECTION); glLoadIdentity (); gluPerspective(65.0, (GLfloat) w/(GLfloat) h, 1.0, 20.0);/设定投影矩阵 glMatrixMode(GL_MODELVIEW); glLoadIdentity(); glTranslatef (0.0, 0.0, -5.0); /将模型移远5个单位。因为OpenGL库函数定义的模型中心点都在原点,透视投影变换视点也在原点处,不调整原点位置无法观察模型。,投影变换OpenGL的三维坐标变换,2. 绘制上、下臂 调用glutWireCube (1.0)函数绘制的立方体,通过glScalef函数改变长宽高的比例。 glPushMatrix(); glScalef(2.0, 0.4, 1.0); glutWireCube (1.0); glPopMatrix(); 比例变换只作于改变形体的长宽比,不能影响其它运动,因此需要glPushMatrix();和glPopMatrix();函数来限制变换矩阵的影响范围。 下臂绘制也如此。,投影变换OpenGL的三维坐标变换,3. 调整上臂旋转中心 glTranslatef (-1.0, 0.0, 0.0); /将旋转中心沿x轴方向移-1 glRotatef (GLfloat) shoulder, 0.0, 0.0, 1.0); /实现以点(-1,0,0)为基点的绕z轴的旋转 glTranslatef (1.0, 0.0, 0.0); /消除前一个平移变换对立体位置的影响, 即长方体的中心仍保持在原点。,投影变换OpenGL的三维坐标变换,3. 调整下臂旋转中心 glTranslatef (1.0, 0.0, 0.0); /将立体沿x轴方向平移1 glRotatef (GLfloat) elbow, 0.0, 0.0, 1.0); /实现以点(1,0,0)为基点的绕z轴的旋转 glTranslatef (1.0, 0.0, 0.0); /将立体再沿x轴方向平移1 注意:调整上臂旋转中心的所有变换矩阵与调整下臂旋转中心的所有变换矩阵在同一对glPushMatrix()和glPopMatrix()函数内,因此角度为GLfloat) shoulder的旋转也作用于下臂,实现按下s键时上下臂一起旋转。,
展开阅读全文