由正交矩阵构建的仿射变换矩阵求逆的快速算法
Posted lonelyxmas
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了由正交矩阵构建的仿射变换矩阵求逆的快速算法相关的知识,希望对你有一定的参考价值。
原文:由正交矩阵构建的仿射变换矩阵求逆的快速算法原文地址http://blog.csdn.net/i_dovelemon/article/details/45827953
齐次坐标
我们都知道,在3D图形学中,所有的变换都可以划分为三种最基础的变换方式,分别为:
- 旋转变换
- 缩放变换
- 平移变换
通过对这三种变换进行组合,就能够实现任意的变换形式。
在3D坐标下,如果向量使用3D向量表示的话,对于这三种变换的处理方式如下:
- 旋转变换:乘法运算
- 缩放变换:乘法运算
- 平移变换:加法运算
也就是说,这三种变换的处理方式是不同的,旋转和缩放变换能够通过乘法实现,而平移需要通过加法来实现。
所以图形学的大师们,觉得这样的计算方法十分的繁琐,他们希望能够使用一种统一的方式来对坐标进行变换。所以他们决定,将平移变换也使用乘法来统一这种计算方法。
所以,就提出了齐次坐标的概念。
齐次坐标,即使用N+1维的空间向量来表示N维的向量。通过这样的方法就能够使用乘法对平移变换也进行计算。
而平移变换对向量是没有用处的,只有对点才有用。所以就出现了齐次坐标(x,y,z,w),其中当w等于1的时候,表示的是点向量,0的时候,表示的就是普通向量。
仿射变换
在明白了齐次坐标之后,我们来看看什么是仿射变换。
从学习3D以来,就经常听到说3D图形学里面的变换都是仿射变换。以前也查过这个概念,但是过不了多久就忘记了。主要就是因为没有深刻的理解到这个概念的意义,所以就很容易遗忘掉它。直到今天遇到了问题,才深刻的理解仿射变换时什么样的变换。
仿射变换的定义如下:先进行线性变换,在进行平移变换的变换称之为仿射变换。注意这个定义里面,具有先后关系,我就是忽略了这个先后关系才对很多变换,搞的迷迷糊糊的。
在3D中,所谓的线性变换,指的就是旋转变换和缩放变换这两种。也就是说,我们在3D游戏开发中,使用的矩阵变换,实际上是一种仿射变换,它会先对向量进行旋转和缩放(这两种变换的先后顺序,无关紧要),然后在对向量进行平移操作。
这就是仿射变换的定义。一定要牢记,仿射变换时具有先后关系的两种变换的联合。
正交矩阵
在学校学习线性代数的时候,那时候还是很清楚什么是正交矩阵。但是抛去了课本,就忘记了什么是正交矩阵。依稀只记得好像是任意两个行向量相乘的结果为0,也就是相互垂直的关系。今天也一直以这个定义来推导正交矩阵求逆运算的简化步骤,发现总是得不出正确的结果。所以,就重新学习了下什么是正交矩阵。
正交矩阵的定义:
a.矩阵中的任意两个行向量的乘积为0b.矩阵中每一个行向量都是单位向量
没有经过缩放的旋转矩阵就是一个正交矩阵。
3D图形中求逆的几何意义
数学上对矩阵的求逆运算,在学习线性代数的时候,一直就不知道为毛搞这么一个东东。(这也体现了中国填鸭式教育,先交给你是这么做,至于为什么这么做,以后才知道)直到自己学习游戏开发,特别是进行3D变换的时候,才明白了。
在3D中,变换都是通过矩阵来实现的。比如一个矩阵的功能是先让某个向量旋转A角度,在平移B距离。那么这个矩阵的逆矩阵的效果就应该是先让向量平移-B距离,然后在旋转-A角度。也就是说,矩阵和它的逆矩阵对向量进行的变换效果是相反的过程。
矩阵乘法
在学习3D游戏编程的过程中,经常会遇到一个问题,在解决某种变换的时候,网上给出这个变换的矩阵总是有两种不同的格式,他们互为转置。我以前一直不明白怎么回事。直到自己在学习OpenGL(先学DirectX)之后,才明白原来是两个标准3D API对于向量的定义方式不同导致的。
当我们讲解某个变换的时候,作者大多使用自己熟悉的方式来进行讲解。熟悉DirectX的人,会使用行向量的方式对矩阵进行描述,熟悉OpenGL的人,会使用列向量的方式对矩阵进行描述。所以就会导致出现两个相互为转置的矩阵出现。
比如说,在DX中,一个向量实际上是这样的:[x,y,z,w]
它在进行矩阵乘法的时候,是这样的:[x,y,z,w] * M (右乘矩阵的方式)
而对于OpenGL来说,它的向量表示是这样的:
[x,
y,
z,
w]
它在进行矩阵乘法的时候,是这样的:
M * transpose[x,y,z,w] (左乘矩阵的方式)
所以,这就导致了理解上的偏差。初学者最好弄明白这些基础的概念。
正交矩阵求逆
前面讲了一大堆,就是为了得出怎么样快速的求出一个正交矩阵的逆矩阵出来。
这里统一使用OpenGL的矩阵表示方法。
假如有一个矩阵:
[m00 m01 m02 m03]
[m10 m11 m12 m13]
[m20 m21 m22 m23]
[0 0 0 1]
在3D中这个矩阵有两个不同的部分构成,
一个是:
[m00 m01 m02]
[m10 m11 m12]
[m20 m21 m22]
的旋转矩阵R(由于是正交矩阵,这里就只能是未进行缩放的单位向量的正交旋转矩阵)
另外一个就是:
[1 0 0 m03]
[0 1 0 m13]
[0 0 1 m23]
[0 0 0 1]
的平移矩阵
这两个部分构成。
也就是可以简化为如下的矩阵表示:
[R T] * V
[0 0 0 1]
前面说过,要想求一个矩阵的逆矩阵,就是构造一个具有相反效果的矩阵即可,那么上面的矩阵是一个仿射矩阵,它是先进行R旋转,然后在进行T平移操作,所以它的逆操作就应该是:
先平移-T,然后在旋转-R
所以得出下面的矩阵:
[Transpose_R] * [Transpose_T]
[0 0 0 1] [0 0 0 1]
由于R是正交矩阵,正交矩阵有一个特性:
正交矩阵的逆矩阵等于转置矩阵
所以就能够很直观的得出正交矩阵构成的仿射矩阵的逆矩阵了。
以上是关于由正交矩阵构建的仿射变换矩阵求逆的快速算法的主要内容,如果未能解决你的问题,请参考以下文章