rotation - 如何将旋转矩阵转换为四元数
问题描述
我可以将旋转矩阵转换为四元数吗?我知道如何将四元数转换为旋转矩阵,但我找不到与之相反的方法。我可以向您展示如何将四元数转换为旋转矩阵的代码,如下所示。
示例(C++):Quaterniond quat; MatrixXd t; t = quat.matrix();
我想知道像这样将旋转矩阵转换为四元数的方法。
解决方案
将方向余弦矩阵 D 转换为四元数 q 的数值稳定算法如下:
T = D(1,1) + D(2,2) + D(3,3)
M = max( D(1,1), D(2,2), D(3,3), T )
qmax = (1/2) * sqrt( 1 – T + 2*M )
if( M == D(1,1) )
qx = qmax
qy = ( D(1,2) + D(2,1) ) / ( 4*qmax )
qz = ( D(1,3) + D(3,1) ) / ( 4*qmax )
qw = ±( D(3,2) - D(2,3) ) / ( 4*qmax )
elseif( M == D(2,2) )
qx = ( D(1,2) + D(2,1) ) / ( 4*qmax )
qy = qmax
qz = ( D(2,3) + D(3,2) ) / ( 4*qmax )
qw = ±( D(1,3) - D(3,1) ) / ( 4*qmax )
elseif( M == D(3,3) )
qx = ( D(1,3) + D(3,1) ) / ( 4*qmax )
qy = ( D(2,3) + D(3,2) ) / ( 4*qmax )
qz = qmax
qw = ±( D(1,3) - D(3,1) ) / ( 4*qmax )
else
qx = ±( D(3,2) - D(2,3) ) / ( 4*qmax )
qy = ±( D(1,3) - D(3,1) ) / ( 4*qmax )
qz = ±( D(2,1) - D(1,2) ) / ( 4*qmax )
qw = qmax
endif
请注意,四元数中存在符号歧义。上面的算法任意选择最大元素 qmax 的符号为正,但选择该符号为负同样有效(即,本质上翻转了结果的所有符号)。由用户根据应用确定哪个是更合适的选择。
± 选择是根据您使用的四元数约定进行的:
为 Hamilton Left Chain Convention 或 JPL Right Chain Convention 选择 +
选择 - 汉密尔顿右链公约或 JPL 左链公约
汉密尔顿约定意味着四元数元素 i、j、k 以右手方式进行乘法(如叉积):
i * j = k , j * k = i , k * i = j
JPL 约定意味着四元数元素 i、j、k 以左手方式进行乘法(叉积的负数):
i * j = -k , j * k = -i , k * i = -j
Right Chain 表示向量上的四元数旋转操作在右侧具有未修改的四元数:
D * v1 = v2 = q^-1 * v1 * q
Left Chain 表示向量上的四元数旋转操作在左侧具有未修改的四元数:
D * v1 = v2 = q * v1 * q^-1
为了完整起见,这里是另一个方向的算法,将四元数转换为方向余弦矩阵:
D = (qw^2 - dot(qv,qv))*I3 + 2*qv*qv^T ± 2*qw*Skew(qv)
其中 ^T 表示转置(用于该术语中的外部产品)和
qv = [qx]
[qy]
[qz]
I3 = [1 0 0]
[0 1 0]
[0 0 1]
Skew(qv) = [ 0 -qz qy]
[ qz 0 -qx]
[-qy qx 0]
推荐阅读
- reactjs - 如何将高阶组件作为子组件附加
- python - 将浮点数转换回时间戳
- visual-studio - 如果您在 Git 存储库中有一个没有上游的分支,并且有多个遥控器,那么 Visual Studio 如何在您推送时选择使用哪个遥控器?
- python - 如何在开头没有空格的情况下打印此列表?
- node.js - 使用数组过滤器 (MongoDB) 时无法使用聚合运算符 $add 更新日期
- reactjs - 使用 store 中的数据时如何避免重新渲染功能组件
- cython - 为什么我不能在 Jupyterlab 的 Cython 中使用 int 参数?
- javascript - 单击时滚动到不滚动到正确的列表项
- flutter - 颤动中的流构建器延迟问题
- java - 如何检索已触摸的项目的 id?