# 一、旋转,平移,缩放

# 1. 二维旋转

  1. 直角坐标系

​ 如下图,有一个长度为 l, 角度为 θ1 的向量逆时间旋转了 θ 度。设原先向量的横纵坐标为 x1 和 y1,旋转后的横纵左边为 x2 和 y2。

x1=cosθ1l,y1=cosθ1lx_1=cosθ_1l, y_1=cosθ_1l

x2=cos(θ+θ1)l=cosθcosθ1lsinθsinθ1l=cosθx1sinθy1x_2 = cos(θ+θ_1)l = cosθcosθ_1l-sinθsinθ_1l=cosθx_1-sinθy_1

y2=sin(θ+θ1)l=sinθcosθ1l+cosθsinθ1l=sinθx1+cosθy1y_2=sin(θ+θ_1)l = sinθcosθ_1l + cosθsinθ_1l = sinθx_1 + cosθy_1

[cosθsinθsinθcosθ][x1y1]=[x2y2]\left[ \begin{matrix} cosθ & -sinθ \\ sinθ & cosθ \\ \end{matrix} \right] \left[ \begin{matrix} x_1 \\ y_1 \\ \end{matrix} \right] = \left[ \begin{matrix} x_2 \\ y_2 \\ \end{matrix} \right]

​ 由此可以推出在平面的转轴公式。

  1. 复平面

​ 如果有两个模长为 1 的复数角度分别是 θ1 和 θ2,将这两个复数相乘

(cosθ1+sinθ1i)(cosθ2+sinθ2i)=cosθ1cosθ2sinθ1sinθ2+sinθ1cosθ2i+cosθ1sinθ2i(cosθ_1+sinθ_1i)(cosθ_2+sinθ_2i)=cosθ_1cosθ_2-sinθ_1sinθ_2+sinθ_1cosθ_2i+cosθ_1sinθ_2i

=cos(θ1+θ2)+sin(θ1+θ2)i=cos(θ_1+θ_2)+sin(θ_1+θ_2)i

​ 可以看到两个模长为 1 的复数相乘,相当于将两个复数的角度相加,也即角度为 θ1 的角逆时针旋转了 θ2 度,也可以说 θ2 的角逆时针旋转了 θ1 度。

  1. 极坐标

​ 根据欧拉公式,将复数化成极坐标的形式。

cosθ1+sinθ1i=eiθ1cosθ2+sinθ2i=eiθ2cosθ_1+sinθ_1i=e^{iθ_1} cosθ_2+sinθ_2i=e^{iθ_2}

eiθ1eiθ2=ei(θ1+θ2)e^{iθ_1}*e^{iθ_2} = e^{i(θ_1+θ_2)}

# 2. 三维旋转

​ 三维旋转分为,欧拉角,矩阵旋转和四元数。

# 一、欧拉角和矩阵旋转

​ 欧拉证明了,3d 空间的任意旋转均可以通过绕着三个正交轴旋转得到,于是这种绕着三个正交轴旋转得到的旋转被称为欧拉角。

​ 绕 x 轴旋转。设一个向量 v 为 (x1,y1,z1), 绕 x 轴旋转 θ 度。将这个向量 v 分解成平行于 x 轴的向量和垂直于 x 轴的向量。明显在绕着 x 轴旋转时候,平行于 x 轴的向量并没有发生改变,只要求出垂直于 x 轴的向量绕 x 轴旋转 θ 度后的向量再与平行于 x 轴的向量相加即可。

v=v+v=(0,y,z)+(x,0,0)v=v_⊥+v_∥=(0,y,z)+(x,0,0)

v=v+v=v+vv^`=v_⊥^`+v_∥^`=v_⊥^`+v_∥

vy=lcosθ1,vz=lsinθ1,vy=lcos(θ1+θ),vz=lsin(θ1+θv_{⊥y}=lcosθ_1,v_{⊥z}=lsinθ_1,v_{⊥y}^`=lcos(θ_1+θ),v_{⊥z}^`=lsin(θ_1+θ)

[cosθsinθsinθcosθ][vyvz]=[vyvz]\left[ \begin{matrix} cosθ & -sinθ \\ sinθ & cosθ \\ \end{matrix} \right] \left[ \begin{matrix} v_{⊥y} \\ v_{⊥z} \\ \end{matrix} \right] = \left[\begin{matrix} v_{⊥y}^` \\ v_{⊥z}^` \\ \end{matrix} \right]

v=v+v=[0000cosθsinθ0sinθcosθ][0vyvz]+[vx00]=(x,cosθysinθz,sinθy+cosθz)v^`=v_⊥^`+v_∥= \left[ \begin{matrix} 0 & 0 & 0\\ 0 & cosθ & -sinθ \\ 0 & sinθ & cosθ \\ \end{matrix} \right] \left[ \begin{matrix} 0 \\ v_y \\ v_z \\ \end{matrix} \right]+ \left[ \begin{matrix} v_x \\ 0 \\ 0 \\ \end{matrix} \right]= (x,cosθ_y-sinθ_z,sinθy+cosθ_z)

(x,cosθysinθz,sinθy+cosθz)=[100]x+[0cosθsinθ]y+[0sinθcosθ]z=[1000cosθsinθ0sinθcosθ][xyz](x,cosθ_y-sinθ_z,sinθy+cosθ_z)= \left[ \begin{matrix} 1 \\ 0 \\ 0 \\ \end{matrix} \right]x+ \left[ \begin{matrix} 0 \\ cosθ \\ sinθ \\ \end{matrix} \right]y+ \left[ \begin{matrix} 0 \\ -sinθ \\ cosθ \\ \end{matrix} \right]z = \left[ \begin{matrix} 1 & 0 & 0\\ 0 & cosθ & -sinθ \\ 0 & sinθ & cosθ \\ \end{matrix} \right] \left[ \begin{matrix} x \\ y \\ z \\ \end{matrix} \right]

​ 由此推出绕 x 轴旋转的旋转矩阵,此外也可以依次推出绕 y 轴旋转,绕 z 轴旋转的旋转矩阵

  1. 绕 x 轴旋转的旋转矩阵

    \begin{matrix}
    1 & 0 & 0\
    0 & cosθ & -sinθ \
    0 & sinθ & cosθ \
    \end{matrix}
    \right]

[cosθ0sinθ010sinθ0cosθ]\left[ \begin{matrix} cosθ & 0 & sinθ\\ 0 & 1 & 0 \\ -sinθ & 0 & cosθ \\ \end{matrix} \right]

  1. 绕 z 轴旋转的旋转矩阵

[cosθsinθ0sinθcosθ0001]\left[ \begin{matrix} cosθ & -sinθ & 0\\ sinθ & cosθ & 0\\ 0 & 0 & 1\\ \end{matrix} \right]

​ 依次左乘旋转矩阵,比如依次左乘绕 x 轴旋转矩阵,绕 y 轴旋转矩阵,绕 z 轴旋转矩阵,A = ZYX, 这里的矩阵 A 就是一个复合矩阵,因为矩阵乘法有结合律,ZYXv=Av,左乘 A 相当于依次绕 xyz 轴旋转。另外这里的旋转矩阵均是基于初始坐标轴 (或者说世界坐标轴,反正这个坐标轴不会跟着变化) 进行旋转,这就会出现一个问题,如果绕着一个轴旋转 90 度,此时物体的自身的另外两个周会与最开始的两个轴分别重合。比如,绕着 y 轴旋转 90 度,此时物体目前的 x 轴会与初识的 z 轴重合,目前的 z 轴会与 - x 轴重合,这就导致了此时转动 z 轴就不是转动原来的 z 轴而是 x 轴。如果一个物体绕着 x 轴转动,然后再绕着 y 轴转动 90 度,最后再绕着 z 轴转动,会发现此时绕着 z 轴转动相当于之前绕着 x 轴转动,如果想绕着之前的 z 轴转动,得绕着 x 轴转动才行。这就产生一个问题,比如绕着 xyz 轴分别转动,只要中间的轴 y 轴转动达到 90 度,此时绕 z 轴旋转相当于之前绕 y 轴旋转时的绕 x 轴旋转,也即无法正常的绕着 z 轴时表现出绕着 z 轴 (这个是按自身的坐标轴) 的转的情况,或者说此时少了一种转动情况,也即少了一个自由度。这种情况叫做万向死锁。可以用矩阵的方式,探究这个情况。

​ 假设有两种旋转,一种是绕着 x 轴旋转 θ 度然后绕着 y 轴旋转 90 度,一种是绕着 y 轴旋转 90 度,然后绕着 z 轴旋转 θ 度。

​ 第一种旋转

A=XY=[1000cosθsinθ0sinθcosθ][001010100]=[001sinθcosθ0cosθsinθ0]A=XY= \left[ \begin{matrix} 1 & 0 & 0\\ 0 & cosθ & -sinθ \\ 0 & sinθ & cosθ \\ \end{matrix} \right] \left[ \begin{matrix} 0 & 0 & 1\\ 0 & 1 & 0 \\ -1 & 0 & 0 \\ \end{matrix} \right]= \left[ \begin{matrix} 0 & 0 & 1\\ sinθ & cosθ & 0 \\ -cosθ & sinθ & 0 \\ \end{matrix} \right]

​ 第二种旋转

B=YZ=[001010100][cosθsinθ0sinθcosθ0001]=[001sinθcosθ0cosθsinθ0](3)B=YZ= \left[ \begin{matrix} 0 & 0 & 1 \\ 0 & 1 & 0 \\ -1 & 0 & 0 \end{matrix} \right] \left[ \begin{matrix} cosθ & -sinθ & 0 \\ sinθ & cosθ & 0 \\ 0 & 0 & 1 \end{matrix} \right]= \left[ \begin{matrix} 0 & 0 & 1 \\ sinθ & cosθ & 0 \\ -cosθ & sinθ & 0 \end{matrix} \right] \tag{3}

​ 可以发现 XY=YZ,换句话说就是,在绕 y 轴旋转 90 度后,此时绕 z 轴旋转相当于,在绕 y 轴旋转前绕 x 轴旋转。

​ 既然出现万向死锁的原因是之后的旋转是基于最开始的坐标旋转的,那么如果每次旋转都改变坐标系,在根据目前的坐标系旋转,会不会能解决这个问题呢。

​ 同样的绕 xyz 轴旋转,这次后面两次的旋转不再按照初始的坐标轴转,而是转完后重新建系。

  1. 首先绕 x 轴旋转

ry=XYX1r_y=XYX^{-1}

  1. 其实这时候将上面两个相乘就会发现问题,这时候继续绕 z 轴旋转。

rz=ryrxZ(ryrz)1=XYX1XZ(XYX1X)1=XYZY1X1r_z=r_yr_xZ(r_yr_z)^{-1}=XYX^-1XZ(XYX^{-1}X)^{-1}=XYZY^{-1}X^{-1}

  1. 最后将这三个旋转依次相乘。

rzryrx=XYZY1X1XYX1X=XYZr_zr_yr_x=XYZY^{-1}X^{-1}XYX^{-1}X=XYZ

​ 最终发现此时绕 xyz 轴旋转相当于绕 zyx 轴旋转,那么之前绕着初始坐标轴旋转出现的万向死锁问题,在旋转后重新建系也会出现。换句话说,万向死锁无解,此时旋转应该使用四元数。

​ 总结一下欧拉角的缺点,存在万向死锁,且旋转一次需要用到四阶矩阵也即 16 个数,占用空间而且不好插值。唯一的好处可能就是简单易懂。

参考资料:

href="bonus_gimbal_lock.pdf (krasjet.github.io)

【熟肉】线性代数的本质 - 09 - 基变换_哔哩哔哩_bilibili](https://www.bilibili.com/video/BV1Ls411b7r2/

# 二、四元数

​ 四元数由一个实部和三个虚部 (i,j,k) 组成 q=a+bi+cj+dk。虚部可以写成一个三维向量,q=[s,v], 其中 v 是虚部。ijk 有以下关系。

i2=j2=k2=ijk=1i^2=j^2=k^2=ijk=-1

​ 关于四元数与旋转的公式推导可以参考 Krasjet 大佬的文章:quaternion.pdf (ruc.edu.cn)。以下直接说结论。

​ 向量 v 绕着旋转轴 u 旋转 θ 度,令 v=[0,v],q=[cos (θ/2),sin (θ/2) u],u 是单位向量,四元数的模长为 1,旋转后的向量为

v=qvq1=qvqv^`=qvq^{-1}=qvq^*

​ 四元数转为矩阵旋转:

v=[12c22d22bc2ad2ac+2bd2bc+2ad12b22d22cd2ab2bd2ac2ab+2cd12b22c2]vv^`= \left[ \begin{matrix} 1-2c^2-2d^2 & 2bc-2ad & 2ac+2bd \\ 2bc+2ad & 1-2b^2-2d^2 & 2cd-2ab \\ 2bd-2ac & 2ab+2cd & 1-2b^2-2c^2 \\ \end{matrix} \right]v

​ 旋转复合:

​ 假设有两个不同的轴,旋转度数不同的四元数 q1,q2. 向量 v 先绕着 q1 所在的轴旋转然后再绕着 q2 所在的轴旋转。

v=q2q1vq11q21=q2q1vq1q2v^`=q_2q_1vq_1^{-1}q_2^{-1}=q_2q_1vq_1^*q_2^*

​ 其中 q1 和 q2 可以先乘起来,这点与矩阵相同。假设有个 q=q2q1

v=q2q1vq11q21=qvq1v^`=q_2q_1vq_1^{-1}q_2^{-1}=qvq^{-1}

​ 旋转指数形式:

euθ=cosθ+usinθe^{uθ}=cosθ+usinθ

​ 其中 u 为四元数虚部,也即 ijk 三组基组成的三维向量。

v=qvq1=euθ/2veuθ/2v^`=qvq^{-1}=e^{uθ/2}ve^{-uθ/2}

# 3. 平移,缩放

​ 平移和缩放相对于旋转就简单多了。

​ 平移矩阵:

[100vx010vy001vz0001]\left[ \begin{matrix} 1 & 0 & 0 & v_x \\ 0 & 1 & 0 & v_y \\ 0 & 0 & 1 & v_z \\ 0 & 0 & 0 & 1 \\ \end{matrix} \right]

​ 因为平移不是线性变换,而是仿射变换,描述 3 维物体的平移使用三阶矩阵是不行的,得使用四阶矩阵。这时候要给三维向量多一个维度也即 w,此时的向量为 (x,y,z,w), 其中 w 为 1。这个叫做齐次坐标要转成三维坐标只需要给前面三个分量依次除于 w 即可。即(x/w,y/w,z/w)。

​ 缩放矩阵:

x_t & 0 & 0 \\ 0 & y_t & 0 \\ 0 & 0 & z_t \\

​ 想要缩放 x 轴,只需要改变 xt 即可,对于 yz 同理。如果 xyz 的缩放相同,整个物体就会等比例缩放,如果 xyz 缩放不同,物体看起来会压缩或者拉伸。

# 4. 复合矩阵

​ 与旋转同理,可以将平移,缩放,旋转矩阵分别乘起来得到一个新的矩阵,新的矩阵的几何意义就是对物体进行平移,缩放,旋转。因为平移需要四阶矩阵,所以旋转,缩放得化成四阶矩阵,除第四列四行为 1,其他四行和四列为 0。

​ 缩放矩阵 (四阶形式):

x_t & 0 & 0 & 0\\ 0 & y_t & 0 & 0 \\ 0 & 0 & z_t & 0\\ 0 & 0 & 0 & 1\\