四元数(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 = -k

jk = 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.2k

A = [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         0
         0    0.8660    0.5000
         0   -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.mfbz.cn/a/442203.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

2024届 C++ 刷题 笔试强训 Day 01

选择题 01 以下for循环的执行次数是&#xff08;&#xff09; for(int x 0, y 0; (y 123) && (x < 4); x); A 是无限循环 B 循环次数不定 C 4次 D 3次 解题思路&#xff1a; 我们直接来看本道题中最关键的部分&#xff1a;(y 123) && (x < 4)。 (y…

OpenTenBase 开发环境搭建及Debug设置

最近有个 OpenTenBase开源核心贡献挑战赛 领导建议大家都去试试&#xff0c;我也去凑了下热闹&#xff0c;发现能力有限一时半会是搞不明白了&#xff0c;最多也就是能搞搞文档翻译&#xff0c;或者写点操作手册啥的。 不过不管怎么样&#xff0c;先把开发环境搭上&#xff0c;…

STM32day3

1.思维导图 1.总结任务的调度算法&#xff0c;把实现代码再写一下 /* Definitions for myTask02 */ osThreadId_t myTask02Handle; uint32_t myTask02Buffer[ 64 ]; osStaticThreadDef_t myTask02ControlBlock; const osThreadAttr_t myTask02_attributes {.name "myTa…

严刑拷打_微服务

文章详情 &#xff1a;&#x1f60a; 作者&#xff1a;Lion J &#x1f496; 主页&#xff1a; https://blog.csdn.net/weixin_69252724 &#x1f389; 主题&#xff1a; 微服务相关知识 ⏱️ 创作时间&#xff1a;2024年03月8日 ———————————————— 文章目…

webpack5:基本概念整理

写在前头&#xff1a;这篇文章只是我个人在学习过程中对webpack文档的简单总结&#xff0c;更多详细信息请在官网阅读。 一、webpack是什么 webpack 是一个用于现代 JavaScript 应用程序的静态模块打包工具。当 webpack 处理应用程序时&#xff0c;它会在内部从一个或多个入口…

掌握MySQL,看完这篇文章就够了!

1. MySQL MySQL是一种广泛使用的关系型数据库管理系统&#xff08;RDBMS&#xff09;&#xff0c;由瑞典的MySQL AB公司开发&#xff0c;目前属于甲骨文公司&#xff08;Oracle Corporation&#xff09;。 MySQL使用结构化查询语言&#xff08;SQL&#xff09;进行数据库管理…

C语言指针——常量字符串和 变量字符串

常量字符串和 变量字符串 常量字符串和变量字符串是在编程中常见的两种字符串类型&#xff0c;它们有以下区别&#xff1a; 值的不可变性&#xff1a;常量字符串的值是不可变的&#xff0c;一旦被定义&#xff0c;就不能修改。而变量字符串的值是可变的&#xff0c;可以随时修…

Redis进阶(三):主从复制

为了解决单点问题&#xff0c;实现多服务器部署redis&#xff0c;有几种解决方案可以实现&#xff1a;主从复制&#xff0c;主从哨兵还有集群。 何为主从复制 简单来说有三个服务器分别部署了redis-server程序&#xff0c;选中一个服务器当作主节点&#xff0c;其他的就是从节…

【PCL】(二十六)自定义条件的欧几里得聚类分割点云

&#xff08;二十六&#xff09;自定义条件的欧几里得聚类分割点云 以下代码实现自定义条件对点进行欧几里得聚类分割。 conditional_euclidean_clustering.cpp #include <pcl/point_types.h> #include <pcl/io/pcd_io.h> #include <pcl/console/time.h>#…

Android Studio编译及调试知识

文章目录 Android Studio编译kotlin项目Android Studio编译Java和kotlin混合项目的过程gradle打印详细错误信息&#xff0c;类似这种工具的使用Android apk 从你的代码到APK打包的过程&#xff0c;APK安装到你的Android手机上的过程&#xff0c;最后安装好的形态&#xff0c;以…

Mint_21.3 drawing-area和goocanvas的FB笔记(五)

FreeBASIC SDL图形功能 SDL - Simple DirectMedia Layer 是完整的跨平台系统&#xff0c;有自己的窗口、直接捕获键盘、鼠标和游戏操纵杆的事件&#xff0c;直接操作音频和CDROM&#xff0c;在其surface上可使用gfx, openGL和direct3D绘图。Window3.0时代&#xff0c;各种应用…

准谐振PWM控制器-能够实现多种保护功能FAN6921MRMY 功率因数控制器

高度集成的FAN6921MRMY将功率因数控制器 (PFC) 和准谐振 PWM 控制器相结合。集成提供了成本高效的设计&#xff0c;可减少外部组件数量。对于 PFC&#xff0c;FAN6921MRMY使用控制导通时间技术提供调节的直流输出电压&#xff0c;执行自然的功率因数校正。FAN6921MRMY使用创新的…

【代码随想录算法训练营Day40】01背包问题一维dp数组;二维dp数组(滚动数组);416.分割等和子集

文章目录 ❇️Day 41 第九章 动态规划 part04✴️今日任务❇️01背包问题 二维背包问题的区别暴力解法动规五部曲 ❇️01背包问题 一维二维转一维&#xff1a;滚动数组动规五部曲 ❇️416. 分割等和子集随想录思路自己的思路二维方法一维方法 自己的代码二维方法一维方法 ❇️D…

Kibana二次开发环境搭建

1 kibana环境搭建 1.1 搭建后端服务 &#xff08;1&#xff09;java环境安装 ElasticSearch运行需要java jdk支持。所以要先安装JAVA环境。由于ElasticSearch 5.x 往后依赖于JDK 1.8的&#xff0c;所以现在我们下载JDK 1.8或者更高版本。下载JDK1.8,下载完成后安装&#xff…

去电脑维修店修电脑需要注意什么呢?装机之家晓龙

每当电脑出现故障时&#xff0c;你无疑会感到非常沮丧。 如果计算机已过了保修期&#xff0c;您将无法享受制造商的免费保修服务。 这意味着您必须自费找到一家电脑维修店。 去电脑维修店并不容易。 大家一定要知道&#xff0c;电脑维修非常困难&#xff0c;尤其是笔记本电脑维…

qtCreator可以全局包含。VSqt中千万不能全局包含,你的控件头文件会自己变成<>括号,编译就报错

qtCreator可以全局包含。 VSqt中千万不能全局包含&#xff0c;你的控件头文件会自己变成&#xff1c;&#xff1e;括号&#xff0c;编译就报错

重建大师6.2版本的建模效果出现下图中模糊的情况,是什么原因?

可能是因为坐标原点设置的不对&#xff0c;图例中的三角网都出现了精度损失的问题。 坐标原点设置的具体操作&#xff1a;提交产品后&#xff0c;在弹出的界面&#xff0c;可以设定坐标原点。 重建大师是一款专为超大规模实景三维数据生产而设计的集群并行处理软件&#xff0…

第七届强网杯-PWN-【warmup】

文章目录 warmup libc 2.35检查IDA逆向maindeldelete_noteadd_noteshow_noteinput_numberread_16atoi __errno_location()相关解释prctl相关 思路高版本off by null利用技巧产生chunk extend泄露libc基地址泄露heap基地址修改放入tcachebin中的chunk的fd为stdout最后add两个chu…

AI大模型助力创意思维,拓展无限可能性

在当今快速发展的科技时代&#xff0c;人工智能大模型正逐渐成为我们生活中不可或缺的一部分。它们拥有强大的计算能力和学习能力&#xff0c;能够帮助我们解决许多复杂的问题&#xff0c;同时也可以为创意思维的拓展提供无限可能性。 人工智能大模型可以通过对海量数据的分析…

docker部署springboot jar包项目

docker部署springboot jar包项目 前提&#xff0c;服务器环境是docker环境&#xff0c;如果服务器没有安装docker&#xff0c;可以先安装docker环境。 各个环境安装docker&#xff1a; Ubuntu上安装Docker&#xff1a; ubuntu离线安装docker: CentOS7离线安装Docker&#xff1…
最新文章