三维变换
与上一篇文章中的二维变换类似,我们可以使用一个 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轴旋转度,对应矩阵