本文首先讲解欧拉变换(Euler transform)以及它的参数提取(extraction of parameters)。欧拉变换是描述朝向(orientation)的一个直观的方法。然后,会讲到如何从单个矩阵中提取出一系列变换。最后,讲述一个绕任意轴旋转实体(entity,即点、线、面或者物体)的方法。
如果不熟悉旋转变换,建议先看这篇文章:图形学中的基本变换(Basic Transforms)
1 欧拉变换(The Euler Transform)
欧拉变换是一个直观的方法,用于构造一个矩阵设置你自己(即照相机camera)或者任何别的实体朝向某个方向。其名字来源于伟大的瑞士数学家莱昂哈德·欧拉(Leonhard Euler,1707–1783).
首先,某个默认的观察方向(或者视线方向view direction)需要被确立。它经常是沿着-z轴,使头部朝向正y轴,如图4.7所示。这里可以想像一下右手坐标系,正y轴朝向电脑屏幕正上方,正z轴,从垂直电脑屏幕指向屏幕外,而负z轴指向屏幕里。也就是默认观察方向指向屏幕里。
![3be39fdd5541840da997c535b4893fd1.png](https://i-blog.csdnimg.cn/blog_migrate/2fe50d43e5595babc6cf4f127e3b2a29.png)
欧拉变换涉及到三个角度,即欧拉角(Euler angles): head, pitch, roll,如图4.7所示。它们分别简称为,分别表示应该绕对应的轴旋转的角度。有时它们也会被称为"rolls",例如,"head"对应"y-roll","pitch"对应"x-roll"。"head"有时也没称为"yaw",表示偏航角。
怎么记住三个欧拉角各自的作用(对应的轴)?
答案: 想像一下,静止状态时一个观察者站立,双臂向两边平伸展开,目视前方,其视线方向为负z轴(roll),头顶方向为正y轴(head),右臂所指的方向为正x轴(pitch)。改变head会使观察者做出摇头的动作(即绕y轴旋转head弧度),改变pitch为使观察者做出点头的动作(即绕x轴旋转pitch弧度),改变roll会使观察者的头部倾斜(即绕z轴旋转roll弧度)。
欧拉变换是三个旋转矩阵的乘积。用
矩阵的顺序多达24种。这里我们仅展示方程4.21里的这种,因为它是常为常用。因为
注意欧拉变换不仅可以用于设置照相机的朝向,也可以设置任何物体或实体的朝向。这些变换可以在全局的世界坐标系下完成,也可以在相对于某个物体的局部坐标系完成。
需要注意的是,欧拉角的某些情形下,把z轴作为初始的up direction(即上方向,而我们这里使用y轴作为up direction)。这种差异仅仅是一个符号改变,但可能会令人困惑。在计算机图形学中,如何看待世界(the world)和如何排列内容,有一个区分(a division)或者说有两种方式: y-up或者z-up。大多数生产过程(Most manufacturing processes),包括3D打印,把z-direction作为世界空间(world space)的up方向。航空和海上运输工具认为−z是up方向。而媒体相关的建模系经常认为y-direction为世界坐系下的up方向,这和图形学中描述照相机屏幕上方向(a camera's screen up direction)的方式一致。在本文中,我们使用y-up。
这里需要指出观察空间(view space)内的照相机的上方向(camera's up direction)和世界空间的上方向(world's up direction)没有什么特别的关系。毕竟处于两个坐标系中。
尽管对于小的角度或者观察者朝向改变,欧拉角很有用,但它也有一些严重的限制。同时结合使用两个欧拉角集合(tow sets of Euler angles)是困难的。例如,在两个欧拉角集合间进行插值不是简单地对两组集合的三个角度分别进行插值。因为两个不同的欧拉角集合可能给出相同的朝向,此时任何插值都不会旋转物体。这些是考虑用四元数(Quaternion)等来代替欧拉角的原因。
2 从欧拉变换中提取参数(Extracting Parameters from the Euler Transform)
有时从一个正交矩阵,即欧拉变换矩阵,提交出欧拉角
这里我们放弃了
连接方程4.22中的三个旋转矩阵,可以得到:
显然,
因此可解出三个欧拉角分别为:
有一个特殊的情形需要处理。如果
因为
注意arcsin的定义域为
不同的组合可能产生相同的欧拉变换。
当使用欧拉变换时,万向节锁(gimbal lock)可能会出现。当某个旋转使得三个自由度(对应r, p, h或者说对应x, y, z轴)中的一个消失时,万向节锁会出现。例如,变换顺序为
使用案例: 限制一个变换(Constraining a Transform)
设想你正拿着一个虚拟的扳手,正在拧紧一个螺栓。为了使螺栓拧紧,你必须使扳手绕x轴旋转。现在假设你的输入设备(鼠标、VR手套、空间球等)给你一个旋转矩阵,即,一个关于扳手运动的旋转。问题是对扳手施加这个transform很可能是错误的,因为应该只绕x轴旋转。为了限制输入变换(the input transform)仅绕x轴旋转,只需要用上面的方法提取(extract)出欧拉角
3 矩阵分解(Matrix Decomposition)
到目前为止,我们总是假设我们知道当前使用的变换矩阵的原始形态及变化历史(the origin and history of the transformation matrix)。但通常的情形并不是这样的。例如,有时我只有一个由多个变换矩阵相乘得到的最终的矩阵(concatenated matrix),而不知道别的任何信息。从一个concatenated matrix中提取出各种变换的任务被称为矩阵分解(matrix decomposition)。
有许多原因需要从concatenated matrix中提取各种变换。包括:
- 提取出一个物体的缩放因子
- 找到一个特殊系统需要的变换。(例如,有些系统可能不允许使用任意
矩阵)
- 检测一个模型是否只经历了刚体变换(only rigid-body transforms)
- 在一个动画的关键帧之间插值只对该物体可用的矩阵
- 从一个旋转矩阵中移除错切变换
提取平移矩阵也是简单直观的,只需要原始
目前网上已有相关的文章和代码:
- Thomas, Spencer W., “Decomposing a Matrix into Simple Transformations,” in James Arvo, ed., Graphics Gems II, Academic Press, pp. 320–323, 1991. Cited on p. 72, 74
- Goldman, Ronald, “Recovering the Data from the Transformation Matrix,” in James Arvo, ed., Graphics Gems II, Academic Press, pp. 324–331, 1991. Cited on p. 74
- Goldman, Ronald, “Decomposing Linear and Affine Transformations,” in David Kirk, ed., Graphics Gems III, Academic Press, pp. 108–116, 1992. Cited on p. 74
- Sloan, Peter-Pike, Ben Luna, and John Snyder, “Local, Deformable Precomputed Radiance Transfer,” ACM Transactions on Graphics (SIGGRAPH 2005), vol. 24, no. 3, pp. 1216–1224, Aug. 2005. Cited on p. 431, 481
4 绕任意轴旋转(Rotation about an Arbitrary Axis)
有时能够使一个实体绕任意旋转轴旋转是很有用的。假设旋转轴
为了达到此目的,我们首先需要变换坐标空间,在新的坐标空间中,
![01e81b83f530bb0aa32c8a29c79105f1.png](https://i-blog.csdnimg.cn/blog_migrate/0679f170970e0375b1f0c29e6685031e.png)
关键的问题是: 怎么计算
为了计算
这能确保
关于为什么长这样,请参看上篇文章中在构造相机变换矩阵时提到的问题:“思考一个问题:为什么方程4.20中的变基矩阵(change of basis)长这样?”
提示:显示可以看到, 即
分别把
变成了x, y, z坐标轴。
因此最终把物体绕归一化的轴
总之,就是先通过坐标空间变换把
另外一篇文章 四元数和旋转(Quaternion & rotation)也介绍过一种方法来计算绕任意轴旋转,它直接给出了一个绕任意轴旋转的矩阵。此处不再单独说明。那篇文章中也说明了用四元数做任意轴旋转会更新加高效、便捷。
Reference:
- Real-Time Rendering 4th 第4.2节
- 四元数和旋转(Quaternion & rotation)