三维变换
与上一篇文章中的二维变换类似,我们可以使用一个 3*3 的矩阵来表示一个三维的线性变换:
并且矩阵 的
,
和
即为
变化后的值,
,
和
即为
变化后的值,
,
和
即为
变化后的值。
仿射变换的公式为:
同样的,我们可以通过引入齐次坐标来表示仿射变换,公式为:
例如缩放s倍的矩阵为:
旋转变换
相比其他变换,旋转变换相对的要复杂一些。首先我们要确定我们的坐标系是左手坐标系还是右手坐标系,这会影响到x,y,z三个轴的相对关系,本文我们使用右手坐标系来进行相关的运算。右手坐标系如下图,右手四指弯曲的方向代表x轴到y轴的方向,大拇指方向代表z轴方向。
我们先来看看在三维空间中绕x,y,z三个轴中的某个轴逆时针旋转 角度的矩阵是如何的
- 绕x轴旋转,则可以看作是在yz平面的二维旋转,x轴的(1,0,0)不变,y轴(0,1,0)变为(0,cos
,sin
),z轴的(0,0,1)变为(0,-sin
,cos
),因此对应的矩阵为:
- 绕y轴旋转,则可以看作是在xz平面的二维旋转,y轴的(0,1,0)不变,x轴(1,0,0)变为(cos
,0,-sin
),z轴的(0,0,1)变为(sin
,0,cos
),因此对应的矩阵为:
- 绕z轴旋转,则可以看作是在xy平面的二维旋转,z轴的(0,0,1)不变,x轴(1,0,0)变为(cos
,sin
,0),y轴的(0,1,0)变为(-sin
,cos
,0),因此对应的矩阵为:
的结合使用
两者结合使用
对于如下表达式我们应该如何理解
通过上一篇提到的复合变换,上面式子表达的应该是先绕x轴旋转,然后再绕y轴旋转。假设原先物体的x轴方向为(1,0,0),y轴方向为(0,1,0),z轴方向为(0,0,1),我们先将其绕x轴逆时针旋转 度,即
操作。此时物体自身的y轴(0,1,0)会跟着x轴的旋转变为(0,cos
,sin
),记作
。那么我们再做
操作时,旋转的y轴是原先的 y=(0,1,0) 还是
=(0,cos
,sin
) ?这是两种完全不一样的情况,如下图
垂直向上较长的那根绿线为 y ,而较短的绿线即为 ,我们来看看绕它们旋转的情况分别是怎样的(左图为绕y旋转,右图为绕
旋转)
答案是:再做 操作时,旋转的y轴就是原先的 y=(0,1,0),即上左图的情况。因为
的旋转矩阵是根据 y=(0,1,0)的情况计算出来了,因此使用该矩阵计算时,无论物体属于一个什么角度,计算出来的结果都是根据 y=(0,1,0)这个轴进行逆时针旋转的结果(注:(0,0,0)为物体的中心点)。
我们可以称x轴方向为(1,0,0),y轴方向为(0,1,0),z轴方向为(0,0,1)的三个轴为世界坐标轴,它们不根据物体的旋转而改变。而会根据物体自身的坐标轴会根据物体的旋转而改变,例如上诉中的,我们可以称之为模型坐标轴。(自己按照unity常用的说法瞎定义了,懂原理就好。)
因此上诉的两个旋转操作都是按照世界坐标轴来进行的,这种我们称之为外旋,表达式 ,我们可以称之为 x-y外旋 操作。那么内旋就是使用模型坐标轴来做旋转操作咯,那么如果我想要实现先绕x轴旋转
度,在绕旋转后的模型坐标轴的y轴(
)旋转
(即 x-y内旋 操作),那么应该怎么计算呢?
首先,第一步是绕x轴旋转,此时物体还没发生旋转,因此模型坐标的x轴等于世界坐标的x轴,因此我们依旧可以使用 矩阵。接着我们要绕
=(0,cos
,sin
) 旋转,这里我们需要将其进行拆解(类似于上一篇中二维空间绕空间中任意一点旋转那样,拆解成先把任意点移到原点,然后旋转,然后再把改点移回去),先把
绕世界坐标的x轴旋转
度,使其与世界坐标的y轴重叠,然后使用
矩阵进行旋转
角度,最后再绕世界坐标的x轴旋转
,是旋转轴
回到(0,cos
,sin
)方向。
因此 x-y内旋操作即为:
- 绕世界坐标x轴旋转
度,对应矩阵
- 绕世界坐标x轴旋转
度,对应矩阵
- 绕世界坐标y轴旋转
度,对应矩阵
- 绕世界坐标x轴旋转
度,对应矩阵
可以发现第一第二步可以抵消,因此x-y内旋操作等价于先绕世界坐标y轴旋转度再绕世界坐标x轴旋转
度,即 x-y内旋 等于 y-x外旋。
上诉过程用矩阵来表达的话,我们知道绕世界坐标x轴旋转度即为绕世界坐标x轴旋转
度的逆变换,因此其矩阵即为
的逆矩阵,为
,因此矩阵如下
x-y内旋 =
=
(因为
等于单位矩阵) = y-z外旋
同理也可得出 x-z内旋等于z-x外旋,z-y内旋等于y-z内旋等等。
三者结合使用
知道上面这些原理后,我们再进一步,来理解下面表达式
同样的,上面式子可以称之为 x-y-z外旋 操作,即先绕世界坐标的x轴旋转度,然后在绕世界坐标的y轴旋转