3D数学基础--3D中的方位与角位移(2)

2024-05-09 07:32

本文主要是介绍3D数学基础--3D中的方位与角位移(2),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

前言:3D中讨论的四元数都是单位四元数

四元数记法

上一章节讲了用三个数表达3D方位一定会有万向锁这样的问题,它涉及到一些非常高级的数学概念,如“簇”。而四元数通过使用四个数来表达方位,从而可以避免这些问题,下面先来看看它的记法:
这里写图片描述
注:w:类似复数实部,v:虚数。

四元数的数学渊源

四元数其实是由数学里的复数引申而来的,首先来简单说下什么是复数?复数=实数+虚数,它扩展了如对一个负数开平方根的问题。下面来看看复数的定义:
这里写图片描述
复数集存在于一个2D平面上,这个平面有两个轴:实轴(x)和虚轴(y)。这样,就能将复数(x,y)解释为一个2D向量,好的,现在我们可以这样通俗的理解,复数=向量。下面再来看看用复数怎么表达平面中的旋转:
这里写图片描述
从上面可以看出引入复数q和用2×2旋转矩阵达到的效果是一样的,目前为止,我们已经将复数和前面学习的知识联系起来了,而现在我们讲的只是2D平面,那么怎么把复数扩展到3D中呢?它又怎么和四元数联系起来呢?下面我们来看下书上关于它的一个典故:
这里写图片描述
四元数扩展复数系统,它使用了三个虚部i, j, k。它们关系如下:
这里写图片描述

四元数几何意义

欧拉证明了一个旋转序列等价于单个旋转,因此,3D中的任意角位移都能表示为绕单一轴的单一旋转。我们记角度为θ,旋转轴为n(向量),那么绕n轴旋转θ角度,可用复数形式表示为(θ,n),那么其对应的四元数表示为:
这里写图片描述
注释:我们可以近似把一个四元数理解为一个旋转矩阵或角位移。

四元数的一般数学运算

  • 负四元数:
    这里写图片描述
    q和-q代表的角位移是相同的,其实就是相当于将θ加上360°的倍数,对方位没影响。所以负四元数只是在数学上把它的四个分量都变负了,但几何上它们是等效的。即3D中任意角位移都有两种不同的四元数表示方法,它们互相为负。

  • 没有角位移的单位四元数:
    这里写图片描述
    注:代入上面四元数的四个值公式即可得出。

  • 四元数的模:
    这里写图片描述
    而我们3D数学里只使用模为1的四元数(单位四元数),即前面列出的四元数的四个值公式的四元数。

  • 四元数的共轭和逆:
    数学定义我就直接拿书上讲的,如下:
    这里写图片描述
    由于我们只使用单位四元数,所以四元数的逆和共轭是相等的。那么,它们有什么几何意义呢?共轭其实就是把四元数的向量部分变负,所以一个四元数的共轭就是代表一个相反的角位移。
    注释:其实我们还可以保持四元数向量部分不变,而让角度部分变负,同样能代表一个相反的角位移。但为了和复数的共轭概念一致,所以四元数的共轭用上面那种形式定义。

  • 四元数的叉乘:
    四元数的叉乘不用乘号,而且行与列的形式也没什么区别,下面是四元数乘法的标准定义:
    这里写图片描述
    但我们实际不用这种形式,具体原因这里不打算详细讲解,大体是因为这个形式会导致多个变换连接成一个后,变换顺序会颠倒。以后会把这些数学计算封装成一个四元数的类,对于里面的数据我们不再需要管。之所以用叉乘就是执行旋转变换时需要用到它。

  • 四元数“差”:
    四元数的差是指一个方位到另一个方位的角位移。我们用四元数表示是:从a旋转到b的角位移d等于:这里写图片描述

  • 四元数点乘:
    四元数的点乘和向量的点乘很类似,几何原理也类似,a·b的绝对值越大,a和b代表的角位移越“相似”。公式如下:
    这里写图片描述

四元数的高级数学运算

  • 四元数的对数,指数和标量乘运算:
    虽然这些运算我们很少直接使用它们,但它们是某些重要四元数运算的基础,下面来分别看看它们的定义:
    这里写图片描述

    这里写图片描述

    这里写图片描述

  • 四元数求幂:
    注意它与上面指数运算的区别,指数运算底数是e,而这里是四元数做底数。所以,指数运算只要一个参数–四元数,而四元数求幂要两个参数–四元数和指数。公式如下:
    这里写图片描述
    再来说说它能做什么用?假设,四元数q代表一个角位移,现在想要得到代表1/3这个角位移的四元数,其实就是等于这个四元数的1/3次幂。即四元数求幂它可以从角位移中抽取一部分。

    四元数求幂代码实例:

//四元数输入和输出float w, x, y, z;//指数float exponent;//检查单位四元数,避免除零if(fabs(w) < 0.9999f){//提取半角float alpha = acos(w);//计算新的alpha值float newAlpha = alpha * exponent;//计算新的w值w = cos(newAlpha);//计算新的x, y, z 值float mult = sin(newAlpha) / sin(alpha);x *= mult;y *= mult;z *= mult;}
  • 四元数插值(slerp):
    当今3D数学中四元数之所以存在的理由就是利用它可以在两个四元数间平滑的插值。它避免了欧拉角插值的所有问题。具体的推导过程就不详细解释了,有兴趣的可以自己查阅相关资料(3D数学基础图形与游戏开发),下面直接贴出公式:
    这里写图片描述

    slerp代码实例:

//两个输入四元数float w0, x0, y0, z0;float w1, x1, y1, z1;//插值变量float t;//输出四元数float w, x, y, z;//用点乘计算两四元数夹角的cos值float cosOmega = w0 * w1 + x0 * x1 + y0 * y1 + z0 * z1;//如果点乘为负,则反转一个四元数以取得短的4D弧if(cosOmega < 0.0f){w1 = -w1;x1 = -x1;y1 = -y1;z1 = -z1;cosOmega = -cosOmega;}//检查插值的起点和终点是否过于接近以避免除零float k0, k1;if(cosOmega > 0.9999f){//非常接近,直接用线性插值k0 = 1.0 - t;k1 = t;}else{//用三角公式sin^2(cosOmega) + cos^2(cosOmega) = 1计算出sinwfloat sinOmega = sqrt(1.0f - cosOmega * cosOmega);//通过sinw 和 cosw计算w夹角float omega = atan2(sinOmega, cosOmega);//计算分母的倒数,这样只需要一次除法float oneOverSinOmega = 1.0f / sinOmega;//计算插值变量k0 = sin((1.0f - t) * omega) * oneOverSinOmega;k1 = sin(t * omega) * oneOverSinOmega;}//得到插值w = w0 * k0 + w1 * k1;x = x0 * k0 + x1 * k1;y = y0 * k0 + y1 * k1;z = z0 * k0 + z1 * k1;
  • 四元数样条(squad):
    slerp(球面线性插值)只提供了两个方位间的插值,但对于超过两个的方位序列,我们要进行插值就得用到squad。对于其具体数学原理推导这里也不打算讲了。

四元数的优点和缺点

  • 四元数的一些其他角位移表示方法所没有的优点:
    1,平滑插值
    2,快速连接和角位移求逆,同样的操作,它要比矩阵快且容易些。
    3,能快速转换成矩阵形式。
    4,仅用四个数表示。

  • 缺点:
    1,比欧拉角稍微大一些。
    2,四元数可能不合法。因为我们讨论的有意义的四元数必须是单位大小,而输入坏数据或浮点数舍入误差累积都可能使四元数不合法(当然我们可以通过四元数标准化来解决这个问题)。
    3,难于使用,在所有三种形式中,四元数是最难直接使用的。

这篇关于3D数学基础--3D中的方位与角位移(2)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/972777

相关文章

Three.js构建一个 3D 商品展示空间完整实战项目

《Three.js构建一个3D商品展示空间完整实战项目》Three.js是一个强大的JavaScript库,专用于在Web浏览器中创建3D图形,:本文主要介绍Three.js构建一个3D商品展... 目录引言项目核心技术1. 项目架构与资源组织2. 多模型切换、交互热点绑定3. 移动端适配与帧率优化4. 可

从基础到高级详解Python数值格式化输出的完全指南

《从基础到高级详解Python数值格式化输出的完全指南》在数据分析、金融计算和科学报告领域,数值格式化是提升可读性和专业性的关键技术,本文将深入解析Python中数值格式化输出的相关方法,感兴趣的小伙... 目录引言:数值格式化的核心价值一、基础格式化方法1.1 三种核心格式化方式对比1.2 基础格式化示例

redis-sentinel基础概念及部署流程

《redis-sentinel基础概念及部署流程》RedisSentinel是Redis的高可用解决方案,通过监控主从节点、自动故障转移、通知机制及配置提供,实现集群故障恢复与服务持续可用,核心组件包... 目录一. 引言二. 核心功能三. 核心组件四. 故障转移流程五. 服务部署六. sentinel部署

从基础到进阶详解Python条件判断的实用指南

《从基础到进阶详解Python条件判断的实用指南》本文将通过15个实战案例,带你大家掌握条件判断的核心技巧,并从基础语法到高级应用一网打尽,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一... 目录​引言:条件判断为何如此重要一、基础语法:三行代码构建决策系统二、多条件分支:elif的魔法三、

Python WebSockets 库从基础到实战使用举例

《PythonWebSockets库从基础到实战使用举例》WebSocket是一种全双工、持久化的网络通信协议,适用于需要低延迟的应用,如实时聊天、股票行情推送、在线协作、多人游戏等,本文给大家介... 目录1. 引言2. 为什么使用 WebSocket?3. 安装 WebSockets 库4. 使用 We

从基础到高阶详解Python多态实战应用指南

《从基础到高阶详解Python多态实战应用指南》这篇文章主要从基础到高阶为大家详细介绍Python中多态的相关应用与技巧,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 目录一、多态的本质:python的“鸭子类型”哲学二、多态的三大实战场景场景1:数据处理管道——统一处理不同数据格式

MySQL数据类型与表操作全指南( 从基础到高级实践)

《MySQL数据类型与表操作全指南(从基础到高级实践)》本文详解MySQL数据类型分类(数值、日期/时间、字符串)及表操作(创建、修改、维护),涵盖优化技巧如数据类型选择、备份、分区,强调规范设计与... 目录mysql数据类型详解数值类型日期时间类型字符串类型表操作全解析创建表修改表结构添加列修改列删除列

Python 函数详解:从基础语法到高级使用技巧

《Python函数详解:从基础语法到高级使用技巧》本文基于实例代码,全面讲解Python函数的定义、参数传递、变量作用域及类型标注等知识点,帮助初学者快速掌握函数的使用技巧,感兴趣的朋友跟随小编一起... 目录一、函数的基本概念与作用二、函数的定义与调用1. 无参函数2. 带参函数3. 带返回值的函数4.

python panda库从基础到高级操作分析

《pythonpanda库从基础到高级操作分析》本文介绍了Pandas库的核心功能,包括处理结构化数据的Series和DataFrame数据结构,数据读取、清洗、分组聚合、合并、时间序列分析及大数据... 目录1. Pandas 概述2. 基本操作:数据读取与查看3. 索引操作:精准定位数据4. Group

使用Python绘制3D堆叠条形图全解析

《使用Python绘制3D堆叠条形图全解析》在数据可视化的工具箱里,3D图表总能带来眼前一亮的效果,本文就来和大家聊聊如何使用Python实现绘制3D堆叠条形图,感兴趣的小伙伴可以了解下... 目录为什么选择 3D 堆叠条形图代码实现:从数据到 3D 世界的搭建核心代码逐行解析细节优化应用场景:3D 堆叠图