Real-Time Rendering 4th 译文《四 坐标变换 上 》

第四章 变换

[个人感觉本章先了解各种基础变换的概念和矩阵表示即可,后面的矩阵公式的推导可以等到后面,再回过头来看]
变换是一种将点,向量或颜色之类的实体以某种方式转换他们的一种操作。对于计算机图形从业者来说,掌握变换是非常重要的。有了它们,你可以定位、重塑和移动物体、灯光和照相机。你还可以确保所有计算都在同一坐标系中进行,并且以不同的方式将对象投影到平面上。这里只是少数可以通过变换执行的操作,但是这已经充分说明了变换在实时图形或任何类型计算机图形中的重要性。

线性变换是保留向量加法和标量乘法的变换。具体来说:
在这里插入图片描述
举个例子, 是一个使向量每个元素乘以 5 的变换。为了证明这是线性的,需要满足两个条件(公式 4.1 与 公式 4.2)。第一个条件成立,因为任何两个向量乘以 5 然后相加就等于将向量相加然后再相乘。第二个标量乘法条件(公式 4.2)已经明显是满足的。此函数我们称为缩放变换,因为它可以更改对象的缩放比例(大小)。旋转变换是另一个线性变换,它可使向量绕原点旋转。包括缩放和旋转变换,实际上三维向量的所有线性变换,都可以使用 3 × 3 矩阵表示。

然而,矩阵的大小通常不够大。三维向量 x的函数,例如f(x)=x+(7,3,2)是非线性的。在两个单独的向量上执行此函数将把(7,3,2)的每个值相加两次。这种将定值向量加到另一个向量上的操作称为平移,它会将位置移动相应的值。平移是一种很有用的变换类型,接下来我们将组合各种变换,例如,将对象缩放到一半大小,然后将其移动到其他位置。此时我们会发现,将函数保持为简单形式是很难轻松地进行组合的。

我们可以使用仿射变换将线性变换和平移结合起来,仿射变换通常存储为 4 × 4 矩阵。仿射变换是先执行线性变换然后执行平移变换。为了表示四维向量,我们使用齐次表示法,以相同的方式表示点和方向(使用粗体小写字母)。方向向量表示为v=(vx,vy,vz 0) T,点表示为v=(vx,vy,vz 1) T [点为1,向量0]。在本章中,我们将广泛使用在 realtimerendering.com 上可下载的线性代数附录中解释的术语和运算。

所有平移,旋转,缩放,反射和剪切矩阵都是仿射(affine)的。仿射矩阵的主要特征就是它保留了线的平行性,但不一定保留长度和角度。仿射变换也可以是任何单个仿射变换矩阵按照顺序的组成。

本章将从最根本的基本仿射变换开始。本部分可以看作是简单变换的“参考手册”。之后,我们会描述一些专用的矩阵,随后对四元数)——一种强大的变换工具,进行讨论和描述。然后是顶点融合和变形,这是表达网格动画的两种简单但有效的方法。最后,描述了投影矩阵。这些变换中大多数,它们的符号,功能和特性都总结在 表 4.1 中,其中正交矩阵(A矩阵与A的转置矩阵成绩为单位矩阵)的逆矩阵为其转置矩阵。

变换是用于操纵几何体基本工具。大多数图形应用程序编程接口允许用户设置任意矩阵,有时库可能与实现本章讨论的许多变换的矩阵运算一起使用。但是,仍然有必要了解函数调用背后的实际矩阵及其相互作用。知道调用函数后矩阵做了什么是一个开始,但是了解矩阵本身的属性将使你的理解更进一步。例如,这种理解可以使你辨别何时处理正交矩阵(正交是其转置),从而可以更快地进行矩阵求逆。这样的知识可以让你的代码更加高效。

4.1 基本变换 Basic Transforms

本节介绍最基本的变换,例如平移,旋转,缩放,剪切,连续变换,刚体变换,法线变换和求逆。对于有经验的读者,可以将其用作简单变换的参考手册,对于新手,则可以作为该主题的入门。本材料是本章其余部分和本书其他各章的必要背景。我们从最简单的变换——“平移”开始。
在这里插入图片描述

4.1.1 平移 Translation

从一个位置到另一个位置的变化由平移矩阵T表示。此矩阵通过向量 ,去平移实体。T由下面的 公式 4.3 给出:
qqq
图 4.1 显示了平移变换效果的示例。容易证明,将点P=(Px,Py,Pz,1) 与T(t)相乘会产生一个新的
点P’(Px+tx,Py+ty,Pz+tz,1), 这显然是一个平移。请注意,向V=(Vx,Vy,Vz,0) 不受T(t)乘法的影响,因为方向向量无法平移。相反,点和向量都受其余仿射变换的影响。平移矩阵的逆是T(-t) ,即向量t取反.

图 4.1 左边的方形进行了平移变换,平移矩阵为 T(5,2,0),方形向右移动了 5 个单位距离,向上移动了 2 个单位距离。

在这一点上,我们应该提到的是,有时在计算机图形学中看到的另一种有效的符号方案,它使用的矩阵的底标是平移向量。例如DirectX 就是使用这种形式。在该方案中,矩阵的顺序将颠倒,即矩阵应用的顺序将从左至右读取。由于向量是行向量,因此可以将这种表示形式的向量和矩阵称为行优先形式(。在本书中,我们将使用列优先形式。无论使用哪种方式,这纯粹是一种符号上的差异。当矩阵存储在内存中时,十六进制的最后四个值为三个平移值加后跟的一个值。

4.1.2 旋转

旋转变换将一个向量(位置或方向)绕经过原点的给定轴旋转指定的角度。像平移矩阵一样,它是一个刚体变换,换句话说,它保留了变换后的点之间的距离,并保留了惯用性(即从不会使左右两侧互换)。在计算机图形学中,这两种类型的变换对于定位和定向对象显然很有用。方向矩阵是与摄像机视图或对象相关联的旋转矩阵,它定义了其在空间中的方向,即其向上和向前的方向。

在二维中,旋转矩阵很容易得出。假设我们有一个向量V=(Vx,Vy),我们将其参数化V=(Vx,Vy)=
(rcosθ,rsinθ)。如果我们将向量旋转Φ弧度(逆时针),则将得到 U=(r cos(θ +Φ ),r sin(θ +Φ ))。这可以重写为


在这里我们使用角度和关系来展开cos(θ +Φ ) 和 sin(θ +Φ )。在三维中,常用的旋转矩阵是Rx(Φ ),Ry(Φ ),Rz(Φ ),,它们分别绕x,y 和 z 轴旋转实体 Φ ,弧度。它们由公式 4.5 – 4.7 给出:
![https://img-blog.csdnimg.cn/679f047eaa504bf58e112e892016103b.png)]](https://img-blog.csdnimg.cn/679f047eaa504bf58e112e892016103b.png)
如果从 4 × 4 矩阵中删除最底行和最右列,则将获得 3 × 3 矩阵。对于每个绕任意轴旋转Φ 弧度的 3 × 3 矩阵R,它的迹(trace,矩阵中对角元素的总和)与轴无关,是恒定的,计算公式为 [997]:

tr(R)=1=2cosΦ

旋转矩阵的效果可以在图 4.4 中看到。使旋转矩阵Ri(Φ ) 起作用的原因是,它绕着轴 i旋转了 Φ 弧度,它让所有的点绕i轴旋转了。注意, 也将用于表示围绕任何轴的旋转矩阵。上面给出的轴旋转矩阵可以在一系列的三个变换中使用,以执行任意轴旋转。该过程在 第 4.2.1 节 中讨论。第 4.2.4 节 介绍了直接绕任意轴的旋转。
所有旋转矩阵的行列式都有一个正交的行列式。这对于任意数量的连续变换也成立。还有另一种求逆的方法:
Ri(Φ )的逆矩阵=Ri(-Φ ),即绕同一轴沿相反方向旋转。

4.1.3 缩放

缩放矩阵 S(s)=(Sx,Sy.Sz),分别沿 x,y 和 z 方向按 Sx,Sy.Sz的缩放因子去缩放实体。这意味着可以使用缩放矩阵来放大或缩小对象。Si越大,则按比例缩放的实体在该方向上越大。将s的任何分量设置为 1 自然可以避免在该方向上缩放比例发生变化。公式 4.10 展示了 S(s)
在这里插入图片描述
图4.4 说明了缩放矩阵的作用。如果 Sx=Sy=Sz,则缩放操作称为统一操作,否则称为非统一操作。有时,使用等向性和非等向性缩放来代替统一和非统一性。倒数是
S(x)的负一次方=S(1/Sx,1/Sy.1/Sz)

使用齐次坐标,创建统一缩放矩阵的另一种有效方法是通过操作位置(3,3)处的矩阵元素,即右下角的元素。该值会影响齐次坐标的w分量,因此会缩放矩阵变换后的点(而非方向向量)的每个坐标。例如,要均匀地缩放 5 倍,可以将缩放矩阵中(0,0),(1、1)和(2,2)的元素设置为 5,或将(3, 3)可以设置为 1/5。执行此操作的两个不同矩阵如下所示:
在这里插入图片描述
与使用S进行均匀缩放相反,必须始终在使用 S’ 之后进行齐次化。这可能是低效的,因为它涉及齐次化过程中的除法。如果右下角的元素(位置(3,3))为1,则不需要除法。当然,如果系统总是在不检测是否为 1 的情况下进行除法,则不会产生任何额外消耗。

S的一个或三个分量上的负值给出一种反射矩阵,也称为镜像矩阵。如果只有两个比例因子为 -1,那么我们将旋转 π 弧度。应当注意的是,与反射矩阵连接的旋转矩阵也是反射矩阵。因此,以下是反射矩阵:
在这里插入图片描述
当检测到反射矩阵时,通常需要进行特殊处理。例如,当顶点由反射矩阵变换时,其三角形的顶点具有逆时针顺序的三角形将获得顺时针顺序。此顺序更改可能导致不正确的照明和背面剔。要检测给定的矩阵是否以某种方式反射,请计算矩阵左上 3×3 个元素的行列式。如果该值为负,则矩阵是反射的。例如,公式4.12 中矩阵的行列式为 0*0-(-1)(-1)=-1。

4.1.4 剪切
另一类变换是剪切矩阵。这些矩阵可以,例如,用于扭曲游戏中整个场景,以产生迷幻效果或扭曲模型的外观。有六个基本剪切矩阵,它们分别表示为Hxy(S) ,Hxz(S) ,Hyx(S) ,Hyz(S) ,Hzx(S),Hzy(S) 和 。第一个下标用于表示剪切矩阵正在更改哪个坐标,而第二个下标表示进行剪切的坐标。剪切矩阵 Hxz(S)的示例如 公式4.15 所示。注意,下标可用于在下面的矩阵中找到参数 s的位置; (其数字索引为0)标识第零行,而 (其数字索引为 2 )标识第二列,因此 位于此处:

在这里插入图片描述
在这里插入图片描述
图4.3 用Hxz(s) 剪切单位平方的效果。y值和z值都不受转换的影响,而x值是旧x值和s乘以z值的总和,导致平方倾斜。这种变换是保留区域的,这可以通过虚线区域相同来看出。

将此矩阵与点P(Px,Py,Pz) 相乘的结果是一个点(Px+Pz,Py,Pz)T: 。以图形方式显示,如图4.3所示。 Hij(s)的倒数(相对于第 j个坐标剪切第 i个坐标,其中 )是通过在相反方向上剪切产生的,即Hij的负一次方=Hij(-s)。

你还可以使用略有不同的剪切矩阵:

然而,在此,两个下标都用于表示这些坐标将被第三坐标剪切。这两种不同类型的描述之间的联系是 ,其中 用作第三坐标的索引。该使用什么矩阵取决于个人偏好。最后,应该注意的是,由于任何剪切矩阵的行列式 ,这是一个保留体积的变换,如图 4.3 所示。
在这里插入图片描述

4.1.5 连续变换

由于矩阵上乘法运算的不可交换性,因此矩阵出现的顺序很重要。因此,变换的连续变换被认为是顺序相关的。

作为顺序依赖的示例,请考虑两个矩阵SR。S(2,0.5,1) 将 x 分量缩放为两倍,将y分量缩放为 0.5。Rz(π /6) 绕 z 轴逆时针旋转 π/6 弧度(在右手坐标系中从本书的页面向外指向)。这些矩阵可以用两种方法进行混合,其结果是完全不同的。这两种情况如图 4.4 所示。

在这里插入图片描述
图4.4 这说明了矩阵相乘时的顺序依赖性。在第一行图片中,应用旋转矩阵Rz(π /6) ,然后缩放 S(2,0.5,1)。这样,合成后的矩阵为S(2,0.5,1)Rz(π /6) 。在第二行图片中,以相反的顺序应用矩阵,从而得出Rz(π /6)S(2,0.5,1)。结果明显不同。对于任意矩阵 MN,通常认为 MN 不等于 NM。

将一系列矩阵的连接转换为单个矩阵的明显原因是为了提高效率。例如,假设你的游戏场景具有数百万个顶点,并且场景中的所有对象都必须缩放,旋转并最终平移。现在,不是将所有顶点与这三个矩阵中的每一个相乘,而是将这三个矩阵连接到一个矩阵中。然后将此单个矩阵应用于顶点。该复合矩阵为C=TRS(transfer roration scale)[这里为从右到左,为缩放-旋转-平移] 。注意这里的顺序。比例矩阵 S 应该首先应用于顶点,因此在合成中显示在右侧。该排序意味着TRSP,其中 P 是要变换的点。顺便说一句, 是场景图系统常用的顺序。

4.1.6 刚体变换

当一个人抓住一个坚固的物体时,例如从桌子上用笔将其移动到另一个位置,也许移动到衬衫的口袋里,只有物体的方向和位置会发生变化,而物体的形状通常不会受到影响。这种仅由平移和旋转的串联组成的变换称为刚体变换。它具有保留长度,角度和惯用性的特性。

可以将任何刚体矩阵 X 表示为平移矩阵T(t)和旋转矩阵R的串联。因此,X在公式 4.17 中具有矩阵的外观:
在这里插入图片描述
X的倒数计算为 X-1=-{T(t)R}-1=R-1T(t)-1 =RTT(-t)因此,为了计算逆,对R的左上3×3矩阵进行转置,并且 T的平移值改变符号。将这两个新矩阵以相反的顺序相乘以获得逆。计算X的逆的另一种方法是考虑 R(使R出现为3×3矩阵)和 X 的符号如下(符号在第 6 页的公式 1.2 中描述):

在这里插入图片描述
其中,r,0表示旋转矩阵的第一列(即逗号表示从 0 到 2 的任何值,而第二个下标为 0),而 r0T是列矩阵的第一行。请注意,0 是填充有零的 3×1 列向量。一些计算得出公式 4.19 中所示表达式的反函数:
在这里插入图片描述

4.1.7 法线变换

单个矩阵可用于一致地变换点,线,三角形和其他几何形状。矩阵还可以沿这些线或在三角形的曲面上变换切向量。但是,矩阵不能始终用于变换一个重要的几何特性,即表面法线(和顶点照明法线)。图 4.6 显示了如果使用相同的矩阵会发生什么。
在这里插入图片描述
图 4.6。左侧是原始几何图形,三角形以及从侧面显示的法线。中间的插图显示了如果模型沿 x 轴缩放 0.5,法线使用相同的矩阵会发生什么。右图显示了法线的正确变换。

假设Model space中的某条切线向量是T,法线向量是N。

那么由他们是垂直的可得到:TTN=0 【我的理解:点乘为0 ,表示夹角为90度】

假设他们变换到Eye space中后分别是T’和N’。那么他们应该仍然是相互垂直的:T’TN’=0 【我的理解:点乘为0 ,表示夹角为90度】

假设切线向量和法线的变换矩阵为M、G。则有:(MT)T(GN)=0 【我的理解:乘上各自的变换】

进一步推出:TTMTGN=0 【我的理解: (MT)T = TTMT

由于TTN=0,因此我们猜想MTG=0.因此:
G=(M-1)T 【我的理解:( MT)-1 等于 (M-1)T 下面有推导】

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

即使只计算一个完整的 4×4 矩阵的伴随,也可能代价很昂贵,并且通常没有必要。由于法线是向量,因此平移不会对其产生影响。此外,大多数模型变换都是仿射的。它们不会更改传入的齐次坐标的 w 分量,也就是说,它们不会执行投影。在这些情况下,正常变换所需的仅是计算左上 3×3 分量的伴随矩阵。

通常甚至不需要这种伴随计算。假设我们知道变换矩阵完全由平移,旋转和统一缩放操作(无拉伸或压扁)的串联组成。可知平移不影响法线。统一的缩放因子仅改变法线的长度。剩下的就是一系列旋转,因此总是产生某种形式的最终的旋转值,仅此而已。逆的转置可用于变换法线。旋转矩阵是通过其转置矩阵为逆来定义的。代替以获得法线变换,两个转置(或两个逆)给出原始旋转矩阵。综上所述,原始变换本身也可以在这些情况下直接用于变换法线。

最后,并不总是需要完全重新归一化生成的法线。如果仅平移和旋转连接在一起,则法线在通过矩阵进行变换时不会更改长度,因此不需要重新归一化。如果还连接了统一的缩放比例,则总缩放比例因子(如果已知或已提取,请参见第 4.2.3 节)可用于直接归一化所生成的法线。举个例子,如果我们知道应用了一系列缩放,使对象变大了 5.2 倍,则通过将此矩阵直接变换的法线除以 5.2 就会对其进行重新归一化。另外,为了创建一个产生归一化结果的法线变换矩阵,原始矩阵左上角的 3×3 可以除以该比例因子。

请注意,在变换之后,表面法线是从三角形得出的系统中,法线变换不是问题(例如,使用三角形边的叉积)。另外,切向量在本质上与法线不同,并且总是直接由原始矩阵变换而成。

4.1.8 逆的计算

在许多情况下都需要逆。例如在坐标系之间来回切换时, 根据有关变换的可用信息,我们可以使用以下三种方法之一来计算矩阵的逆:

1、如果矩阵是单个变换或具有给定参数的简单变换序列,则该矩阵可以通过“反转参数”和矩阵顺序轻松地计算。举个例子,如果 M=T(t)R(Φ),则M-1=R(-Φ) T(-t)[译者提示,括号求逆,则展开需要改变顺序,然后分别求逆]。这很简单,并且保留了变换的准确性,这在渲染巨大世界时很重要[1381]。

2 如果已知矩阵是正交的,则 M-1=MT ,即转置为逆。旋转的任何序列都是旋转,因此是正交的。

3 如果没有任何已知条件,则可以使用伴随方法,克莱姆法则,LU分解(LU decomposition)或高斯消除法来计算逆。通常最好使用克莱姆法则和伴随方法,因为它们的分支操作较少; 在现代体系结构上最好避免使用“if”测试。请参阅第 4.1.7 节,了解如何使用伴随来反转变换法线。

优化时也可以考虑逆计算的目的。例如,如果将逆函数用于向量变换,则通常只需要对矩阵左上角的 3×3 部分进行反转(请参见上一节)。

4.2 特殊矩阵变换与运算

在本节中,将介绍和推导一些对实时图形来说必不可少的几种矩阵变换和运算。首先,我们介绍欧拉变换及其参数提取,欧拉变换是描述方向的一种直观的方法。然后,我们会谈到从单个矩阵中提取出一组基本变换。最终,推导出一种绕任意轴旋转实体的方法。

4.2.1 欧拉变换

这种变换是构造矩阵以将自己(即相机)或任何其他实体定向到某个方向的一种直观方法。它的名字来自伟大的瑞士数学家莱昂哈德·欧拉(Leonhard Euler,1707–1783年)。

首先,必须建立某种默认的视图方向。如图 4.7 所示,它通常沿负 z 轴放置,head 沿 y 轴放置。欧拉变换是三个矩阵的乘积,即图中所示的旋转。更正式地说,表示为E的变换由公式 4.21 给出:
在这里插入图片描述
矩阵的顺序可以以 24 种不同的方式选择 [1636];这可以通过选择矩阵的顺序来实现。我们介绍这个是因为它是常用的。由于 E是旋转的串联,因此它也显然是正交的。因此,它的逆可以表示为
E-1=ET=(Rz,Rx,Ry)T=RyTRxTRzT,当然,直接使用E的转置会更容易。

欧拉角h,p,r 分别表示 head,pitch和 roll 应按其顺序旋转以及绕其各自的轴旋转多少。有时,所有角度都称为“rolls”,例如,我们的“head”为“ y-roll”,而我们的“pitch”为“ x-roll”。另外,“head”有时也称为“yaw”,例如在飞行模拟中。

在这里插入图片描述
图4.7。欧拉变换及其与更改 head,pitch 和 roll 的方式之间的关系。显示默认视图方向,沿负z轴看,向上方向沿y轴看。

这种变换很直观,因此很容易用外行的语言进行讨论。例如,改变 head 角度会使观看者摇头“no”,改变 pitch 会使他们点头,而 rolling 会使他们的 head 向侧面倾斜。我们不是在谈论围绕 x , y 和 z 轴 的旋转,而是谈论改变 head,pitch 和 roll。请注意,此变换不仅可以定向相机,还可以定向任何对象或实体。可以使用世界空间的全局轴(the global axes of the world space)或相对于局部参照系执行这些变换。

重要的是要注意,一些欧拉角的表示将 z 轴作为初始向上方向。这种差异纯粹是一种符号上的变化,尽管可能会造成混淆。在计算机图形学中,如何看待世界以及如何形成内容存在分歧:y 向上 或 z 向上。大多数制造工艺(包括3D打印)都认为 z 方向在世界空间中向上。航空和海上交通工具认为 -z 为向上。建筑和 GIS(地理信息系统,Geographic Information System 或 Geo-Information system,缩写为 GIS) 通常使用 z-up,因为建筑平面图或地图是二维的 x 和 y 。与媒体相关的建模系统通常将 y 方向视为世界坐标上的向上方向,以匹配我们始终在计算机图形学中描述相机的屏幕向上方向的方式。这两个世界向量选择之间的差异仅相差 90° 旋转(并且可能是反射),但不知道假定哪个会导致问题。在本卷中,除非另有说明,否则我们使用 y 向上的世界方向。

我们还想指出,相机在其视野中的向上方向与世界的向上方向没有特别关系。转动 head,视野就会倾斜,其世界空间向上方向与世界方向不同。再举一个例子,假设世界使用 y-up,而我们的相机则直视下方的地形,鸟瞰。此方向表示相机已向前倾斜 90°,因此其在世界空间中的向上方向为 。在这种方向上,相机没有 y 分量,而是认为 -z 在世界空间中向上,但根据定义,“ y在上方”在视图空间(view space)中仍然适用。

欧拉角虽然适用于较小的角度变化或观看者方向,但还有其他一些严重的限制——很难将两组欧拉角组合使用。例如,在一组和另一组之间进行插值并不是对每个角度进行插值的简单问题。实际上,两组不同的欧拉角可以给出相同的方向,因此任何插值都不应旋转对象。这些是使用本章稍后讨论的替代方向表示形式(例如四元数)值得追求的一些原因。使用欧拉角,你还会遇到被称为万向节锁定的问题,这将在第 4.2.2 节中介绍。

4.2.2 从欧拉变换中提取参数

在某些情况下,使用从正交矩阵中提取欧拉参数 h,p 和 r 的过程很有用。此过程如公式 4.22 所示:
在这里插入图片描述
(z,x,y)

在这里,我们放弃了 4×4 矩阵而使用3×3 矩阵,因为后者提供了旋转矩阵的所有必要信息。也就是说,等效的 4×4 矩阵的其余部分始终在右下位置包含 0 和一个 1。

将公式 4.22 中的三个旋转矩阵串联起来:

在这里插入图片描述
由此可见,pitch 参数由sinp=e21 给出。同样,将 e01除以 e11,并类似地将e20 除以e22 ,会产生以下用于 head 和 roll 参数的提取公式:
在这里插入图片描述
因此,如公式 4.25 所示,使用函数 atan2(y,x)(请参阅第1章第8页)从矩阵E提取欧拉参数h(head),p(pitch)和r(roll):
在这里插入图片描述
但是,有一种特殊情况需要处理。如果 cosp,则具有万向节锁定(第 4.2.2 节),旋转角度r和h将绕同一轴旋转(尽管可能沿不同的方向旋转,具体取决于p 旋转角度是 -π/2 还是π/2 ),因此只需导出一个角度。如果我们任意设置 h=0 [1769],我们得到
在这里插入图片描述
由于 P 不影响第一列中的值,因此当 cosp=0 时,我们可以使用sinr/cosr=tanr=e10/e00 ,得出
r=atan2(e10,e00) 。

请注意,根据反正弦的定义-π/2<=p<=π/2,,这意味着如果使用该间隔之外的P值创建 E,则无法提取原始参数。h,p 和 r不是唯一的,意味着可以使用一组以上的欧拉参数来产生相同的变换。有关欧拉角转换的更多信息,请参见 Shoemake 的 1994 年文章 [1636]。上面概述的简单方法可能会导致数值不稳定的问题,这在速度方面会付出一定的代价来避免 [1362]。

当您使用欧拉变换时,可能会发生万向节锁定[499,1633]。这发生在旋转时,会因此失去一个自由度。举个例子,变换的顺序是 x/y/z。假设第二次旋转我们绕 y 轴旋转π/2 。这样做会旋转局部 z 轴以使其与原始 x 轴对齐,因此围绕 z 的最终旋转是不正确的。

在数学上,我们已经在公式 4.26 中看到了万向节锁定,其中假设 cosp=0,即2kπ+(-)π/2 ,其中 k 是整数。有了这样的 p值,我们失去了一个自由度,因为矩阵仅取决于一个角度r+h 或 r-h(但不是同时取决于两个角度)。

尽管在模型系统中通常以x/y/z 顺序表示欧拉角,但绕每个局部轴旋转时,其他顺序也是可行的。例如,z/x/y动画中使用 ,动画和物理学中都使用z/x/z 。所有都是指定三个单独旋转的有效方法。最后的z/x/z 顺序在某些应用中可能会更好,因为只有当绕 x 旋转 π弧度(半旋转)时,才会发生万向节锁定。没有完美的序列可以避免万向节锁定。尽管如此,欧拉角还是很常用的,因为动画师更喜欢曲线编辑器来指定角度如何随时间变化 [499]。

示例:约束变换

想象您拿着一把(虚拟的)扳手紧紧地抓住螺栓。为了将螺栓固定到位,您必须围绕 x 轴旋转扳手。现在假设您的输入设备(鼠标,VR手套,太空球等)为扳手的运动提供了一个旋转矩阵,即一个旋转矩阵P。问题在于,将这种变换应用于扳手,扳手应该只绕x轴旋转,这可能是错误的。要将输入变换(称为 p)限制为绕 x 轴旋转,只需使用本节中介绍的方法提取欧拉角 h, p和 r,然后创建一个新矩阵Rx§ 。然后,这是一种受欢迎的变换,它将使扳手绕 x 轴旋转(如果 P 现在包含这样的运动)。

4.2.3 矩阵分解

到目前为止,我们一直在假设我们知道所使用的变换矩阵的初始状态和历史记录的情况下进行工作。通常情况下并非如此。例如,仅连接的矩阵可以与某个变换后的对象相关联。从连续矩阵中提取各种变换的任务称为矩阵分解。

提取变换的原因有很多。用途包括:

为对象提取比例因子。
查找特定系统所需的变换。(例如,某些系统可能不允许使用任意 4×4 矩阵。)
确定模型是否仅经历了刚体变换。
在动画中的关键帧之间进行插值,其中仅对象的矩阵可用。
从旋转矩阵中删除剪切。
我们已经提出了两种分解方法,分别是为刚体变换导出平移和旋转矩阵(第4.1.6节)以及从正交矩阵导出欧拉角(第4.2.2节)。

正如我们所看到的,提取变换矩阵很简单,因为我们只需要 4×4 矩阵的最后一列中的元素。我们还可以通过检查矩阵的行列式是否为负来确定是否发生了反射。要分离出旋转,缩放和剪切,需要花费更多的精力。

4.2.4 绕任意轴旋转

有时使用使实体绕任意轴旋转某个角度的过程会很方便。假设旋转轴 r已归一化,并且应该创建一个围绕 旋转 α弧度的变换。

为此,我们首先变换到一个空间,这个空间里我们要围绕其旋转的轴是 x 轴。这是通过一个称为 M的旋转矩阵完成的。然后执行实际的旋转,之后使用 M-1进行变换 [314]。此过程如图 4.8 所示。

在这里插入图片描述
图4.8 围绕任意轴r的旋转是通过寻找由r、s和t构成的正交基来实现的。然后,我们将这个基础与标准基础对齐,使r与x轴对齐,围绕x轴旋转,最后我们再转换回来。

为了计算 M,我们需要找到两个对 r 来说正交的轴。我们专注于找到第二根轴s,知道第三根轴t将是第一根轴和第二根轴的叉积,t=r x s 。一种数字稳定的方法是找到 r 的最小成分(绝对值),并将其设置为 0。交换剩余的两个成分,然后对它们中的第一个取反(实际上,可以否定非零分量中的任何一个)。在数学上,这表示为 [784]:
在这里插入图片描述
这保证了 s 与 r 正交(垂直),并且(t,s,t) 是正交的基础。Frisvad [496] 提出了一种在代码中没有任何分支的方法,该方法速度更快,但准确性较低。Max [1147] 和 Duff 等。[388] 提高了 Frisvad 方法的准确性。无论采用哪种技术,都会使用这三个向量来创建旋转矩阵:
在这里插入图片描述
该矩阵将向量 r 变换为 x 轴,将 s 变换为 y 轴,将 t变换为 z 轴。因此,然后使围绕标准化向量 r 旋转 弧度α的最终变换为:
X=MTRx(α)M

换句话说,这意味着首先我们进行变换,使 r 为 x 轴(使用 M ),然后围绕该 x 轴旋转 α 弧度(使用 Rx(α)),然后使用 M 的逆函数进行变换 ,在这种情况下为 Mt ,因为 M 是正交的。

Goldman [550]提出了另一种通过 弧度绕任意归一化轴 旋转的方法。在这里,我们只介绍他的变换:

在这里插入图片描述
在第 4.3.2 节中,我们提出了解决此问题的另一种方法,使用四元数(Quaternions)。在那个部分中,还有针对相关问题(例如从一个向量到另一个向量的旋转)的更高效的算法。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值