四元数(Quaternion)的一些性质

        四元数(Quaternion)是用于三维旋转和定向的四部分组成的超复数,超复数简单理解就是比a+bi这样的复数更复杂的复数,其中a+bi这样的复数我们也可以叫做二元数,表示复平面的一点,对于熟悉欧拉公式的朋友就知道,也可以看成是平面上的旋转。
由于二元数是在二维平面的旋转,于是哈密顿就在想是否可以找到一个表示三维空间旋转的复数呢?于是这个四元数就诞生了。
四元数的表示形式为:a +bi+cj+dk(或者w+xi+yj+zk),其中a、b、c、d是实数,i、j、k是三个虚数单位,满足 i² = j² = k² = ijk =−1,每个四元数都是a和i, j, k的线性组合。
因为四元数非常适合表示三维空间的旋转,跟旋转矩阵相比,四元数是没有奇异点的,也就是说两个不同的旋转是不可能存在同样的四元数,这样就避免了机器人中的“万向节死锁”的问题,万向节死锁的本质就是少了一个自由度,比如两个轴重合了,这样就无论怎么旋转都达不到预期了,而四元数不会出现这样的情况,所以特别好使。

1、概述

我们来看下i、j、k的旋转对应着XYZ的哪根轴旋转。
RPY分别表示翻滚角(Roll)、俯仰角(Pitch)、偏航角(Yaw),这几个很好理解,比如开飞机的时候,战斗机在空中旋转,如果是绕X轴旋转,就叫做翻滚;如果是绕Y轴旋转,比如起飞降落这样的情况就叫做俯仰;偏航角就是绕Z轴旋转,这个很简单,就是左右打方向盘。

i旋转代表Z轴与Y轴相交平面中Z轴正向向Y轴正向的旋转。两条轴就是两条直线,就确定一个面,所以就是Z轴向Y轴旋转,那本质就是绕X轴旋转,对应着Roll翻滚角。
j旋转代表X轴与Z轴相交平面中X轴正向向Z轴正向的旋转,就是绕Y轴旋转,对应着Pitch俯仰角。
k旋转代表Y轴与X轴相交平面中Y轴正向向X轴正向的旋转,就是绕Z轴旋转,对应着Yaw偏航角。
简单来说ijk对应着rpy

2、四元数性质

我们先来熟悉四元数具备哪些性质:

i² = j² = k² = ijk =−1
ij = k
ji = -kjk = i,kj = -i
ki = j,ik = -j

这个很好理解,跟刚学习时的虚数i的计算是一样的,但是请注意,四元数是没有乘法交换律的,所以上面的ij≠ji,这个跟矩阵类似,A*B和B*A是不一样的。
四元数的L2范数:a²+b²+c²+d²,四个平方和的平方根,也就是它的模。

加减乘除
我们来计算两个四元数的加减乘除:

% 定义四元数
x=quaternion(3,1,0,0);
% 3 + 1i + 0j + 0k
y=quaternion(0,5,1,-2);
% 0 + 5i + 1j - 2k% x取模(L2范数)
x.norm() 或者 norm(x)
% 3.1623
% x的共轭四元数
x.conj()
% 3 - 1i + 0j + 0k
y.conj()
% 0 - 5i - 1j + 2k

共轭复数就是实部不变,虚部是相反数。

%加法
x+y
% 3 + 6i + 1j - 2k
%减法
x-y
% 3 - 4i - 1j + 2k%计算x*y
x*y
% -5 + 15i +  5j -  5k
% 乘法不遵循交换律
y*x
% -5 + 15i +  1j -  7k%除法分为左除和右除
%左除
x.\y
% 0.5 + 1.5i + 0.1j - 0.7k
%右除
x./y
% 0.16667 -     0.5i - 0.16667j + 0.16667k

3、四元数构造

我们先来熟悉如何自己来构造四元数:

a=1;b=2;c=3,d=4;
quat = quaternion(a,b,c,d);
% 1 + 2i + 3j + 4k
%虽然这里我是用的是整数,但四元数的类型是double型
classUnderlying(quat)
% 'double'

也可以使用四元数组来构造:

A = [1.1;1.2];
B = [2.1;2.2];
C = [3.1;3.2];
D = [4.1;4.2];
quaternion(A,B,C,D)
%得到2x1的四元数组
1.1 + 2.1i + 3.1j + 4.1k
1.2 + 2.2i + 3.2j + 4.2kA = [1.1,1.3;1.2,1.4];
B = [2.1,2.3; 2.2,2.4];
C = [3.1,3.3; 3.2,3.4];
D = [4.1,4.3; 4.2,4.4];
quatMatrix=quaternion(A,B,C,D)
%得到2x2的四元数矩阵
1.1 + 2.1i + 3.1j + 4.1k     1.3 + 2.3i + 3.3j + 4.3k
1.2 + 2.2i + 3.2j + 4.2k     1.4 + 2.4i + 3.4j + 4.4k
%转成Nx4的系数矩阵
compact(quatMatrix)
1.1000    2.1000    3.1000    4.1000
1.2000    2.2000    3.2000    4.2000
1.3000    2.3000    3.3000    4.3000
1.4000    2.4000    3.4000    4.4000

还可以构造Nx1的随机四元数矩阵

quaternion(randn(5,4))
%结果类似
1.4384 -   0.10224i -  0.030051j -   0.86365k
0.32519 -   0.24145i -   0.16488j +  0.077359k
-0.75493 +   0.31921i +   0.62771j -    1.2141k
1.3703 +   0.31286i +    1.0933j -    1.1135k
-1.7115 -   0.86488i +    1.1093j - 0.0068493k

4、旋转向量与四元数

旋转向量包括旋转角度或者弧度,它们之间的相互转换如下:

% 绕X轴旋转60°
d1 = [60,0,0];
quat = quaternion(d1,'rotvecd')
%0.86603 +    0.5i +      0j +      0k
% 绕Y轴旋转60°
d2 = [0,60,0];
quat = quaternion(d2,'rotvecd')
%0.86603 +      0i +    0.5j +      0k
% 绕Z轴旋转60°
d3 = [0,0,60];
quat = quaternion(d3,'rotvecd')
%0.86603 +      0i +      0j +    0.5k
d4 = [60,60,60];
quat = quaternion(d4,'rotvecd')
%0.61619 + 0.45472i + 0.45472j + 0.45472k

到d4的时候,这个结果是怎么来的,就有了疑问,我们来看下计算过程。
三维旋转向量为:v=[vx,vy,vz],θ=||v||,于是就得到公式如下:
四元数=(cos(θ/2),sin(θ/2)*vx/θ,sin(θ/2)*vy/θ,sin(θ/2)*vz/θ)
还是画一张图来更直观的了解下其推导过程:

从图中我们通过复平面的欧拉公式,可以很容易地将旋转向量转换成为一个四元数,其中角度拆分成一半,这样就算是180度重合,也是没有问题的,可能也有基于这个原因的考虑吧。
示例:

%旋转角度(60°,30°,90°),为便于计算,我们先转换成弧度:
v=[pi/3,pi/6,pi/2];
theta=norm(v); %1.9591
%四元数实部
a=cos(theta/2); %0.5574
%四元数虚部
b=sin(theta/2)*v(1)/theta %0.4438
c=sin(theta/2)*v(2)/theta %0.2219
d=sin(theta/2)*v(3)/theta %0.6657
或者
sin(theta/2)*[v/theta] %0.4438    0.2219    0.6657
所以这个四元数a+bi+cj+dk的结果为:0.5574+0.4438i+0.2219j+0.6657k
%四元数转换成旋转向量
rotvecd(quat)%弧度,rotvecd修改为rotvec即可
rotationVector = [pi/3,pi/6,pi/2];
quat = quaternion(rotationVector,'rotvec')
%0.55738 + 0.44379i + 0.22189j + 0.66568k
rotvec(quat)
%1.0472    0.5236    1.5708

这里相当于也再次验证上面的推导,我们来看下旋转矩阵和欧拉角的转换

5、旋转矩阵与四元数

%旋转矩阵转换成四元数
M = [1 0 0; 0 sqrt(3)/2 0.5; 0 -0.5  sqrt(3)/2];
quat = quaternion(M,'rotmat','frame')
%0.96593 + 0.25882i +       0j +       0k
%quaternion(M,'rotmat','point')
rotmat(quat,'frame')
ans =1.0000         0         00    0.8660    0.50000   -0.5000    0.8660

6、欧拉角与四元数

%欧拉角转换成四元数
E = [pi/2,0,pi/4];
quat = quaternion(E,'euler','ZYX','frame')
%0.65328 +  0.2706i +  0.2706j + 0.65328k
%quaternion(E,'euler','ZYX','point')
%四元数转换成欧拉角
euler(quat,'ZYX','frame')
ans =1.5708         0    0.7854

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/739197.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Sui与数据平台ZettaBlock达成合作,为其公测提供数据

Sui一向以闪电般的速度、无限水平扩展著称,现已迅速成为DeFi活动的重要场所。近期,数据平台ZettaBlock宣布在其开创性的Web3数据平台发布中,选择Sui作为基础集成合作伙伴之一。在ZettaBlock的开放测试版发布之际,构建者和开发者将…

双指针算法练习

27. 移除元素 题目 给你一个数组 nums 和一个值 val,你需要 原地 移除所有数值等于 val 的元素,并返回移除后数组的新长度。 不要使用额外的数组空间,你必须仅使用 O(1) 额外空间并 原地 修改输入数组。 元素的顺序可以改变。你不需要考虑…

JS 事件捕获、事件冒泡、事件委托

js事件机制在开发中可以说时刻使用,例如dom绑定事件、监听其自身事件等。js事件机制有事件捕获、事件冒泡俩种机制,我们分别说下这俩种机制的使用场景。 一、概念 事件捕获顺序如下: window > document > body > div 事件冒泡顺序…

Using WebView from more than one process

关于作者:CSDN内容合伙人、技术专家, 从零开始做日活千万级APP。 专注于分享各领域原创系列文章 ,擅长java后端、移动开发、商业变现、人工智能等,希望大家多多支持。 未经允许不得转载 目录 一、导读二、概览三、问题过程源码追踪…

【C++进阶】C++继承概念详解

C继承详解 一,继承的概念和定义1.1 继承的概念1.2 继承的定义1.3 继承关系和访问限定符 二,基类和派生类的对象赋值转移三,继承的作用域四,派生类的默认成员函数五,继承和友元&静态成员和继承六,菱形继…

vue 在线预览word

1 mammoth 先找的是mammoth这个插件yarn add mammoth,版本是1,7.0 参考网上的示例使用如下: import mammoth from "mammoth"; const vHtml ref("") const readExcelFromRemoteFile (url) >{var xhr new XMLHttpRequest();xhr.open("…

柚见第十一期(前端页面开发)

创建队伍 便于控制样式,在外面套一层div 创建假数据模拟后端传来数据 //假数据模拟 const initFormData { "name": "", "description": "", "expireTime": "", "maxNum": 0, "passwor…

未来艺术展览新趋势——3D线上画展如何创新展示?

一、艺术展示的数字化转型 随着科技的不断进步,3D线上画展作为艺术展示的新趋势,正逐渐改变着人们欣赏和购买艺术作品的方式。对于画家而言,3D线上画展不仅提供了一个全新的平台来展示他们的作品,还开辟了销售渠道,扩大…

天梯赛的赛场安排(Python)

作者 陈越 单位 浙江大学 天梯赛使用 OMS 监考系统,需要将参赛队员安排到系统中的虚拟赛场里,并为每个赛场分配一位监考老师。每位监考老师需要联系自己赛场内队员对应的教练们,以便发放比赛账号。为了尽可能减少教练和监考的沟通负担&#…

可视化表单流程编辑器为啥好用?

想要提升办公率、提高数据资源的利用率,可以采用可视化表单流程编辑器的优势特点,实现心中愿望。伴随着社会的进步和发展,提质增效的办公效果一直都是很多职场办公团队的发展需求,作为低代码技术平台服务商,流辰信息团…

【CSP试题回顾】201709-2-公共钥匙盒

CSP-201709-2-公共钥匙盒 关键点 1. 选择恰当的数据结构存储钥匙的存取操作 结构体MyKey包含三个字段:time、opt和index。 time字段表示操作发生的时间点。对于取钥匙的操作,这个时间就是老师上课的开始时间;对于还钥匙的操作&#xff0c…

Ollama 只安装 Ollama,本地快速部署谷歌开源大模型Gemma(基于Ollama)

参考:本地快速部署谷歌开源大模型Gemma(基于Ollama) - 知乎 确保系统更新: Bash sudo apt update && sudo apt upgrade 需要先下载Ollama,版本要求0.1.26及以上 运行curl -fsSL https://ollama.com/install.sh | sh 监听 Ollama API 接…

C++ 之LeetCode刷题记录(三十九)

😄😊😆😃😄😊😆😃 开始cpp刷题之旅。 目标:执行用时击败90%以上使用 C 的用户。 22. 括号生成 数字 n 代表生成括号的对数,请你设计一个函数,用…

2023年河北省职业院校技能大赛(高职组) “云计算”赛项任务书

2023年河北省职业院校技能大赛 “云计算”赛项任务书 第一场次:私有云(50分)任务一、私有云服务搭建(15分)任务二、私有云服务运维(25分)任务三、私有云运维开发(10分) 第二场次:容器云任务一、容器云服务搭建任务(5分)任务二、容器云应用部署…

2024年春招助学活动:一批FPGA高端项目让你轻松拿到大厂offer

这里写目录标题 1、前言2、FPGA行业现状3、简历怎么写4、FPGA高端项目4.1 图像类:FPGA图像缩放多路视频拼接4.2 通信类:千兆网UDP协议栈4.3 通信类:万兆网UDP协议栈4.4 图像通信综合:FPGA图像缩放UDP网络视频传输4.5 图像高速接口…

零基础学习JS--基础篇--JavaScript类型化数组

JavaScript 类型化数组是一种类似数组的对象,并提供了一种用于在内存缓冲中访问原始二进制数据的机制。 引入类型化数组并非是为了取代 JavaScript 中数组的任何一种功能。相反,它为开发者提供了一个操作二进制数据的接口。这在操作与平台相关的特性时会…

Java SE String类(一):常用方法(上)

1. 常用方法 1.1 字符串构造 String类的常用构造方法只有以下三种 public class Main {public static void main(String[] args) {String s1 "hello";//使用常量串进行构造String s2 new String("hello");//创建String对象char[] array {h,e,l,l,o};…

DeepLearning in Pytorch|我的第一个NN-共享单车预测

目录 概要 一、数据准备 导入数据 数据可视化 二、设计神经网络 版本一 版本二(正片) 三、测试 小结 概要 我的第一个深度学习神经网络模型---利用Pytorch设计人工神经网络对某地区租赁单车的使用情况进行预测 输入节点为1个,隐含…

大预言模型——ChatGPT,Claude3、Sora、等技术

原文链接:大预言模型——ChatGPT,Claude3、Sora、等技术https://mp.weixin.qq.com/s?__bizMzUzNTczMDMxMg&mid2247596849&idx3&sn111d68286f9752008bca95a5ec575bb3&chksmfa823ad6cdf5b3c0c446eceb5cf29cccc3161d746bdd9f26cc060f78c359ec3e2a8f35…

预测建模案例-预防机器故障

预测分析是一种使用当前数据和历史数据来预测活动、行为和趋势的高级分析形式。它涉及将统计分析技术、数据查询和机器学习算法应用于数据集。预测分析还涉及创建预测模型,以对特定操作或事件发生的可能性设置数值或评分。 预测分析寻找数据模式并预测未来趋势&…