坐标变换 及矩阵变换

为了对一个点进行变换(平移、伸缩、旋转等),可以用一个4  ×  4 的的变换矩阵来表示,如最常见的是使用一个模型视图变换矩阵,来变换点、线、多边形以及其它几何体,也可以变换多边形表面的切向量。变换思路如下:设置一个4  ×  4 的矩阵中元素的值,使其表示某一具体的变换。然后将某一点的坐标或者某一向量的分量放入一个1  ×  4 的行向量 v 中。乘积 vX 就生成了经过变换的向量 v˜ ,例如,如果 X 表示沿着 x 轴平移10个单位, v=[2,6,3,1] ,则乘积 vX=v˜=[12,6,3,1]

前面提到了将某一点的坐标或者某一分量的各分量放入一个1  ×  4的行向量 v 中。但是在几何学中,表示3D空间中的某点信息是使用3个分量(XYZ)来表示的!为了使向量-矩阵相乘有意义,我们必须将3D的点或向量拓展为4D行向量。

如何使用第四个分量?这个分量我们用w表示,其中w叫做齐次坐标。取值为0或者1。当W分量为1时,是为了保证点的平移变换能正确进行。而对于向量,没有必要进行平移变换,而将W分量设为0是为了防止对向量实施平移变换。

PS:

拓展后的4D向量被称为齐次向量,因此齐次向量即可以表示点,也可以表示向量,所以注意本文提到的名词“向量时,注意区分我指的是点还是向量,一般来说,下文提到的”向量“时,基本上指代的是点。

有时,我们所定义的矩阵改变了一个向量的分量w的值(即 w0  且 w1 )如下所示:

P=[p1,p2,p3,1]1000010000100010=[p1,p2,p3,p3]=P 对于 p30 p31 的情况

可见, w=p3 。当 w0 w1 时,就称该变量处于齐次空间中,以区别3D空间。将齐次空间的向量映射回3D空间的方法是:用w分量去除该齐次向量的每一个分量。例如将齐次空间的向量 (x,y,z,w) 映射回3D向量x的方法如下:

[xwywzwww]=[xwywzw1]=[xwywzw]=X

在进行3D编程是,如果涉及到透视投影,则经常需要将向量由齐次空间映射到3D空间。该操作发生在顶点变换步骤的透视除法环节。在OpenGL中,一个典型的顶点变换步骤如下:

可见,对顶点的变换都是通过矩阵来完成的,下面讨论模型视图矩阵的具体形式。

平移矩阵

要想将向量(x,y,z,1)沿着 x 轴平移 px 个单位,沿着 y 轴平移 py 个单位,沿着 z 平移 pz 个单位,只需要将该向量与如下矩阵相乘:

T(p)=100px010py001pz0001

该平移矩阵的逆矩阵可以简单地对平移向量p取负得到。

T1=T(p)=100px010py001pz0001

旋转矩阵

我们可以用如下3个矩阵将一个向量分别绕着x,y,z轴旋转 θ 弧度。当沿着旋转轴指向原点的方向观察时,角度是按顺时针方向度量的。

X(θ)=10000cosθsinθ00sinθcosθ00001

Y(θ)=cosθ0sinθ00100sinθ0cosθ00001

Z(θ)=cosθsinθ00sinθcosθ0000100001

旋转矩阵R的逆矩阵与其转置相等,即 RT=R1 。俱备这样特点的矩阵称为正交矩阵。

比例变换矩阵

如果想让一个向量沿着x、y、z轴分别放大 qx qy qz 倍,可令该向量与如下矩阵相乘:

S(p)=qx0000qy0000qz00001

如果将比例矩阵的各个缩放因子取倒数,就得到该矩阵的逆矩阵。

S1=S(1qx,1qy,1qz)=1qx00001qy00001qz00001

几何变换的组合

经常需要对向量实施一系列的变换。例如我们可能先对向量进行缩放,然后在进行旋转,最后平移到所期望的位置。

这个过程的每一步都是通过让向量乘以一个矩阵来实现,矩阵的一个最关键的优点是,可以借助矩阵乘法将几种变换组合到一个变换矩阵。

例如,当我们先对向量p实施比例变换,乘以比例变换矩阵S;在对变换后的向量实施旋转变换,乘以旋转变换矩阵R:最后对变量实施平移变换,乘以平移变换矩阵T,最后得到向量 p′′′

pSpRyp′′T===pp′′p′′′

我们可以向全部的变换组合为一种变换,然后应用该变换,得到向量 p˜

SRyTpQ==Qp˜

则可以验证: p′′′=p˜

法线的变换矩阵

在着色器中执行光照计算时,不仅需要我们指定顶点坐标,还需要我们去指定法线向量。对于顶点坐标,在着色器中对其施加模型视图变换和投影变换即可得到变换后的顶点坐标,但是对于法向量的变换矩阵却与顶点的变换矩阵不一样!

这是因为法线向量会随着我们的平移和旋转发生变化。比如说,如果我们忽略旋转并且假设做了一个(0,0,-5)的平移,那么法线向量(0,0,1)就会变成(0,0,-4),这不仅长度不对而且根本就指向了错误的方向!这里也许我们可以将法线向量的w分量设为0,这样就可以忽略掉那些移位变换。但是不幸的是,当模型视图矩阵包含不同的空间变换时,尤其是缩放和扭曲时,它将不再有用。比如说,如果模型视图矩阵将我们要绘制的物体放到两倍大小,那法线向量也会被拉伸,即使我们将w分量设为0。这会导致严重的光照错误。

在OpenGL中计算法线向量的变换矩阵的方法是:先求出模型视图矩阵的逆矩阵,然后再对求出的逆矩阵转置。这样就可以得到正确的变换矩阵。这样可以去掉矩阵中非正交的因素。

证明方法如下:

假设世界坐标系(未变换前)中的某条切线向量是T,法线向量是N。那么由他们是垂直的可得到: TTN=0

假设他们变换到视图坐标系中后分别是 T N 。那么他们应该仍然是相互垂直的: TTN=0

假设切线向量和法线的变换矩阵为M、G。则有: (MT)T(GN)=0

进一步推出: TTMTGN=0

由于 TTN=0 ,因此我们猜想 MTG=0 .因此:

G=(M1)T

即:应用于法线向量的变换矩阵是顶点变换矩阵的逆转置矩阵。

注意,在上面求证法线的变换矩阵的时候,是讨论OpenGL中的情况,在OpenGL中,对某一顶点实施变换时,是通过一个矩阵乘以顶点实现的,即 Mv=v ,其中,M是变换矩阵,v和 v 分别是变换前后的顶点。所以对于上面的证明过程有 MT=T 而不是 TM=T .

由于刚才提到的原因,所以在使用OpenGL编程时,我们用代码制定了一系列变换,但是最后指定的变换会最先应用到顶点上。

考虑下面的代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
glMatrixMode(GL_MODELVIEW);
 
glLoadIdentity();
 
glMultMatrixf(N);
 
glMultMatrixf(M);
 
glMultMatrixf(L);
 
glBegin(GL_POINTS);
 
glVertex3f(v);
 
glEnd();

经过变换之后的顶点是 NMLv ,也就是说,v首先与L相乘, Lv 的结果再与M相乘, MLv 再与N相乘,顶点v的变换是按照相反的顺序发生。

**********************************


参考:

《DirectX 9.0 3D游戏开发编程基础》

《OpenGL编程指南 第七版》

OpenGL法线变换详解

3D变换中法向量变换矩阵的推导


几何变换详解[转]  

2012-10-23 10:59:44|  分类: 图形学|举报|字号 订阅

在三维图形学中,几何变换大致分为三种,平移变换(Translation),缩放变换(Scaling),旋转变换(Rotation)。以下讨论皆针对DirectX,所以使用左手坐标系。

平移变换

将三维空间中的一个点[x, y, z, 1]移动到另外一个点[x', y', z', 1],三个坐标轴的移动分量分别为dx=Tx, dy=Ty, dz=Tz, 即

x' = x + Tx

y' = y + Ty

z' = z + Tz

平移变换的矩阵如下。

缩放变换

将模型放大或者缩小,本质也是对模型上每个顶点进行放大和缩小(顶点坐标值变大或变小),假设变换前的点是[x, y, z, 1],变换后的点是[x', y', z', 1],那么

x' = x * Sx

y' = y * Sy

z' = z * Sz

缩放变换的矩阵如下。

旋转变换

这是三种变换中最复杂的变换,这里只讨论最简单的情况,绕坐标轴旋转,关于绕任意轴旋转,在后续的随笔中介绍。

绕X轴旋转

坐标变换 及矩阵变换_第1张图片

绕X轴旋转时,顶点的x坐标不发生变化,y坐标和z坐标绕X轴旋转θ度,旋转的正方向为顺时针方向(沿着旋转轴负方向向原点看)。[x, y, z, 1]表示变换前的点,[x', y', z', 1]表示变换后的点。变换矩阵如下。

关于旋转的正方向,OpenGL与多数图形学书籍规定旋转正方向为逆时针方向(沿着坐标轴负方向向原点看),比如Computer Graphics C Version,p409。

绕Y轴旋转

坐标变换 及矩阵变换_第2张图片

绕Y轴旋转时,顶点的y坐标不发生变化,x坐标和z坐标绕Y轴旋转θ度。[x, y, z, 1]表示变换前的点,[x', y', z', 1]表示变换后的点。变换矩阵如下。

绕Z轴旋转

坐标变换 及矩阵变换_第3张图片

绕Z轴旋转时,顶点的z坐标不发生变化,x坐标和y坐标绕Z轴旋转θ度。[x, y, z, 1]表示变换前的点,[x', y', z', 1]表示变换后的点。变换矩阵如下。

绕坐标轴旋转的矩阵推导

上面三个旋转矩阵是如何得来的呢?我们推导一下,首先看一下二维的情况,再扩展到三维即可。实际上上面三种绕坐标轴旋转的情况属于特殊的二维旋转,比如绕Z轴旋转,相当于在与XOY平面上绕原点做二维旋转。

假设点P(x, y)是平面直角坐标系内一点,其到原点的距离为r,其与X轴的夹角为A,现将点P绕原点旋转θ度,得到点P'(x', y'),P'与X轴的夹角为B,则A = B - θ。(注意,在二维坐标中,逆时针旋转时角度为正,顺时针旋转时角度为负,下图中由P旋转到P',角度为θ,若是由P'转到P,则角度为-θ)。

坐标变换 及矩阵变换_第4张图片

 

于是可得下面的转换方程

(式一)

写成矩阵的形式就是

求得旋转矩阵为

由于这里使用齐次坐标,所以还需加上一维,最终变成

和前面给出的绕Z轴旋转矩阵完全吻合。

对于绕X轴旋转的情况,我们只需将式一中的x用y替换,y用z替换,z用x替换即可。替换后得到

(式二)

对应的旋转矩阵为

对于绕Y轴旋转的情况,只需对式二做一次同样的替换即可,的到的变换方程为

对应的变换矩阵为

== Happy Coding ==


你可能感兴趣的:(数学图形,图形学)