python中用4元数实现3D旋转

利用4元数实现3d旋转有非常多的优点,相比于4x4矩阵,欧拉角的方式具有更好的计算高效性。一般的,4元数(x,y,z,w)表达空间旋转的表达方式如下:

设空间单位向量(a,b,c), 和一个夹角theta。则表示绕空间向量(a,b,c)沿顺时针(沿该向量相同方向看)旋转theta角的四元数为q = (a*sin(theta/2), b*sin(theta/2), c*sin(theta/2), cos(theta/2))。

若,空间上某向量v,按照四元数q旋转后得到的值为u,则

u = qvq(-1) (这里的乘法方式为哈密尔顿积

其中q(-1)指的是四元数q的逆,对于单位4元数的逆,恰恰等于原四元数的虚数部分去反。即,

若q = xi + yj + zk + w, 则q(-1) = -xi -yj -zk + w

除此以外,空间的多个旋转还可以串连起来,例如:

q = q2q1 计算所的的q为先按照q1旋转,再按照q2旋转的4元数。

实际工程应用中,可以使用numpy的numpy-quaternion和scipy的scipy.spatial.transform.Rotation来配合实现4元数的运算,以及4元数与3x3或4x4矩阵的转化。

示例代码如下:(如下代码要求scipy >= 1.4.0)

from scipy.spatial.transform import Rotation as R
import numpy as np
def makeRotationMatrix(theta, axis):
     m4 = np.identity(4)
     s = np.sin(theta/2)
     c = np.cos(theta/2)
     quat = np.zeros([4])
     quat[0:3] = axis * s
     quat[3] = c
     r = R.from_quat(quat)
     m3 = r.as_matrix()
     m4[0:3, 0:3] = m3
     return m4

def makeTranslationMatrix(vec):
     m4 = np.identity(4)
     m4[0:3,3] = vec
     return m4