计算机图形学中的应用非常广泛的变换是一种称为仿射变换的特殊变换,在仿射变换中的基本变换包括平移、旋转、缩放、剪切这几种。本文以及接下来的几篇文章重点介绍一下关于旋转的变换,包括二维旋转变换、三维旋转变换以及它的一些表达方式(旋转矩阵、四元数、欧拉角等)。
首先要明确旋转在二维中是绕着某一个点进行旋转,三维中是绕着某一个轴进行旋转。二维旋转中最简单的场景是绕着坐标原点进行的旋转,如下图所示:
如图所示点v 绕 原点旋转 θ 角,得到点v’,假设 v点的坐标是(x, y) ,那么可以推导得到 v’点的坐标(x’, y’)(设原点到v的距离是r,原点到v点的向量与x轴的夹角是 ϕ )
x=rcosϕy=rsinϕ
x′=rcos(θ+ϕ)y′=rsin(θ+ϕ)
通过三角函数展开得到
x′=rcosθcosϕ−rsinθsinϕ
y′=rsinθcosϕ+rcosθsinϕ
带入x和y表达式得到
x′=xcosθ−ysinθ
y′=xsinθ+ycosθ
写成矩阵的形式是:
绕原点的旋转是二维旋转最基本的情况,当我们需要进行绕任意点旋转时,我们可以把这种情况转换到绕原点的旋转,思路如下:
1. 首先将旋转点移动到原点处
2. 执行如2所描述的绕原点的旋转
3. 再将旋转点移回到原来的位置
也就是说在处理绕任意点旋转的情况下需要执行两次平移的操作。假设平移的矩阵是T(x,y),也就是说我们需要得到的坐标 v’=T(x,y)*R*T(-x,-y)(我们使用的是列坐标描述点的坐标,因此是左乘,首先执行T(-x,-y))
在计算机图形学中,为了统一将平移、旋转、缩放等用矩阵表示,需要引入齐次坐标。(假设使用2x2的矩阵,是没有办法描述平移操作的,只有引入3x3矩阵形式,才能统一描述二维中的平移、旋转、缩放操作。同理必须使用4x4的矩阵才能统一描述三维的变换)。
对于二维平移,如下图所示,P点经过x和y方向的平移到P’点,可以得到:
x′=x+txy′=y+ty
由于引入了齐次坐标,在描述二维坐标的时候,使用(x,y,w)的方式(一般w=1),于是可以写成下面矩阵的形式
我们可以把一个旋转转换为绕基本坐标轴的旋转,因此有必要讨论一下绕三个坐标值x、y、z的旋转。
本文在讨论过程中使用的是类似于OpenGL中定义的右手坐标系,同时旋转角度的正负也遵循右手坐标系的约定。如下图所示
在三维场景中,当一个点P(x,y,z)绕x轴旋转 θ 角得到点P’(x’,y’,z’)。由于是绕x轴进行的旋转,因此x坐标保持不变,y和z组成的yoz(o是坐标原点)平面上进行的是一个二维的旋转,可以参考上图(y轴类似于二维旋转中的x轴,z轴类似于二维旋转中的y轴),于是有:
x′=x
y′=ycosθ−zsinθ
z′=ysinθ+zcosθ
写成(4x4)矩阵的形式
绕Y轴的旋转和绕X轴的旋转类似,Y坐标保持不变,除Y轴之外,ZOX组成的平面进行一次二维的旋转(Z轴类似于二维旋转的X轴,X轴类似于二维旋转中的Y轴,注意这里是ZOX,而不是XOZ,观察上图中右手系的图片可以很容易了解到这一点),同样有:
x′=zsinθ+xcosθ
y′=y
z′=zcosθ−xsinθ
写成(4x4)矩阵的形式
与上面类似,绕Z轴旋转,Z坐标保持不变,xoy组成的平面内正好进行一次二维旋转(和上面讨论二维旋转的情况完全一样)
上面描述了三维变换中绕单一轴旋转的矩阵表达形式,绕三个轴旋转的矩阵很类似,其中绕y轴旋转的矩阵与绕x和z轴旋转的矩阵略有点不同(主要是三个轴向顺序和书写矩阵的方式不一致导致的,绕三个不同坐标旋转轴以及其他二个坐标轴组成平面的顺序是: XYZ(绕x轴) YZX(绕y轴) ZXY(绕z轴),其中绕y轴旋转,其他两个轴是ZX,这和我们书写矩阵按
绕任意轴的三维旋转可以使用类似于绕任意点的二维旋转一样,将旋转分解为一些列基本的旋转。绕任意轴旋转如下图所示:
P点绕向量u旋转 θ 角,得到点Q,已知P点的坐标和向量u,如何求Q点的坐标。
我们可以把向量u进行一些旋转,让它与z轴重合,之后旋转P到Q就作了一次绕Z轴的三维基本旋转,之后我们再执行反向的旋转,将向量u变回到它原来的方向,也就是说需要进行的操作如下:
1. 将旋转轴u绕x轴旋转至xoz平面
2. 将旋转轴u绕y轴旋转至于z轴重合
3. 绕z轴旋转 θ 角
4. 执行步骤2的逆过程
5. 执行步骤1的逆过程
原始的旋转轴u如下图所示:
第1、2、3步骤如下图所示:
步骤1将向量u旋转至xoz平面的操作是一个绕x轴的旋转操作,步骤2将向量u旋转到与z轴重合,第1、2步骤的示意图如下:
作点P在yoz平面的投影点q,q的坐标是(0, b, c),原点o与q点的连线oq和z轴的夹角就是u绕x轴旋转的角度。通过这次旋转使得u向量旋转到xoz平面(图中的or向量)【步骤1】
过r点作z轴的垂线,or与z轴的夹角为 β , 这个角度就是绕Y轴旋转的角度,通过这次旋转使得u向量旋转到与z轴重合【步骤2】
步骤1中绕x轴旋转的是一次基本的绕x轴的三维旋转,按照之前的讨论,旋转矩阵是:
在完成前面两个步骤之后,u方向和z轴完全重合,因此执行旋转 θ 角,执行的是一次绕z轴的基本三维旋转(记作 R(θ) ,根据之前的讨论,我们可以得到: