从四元数转换到矩阵

为了将角位移从四元数转换到矩阵形式,可以利用旋转矩阵,它能计算绕任意轴的旋转:

这个矩阵是用n和θ表示的,但四元数的分量是:

w = cos(θ/2)

x = nx sin(θ/2)

y = ny sin(θ/2)

z = nz sin(θ/2)

让我们看看能否将矩阵变形以代入w、x、y、z,矩阵的9个元素都必须这样做。幸运的是,这个矩阵的结构非常好,一旦解出对角线上的一个元素,其他元素就能用同样的方法求出。同样,非对角线元素之间也是彼此类似的。

考虑矩阵对角线上的元素,我们将完整地解出m11,m22和m33解法与之类似:

m11 = nx2(1 - cosθ) + cosθ

我们将从上式的变形开始,变形方法看起来像是在绕圈子,但你马上就能理解这样做的目的:

现在需要消去cosθ项,而代之以包含cosθ/2或sinθ/2的项,因为四元数的元素都是用它们表示的,像以前那样,设α=θ/2,先用α写出cos的倍角公式,再代入θ:

上式是正确的,但它和其他的标准形式不同,即:

m11 = 1 - 2y2 - 2z2

实际上,还有其他的形式存在。最著名的一个形式是m11 = w2 + x2 - y2- z2,因为w2 + x2 + y2 + z2 = 1,所以这三种形式是等价的。现在回过头来看看能不能直接导出其他标准形式,第一步,n是单位向量,nx2+ny2 + nz2 = 1,则1 - nx2 = ny2 + nz2

m11 = 1 - (1 - nx2)(2sin2(θ/2))

= 1 - (ny2 +nz2)(2sin2(θ/2))

= 1 - 2ny2sin2(θ/2) - 2nz2sin2(θ/2)

= 1 - 2y2 - 2z2

元素m22和m33可以用同样的方法求得。

让我们来看看非对角线元素,它们比对角线元素简单一些,以m12为例子:

m12 = nxny(1 - cosθ) + nzsinθ

其他非对角线元素可用同样的方法导出。

最后,给出从四元素构造的完整旋转矩阵,如公式10.23所示:

 

从矩阵转换到四元数

为了从旋转矩阵中抽出相应的四元数,可以直接利用公式 10.23,检查对角线元素的和(也称作矩阵的轨迹)得到:

通过使轨迹中三个元素中的两个为负,可以用类似的方法求得其他三个元素:

不幸的是,这种方法并不总是能正确工作,因为平方根的结果总是正值。(更加准确地说,没有选择正根还是负根的依据。)但是,q和-q代表相同的方位,我们能任意选择用非负根作为4个分量中的一个并仍能得到正确的四元数,只是不能对四元数的所有4个数都用这种方法。

另一个技巧是检查相对于对角线的对称位置上元素的和与差:

那么应选用四种方法中的哪个呢?似乎最简单的策略是总是先计算同一个分量,如w,然后再计算x、y、z。这伴随着问题,如果w=0,除法就没有定义;如果w非常小,将会出现数值不稳定。Shoemake建议先判断w、x、y、z中哪个最大(不用做平方根运算),根据上面的表,用矩阵对角线计算该元素,再用它计算其他三个。

下面的代码用一种非常直接的方式实现了这个方法。

        Listing 10.4: Converting a rotation matrix to a quaternion
   
    // Input matrix:
    float  m11,m12,m13;
    float  m21,m22,m23;
    float  m31,m32,m33;
   
    // Output quaternion
    float  w,x,y,z;
   
        // Determine which of w, x, y, or z has the largest absolute value
    float  fourWSquaredMinus1 = m11 + m22 + m33;
    float  fourXSquaredMinus1 = m11 – m22 – m33;
    float  fourYSquaredMinus1 = m22 – m11 – m33;
    float  fourZSquaredMinus1 = m33 – m11 – m22;
   
    int  biggestIndex = 0;
   
    float  fourBiggestSquaredMinus1 = fourWSquaredMinus1;
   
    if  (fourXSquaredMinus1 > fourBiggestSquaredMinus1) {
      fourBiggestSquaredMinus1 = fourXSquaredMinus1;
      biggestIndex = 1;
    }
   
    if  (fourYSquaredMinus1 > fourBiggestSquaredMinus1) {
      fourBiggestSquaredMinus1 = fourYSquaredMinus1;
      biggestIndex = 2;
    }
   
    if  (fourZSquaredMinus1 > fourBiggestSquaredMinus1) {
      fourBiggestSquaredMinus1 = fourZSquaredMinus1;
      biggestIndex = 3;
    }
   
        // Perform square root and division
    float  biggestVal = sqrt(fourBiggestSquaredMinus1 + 1.0f) * 0.5f;
    float  mult = 0.25f / biggestVal;
   
        // Apply table to compute quaternion values
    switch  (biggestIndex) {
    case  0:
      w = biggestVal;
      x = (m23 – m32) * mult;
      y = (m31 – m13) * mult;
      z = (m12 – m21) * mult;
      break ;
   
    case  1:
      x = biggestVal;
      w = (m23 – m32) * mult;
      y = (m12 + m21) * mult;
      z = (m31 + m13) * mult;
      break ;
   
    case  2:
      y = biggestVal;
      w = (m31 – m13) * mult;
      x = (m12 + m21) * mult;
      z = (m23 + m32) * mult;
      break ;
   
    case  3:
      z = biggestVal;
      w = (m12 – m21) * mult;
      x = (m31 + m13) * mult;
      y = (m23 + m32) * mult;
      break ;
    }

3D中的方位和角位移(7)相关推荐

  1. 3D 中的方位与角位移(旋转矩阵、欧拉角、四元数)

    文章目录 一.3D 中的方位与角位移 1. 欧拉角 (Euler angles) 2. 四元数的相关知识 2.1 复数 2.2 欧拉旋转定理 2.3 三维空间旋转的拆分 3. 四元数 (Quatern ...

  2. 3D中的方位与角位移

    摘要:本文讲述了3D中描述方位与角位移的方法:矩阵.欧拉角和四元数,以及它们优缺点和适用场景.给理解Gimbal Lock提供了一种新视角. 1. 简介 "方位"是指物体的朝向,是 ...

  3. 3D数学读书笔记——3D中的方位与角位移

    本系列文章由birdlove1987编写,转载请注明出处. 文章链接: http://blog.csdn.net/zhurui_idea/article/details/25339595 方位和角位移 ...

  4. 3D中的方位和角位移(2)

    另一种描述方位的常用方法是欧拉角,这项技术以著名的数学家Leonhard Euler(1707 - 1783)的名字命名,他证明了角位移序列等价于单个角位移. 什么是欧拉角 欧拉角的基本思想是将角位移 ...

  5. 3D中的方位和角位移(1)

    什么是方位 直观地说,我们知道物体的"方位"主要描述的是物体的朝向.然而"方向"和"方位"并不完全一样.向量有"方向"但 ...

  6. 3D中的方位和角位移(8)

    从欧拉角转换到四元数 为了将角位移从欧拉角转换到四元数,可以使用从欧拉角构造矩阵类似的方法.先将这三个旋转分别转换为四元数,这是一个简单的运算.再将这三个四元数连接成一个四元数.和矩阵一样,有两种情况 ...

  7. 3D数学之方位与角位移、欧拉角与四元数

    3D物体如何描述方位: 1.方向 2.角位移 3.旋转 方位≠方向 当向量自转时,不会改变向量的属性 但是物体自转时,物体的方位就变化了 表示方法: 位置:使用相对于参考系的位移 方位:相对于已知方位 ...

  8. WPF 3D中多个模型如何设置某一个在最前?

    原文:WPF 3D中多个模型如何设置某一个在最前? 问题:我们的模型包括导入的3D solid模型和axis坐标轴模型,当模型旋转的时候,3D会将axis挡住. 期望:axis一直在最前面,不会被3D ...

  9. Map 3D中程序设置地图中心点

    你可能需要在Map 3D中通过程序把某块地图拉到屏幕中央来,下面通过程序的方式来实现这个功能. 这里有两种情况,如果你在Map 3D中通过Data Connect连接到了一下FDO数据源(SDF.SH ...

最新文章

  1. 论文:基于粒子群优化的测试数据生成及其实证分析-----生成过程以及实验(计算机研究与发展)
  2. NFS安装系统及PS1设定
  3. 【转】几点 iOS 开发技巧
  4. 二级list列表python_Python list 列表
  5. 当PDF页面总数不确定的时候导出PDF增加页码(i of n)
  6. hdu 3068 最长回文【manacher】(模板题)
  7. 语言五子棋无ai程序框图_2020输入法报告 如何选择更好的AI语音输入法?
  8. phpcms如何做企业站-- 替换首页最初操作
  9. 算法排序代码(简单排序)
  10. 「每天一道面试题」Redis的优势有哪些?
  11. wer 流程图编程_WER机器人搭建学习实操练习
  12. 精益标准工时软件VIOOVI:没有标准工时,别谈精益改善!
  13. 2022年,尽量还是别裸辞了吧···
  14. JavaSE学习笔记_20:Java网络编程
  15. App Store 内购项目配置
  16. Web开发了一个完整精美的聊天室(登录部分引入了Vue技术)
  17. 数据结构之树从入门到如土(四)----从零开始入门Rust实现一颗B树(未完成待续)
  18. 安装opensips时创建MySQL表_Centos7.6安装opensips并实现通话成功
  19. 电容式加速度传感器(你会知道的文章)
  20. 多旋翼无人机组成(小白上路)

热门文章

  1. EVP 签名和校验 Signing and Verifying
  2. echarts地图随意绘制点
  3. 对对碰java_Java开发学习之用Java打造一款对对碰游戏(下篇)
  4. 自动化打包平台系列(一):自动化打平台建设概览
  5. 游戏开发笔记(二)——开发流程和项目管理
  6. 【C语言入门】ZZULIOJ 1036-1040
  7. 步进电机-STM32单片机定时器正弦波输出
  8. x64dbg和IDA pro 配置PDB 符号文件symbols
  9. Layui 手动验证表单
  10. 60帧的丝般顺畅 - QQ飞车手游优化点滴