学习OpenGL-ES: 4 - 坐标系变换(平移)

1,前言:

接下来将是数学系列,将主要讲解一些初学者比较难以理解的内容,并假设读者已经熟悉了基本的向量和矩阵运算以及其几何意义。为了简单化,某些数学概念不甚严谨,但不妨碍学习和理解。

在上一篇文章《学习OpenGL-ES: 3 - 3D绘图原理》中,我们知道绘制3D图形,首先需要描述物体:

  a, 我们需要描述物体位置,也经常需要平移物体,平移是指物体的形状和朝向都不变,只是位置改变。我们通过对物体的所有顶点进行相同的平移来完成这个过程,我们称之为对物体(顶点)进行平移变换,这个变换在计算机图形学中是通过用顶点坐标乘以一个4X4矩阵来完成的,顶点乘以矩阵,得到一个新的顶点,这个新的顶点就是原顶点平移后的结果,我们称这个矩阵为平移变换矩阵。

  b, 与此类似,我们通过用顶点坐标旋转变换矩阵来旋转物体,进行旋转变换。

  c,通过缩放变换矩阵来对物体进行缩放变换。

平移、旋转、缩放是最常见的变换,我们将在随后的几篇文章中分别讲解,先来看平移变换:

2,坐标系(标架):

坐标系由原点和三个正交向量定义,三个正交向量称为一般称为坐标轴,相交于原点。由于位置总是相对的,所以坐标系A总是在某个坐标系B中进行描述:我们把最顶层的坐标系称为世界坐标系,我们总是从这个坐标系出发去描述其它的坐标系。定义世界坐标系原点 [0,0,0], x轴[1,0,0],y轴[0,1,0],z轴[0,0,1]

3, 点和向量:

向量有大小和方向,但没有位置,指定坐标系,向量总是可以由三个坐标轴的线性表示来构造,比如向量V [x, y, z] = x*[1,0,0] + y*[0,1,0] + z[0,0,1]; 对于向量来说,只需要三个坐标轴(基)就可以定义(向量空间),和原点无关。

点描述了3维空间中的位置,为了在向量空间中描述点(位置),引入了原点的概念,所有点都相对于原点进行描述(仿射空间)。

点和向量相加得到另一个点(想象一下点P沿着向量的方向移动向量的长度,其目的地就是新的点),两点相减得到一个向量。在给定坐标系中的任意点P,都可以通过原点P0和从P0指向P的向量V定义:P = P0 + V;同样 V = P - P0; 而每个向量又能由三个坐标轴的线性表示构造,所以每个点总能由原点 + 三个坐标轴的线性表示构造:

P = P0 + V = P0 + (ax + by + cz) = P0 + (a*[1,0,0] + b*[0,1,0] + c*[0,0,1]); 其中a\b\c为标量,x\y\z分别代表三个坐标轴向量,V代表从原点出发,指向P的向量。

另外,由于原点的坐标总是[0,0,0],所以P = P0 + V = [0,0,0] + V[x,y,z] = [x,y,z],注意:点和向量并不等同,此处只是在数值上相等,务必要分清。

4,多坐标系:

虽然点和向量的抽象定义和坐标系无关,无论有没有坐标系,点和向量总是存在于空间中,但当我们描述(表示)以及计算它们的时候,必须先给定一个坐标系。同一个点在不同的坐标系中有不同的表示,同一个向量在不同的坐标系中也有不同的表示。而坐标系由一个点(原点P0)和三个向量(Vx,Vy,Vz)定义,将其视为四元组[P, V, V, V], 所以同一个坐标系,在不同的坐标系中也有不同的表示。

5,平移变换的两种思考方式:

  描述平移,需要描述平移的方向和距离,而向量具有方向和大小,所以我们可以用向量来描述一个平移,沿着向量V的方向移动向量长度的距离,我们称之为沿着V平移。

  a, 移动点:

  这是最自然的想法,有一个点P,移动V,则移动后的新点为P + V(回想一下,点 + 向量 = 点)。

  b,移动坐标系:

  移动坐标系和移动点是可互换的对偶过程。把一个点P移动一段距离,等同于保持点不动,把坐标系反方向移动相同的距离,然后在这个新坐标系中描述P,也就是计算P在新坐标系中的坐标。

  c,其它变换:

  事实上,所有变换都可以表述为变换点和变换坐标系这两种等价的方式。在某些时刻,用一种表述(思考)方式会比另一种更合适,无论用那种方式,我们总可以通过一个逆变换转变到另外一种方式,后面将看到这点。

6,由平移产生一个新坐标系

世界坐标系,原点 [0,0,0], x轴[1,0,0],y轴[0,1,0],z轴[0,0,1],我们把世界坐标系沿x的正方向移动1单位,也就是沿着向量[1,0,0]平移,可以得到一个新的坐标系,那么这个新坐标系在世界坐标系中的表示是什么呢?回想一下,一个坐标系由原点和三个坐标轴决定,因此移动坐标系,也就是移动原点和坐标轴,让我们依次进行计算:

  先计算原点: 原点沿向量[1,0,0]平移,所以新的原点为:[0,0,0] + [1,0,0] = [1,0,0];

  再计算坐标轴:先考虑x轴,x轴为向量,向量没有位置,只有方向和大小,而在平移中,x轴的方向和大小都没有发生变化,所以x不变,同理y和z也不变。

  所以,新坐标系在世界坐标系中的表示:原点 [1,0,0], x轴[1,0,0],y轴[0,1,0],z轴[0,0,1]

可以得出这样一个结论:所有对坐标系的平移只影响原点,不影响坐标轴。

7,计算同一个点在平移后的新坐标系中的坐标

点P,在世界坐标系中坐标为[1,2,3],在第5小节生成的新坐标系中,这个点的坐标是多少?

移动坐标系,等于逆向移动点,因此坐标系平移V[1,0,0],等同于点平移-V = [-1,0,0],所以,平移后的点为:P + (-V) = [1,2,3] + [1,0,0] = [0,2,3].

那么,假设在新坐标系中的一个点[1,2,3],在世界坐标系中的坐标P2是多少呢?首先将新坐标系移回原位置(和世界坐标系重合),需要沿-V移动,所以对坐标系来说,平移-V,对点来说则平移-(-V) = V,则 P2 = [1,2,3] + V = [1,2,3] + [1,0,0] = [2,2,3].

8,用矩阵进行平移变换

如同之前所述,我们可以用向量来描述平移变换,对一个物体进行平移V,等价于对这个物体所有的点P进行这样的运算: P + V

但是,我们往往需要对物体进行各种变换组合,比如:先平移V,再绕X轴旋转100度,再均匀缩放10倍,再平移V。。。所以如果有一种统一的描述和计算方式来表示所有的变换,对于理解、计算、硬件设计都有很大的好处,计算机图形学中使用4X4矩阵来表示所有的变换,因此矩阵是一种用来进行各种变换的数学工具。那么矩阵是怎样进行变换的呢? 

所谓变换,本质上可看做一个函数(映射),假设这个函数为T(),则对于一个顶点P,T(P)将输出一个新的顶点P1,这个顶点就是经过T变换的结果,而T的实现,实际上是拿顶点乘以一个矩阵M,也就是P1 = P X M. 对每一种变换都有一个对应的函数T,也都有一个对应的矩阵M,所以一系列的变换可以描述为:P1 = P X M平移 X M旋转 X M缩放 X M平移 = P平移 X M旋转 X M缩放 X M平移 = P平移+旋转 X M缩放 X M平移 = 。。。

而矩阵乘法满足结合率,所以P X M平移 X M旋转 X M缩放 X M平移 = P X (M平移 X M旋转 X M缩放 X M平移) = P X M连乘矩阵 

 那么,用矩阵进行平移变换,关键就是构造一个矩阵M,令P X M  = P + V。注:在OpenGL ES中,使用4X4齐次坐标矩阵,右手坐标系,列主序,向量右乘。关于左/右手坐标系,行/列主序,向量左/右乘,向量和矩阵元素在内存(数组)中的顺序等,都是初学者容易迷惑的地方,后续将有一篇文章专门对此进行讲解。本文为了书写方便,使用行主序和向量左乘.

假设将点[1,2,3]沿向量[4,5,6]进行平移,我们可以得出平移结果为[1,2,3] + [4,5,6] = [5,7,9],以下为对应的平移变换矩阵:

      1,0,0,0

[1,2,3,1] X 0,1,0,0 = [5,7,9,1]

      0,0,1,0

      4,5,6,1

[1,2,3,1]称之为点[1,2,3]的齐次坐标表示,其中第四个分量一般称为w分量,对3D来说,齐次坐标只是一种数学技巧,用来将各种变换统一为一种矩阵表示(3X3矩阵无法表示仿射变换,平移变换属于仿射变换),齐次坐标可参考之前文章中推荐的书籍(学习OpenGL-ES: 0 - 方法和资料),此处不再赘述。

观察上述矩阵,发现第四行为[4,5,6,1],恰为平移向量V的齐次坐标表示,因此沿向量V[X,Y,Z]平移的平移变换矩阵可构造如下;

  1,0,0,0

  0,1,0,0

  0,0,1,0

  X,Y,Z,1

9,总结:

对3D世界中的物体进行平移,就是对其所有顶点P进行相同的平移,这个平移可以通过一个平移向量V[X,Y,Z]描述,也可以通过一个平移变换矩阵M描述,平移变换的结果P1 = P +V = P X M。M是如下形式的4X4矩阵:

  1,0,0,0

  0,1,0,0

  0,0,1,0

  X,Y,Z,1

posted on 2013-02-23 15:22  kiffa  阅读(5615)  评论(0编辑  收藏  举报

导航