矩阵Matrix到欧拉角Euler转换

2024-03-14 23:48

本文主要是介绍矩阵Matrix到欧拉角Euler转换,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

参考文献:

http://www.geometrictools.com/Documentation/EulerAngles.pdf

但是这里的公式不能直接用,原因是左右手系空间不同,我这边采用Direct3D默认的右手系,参考:

https://docs.microsoft.com/en-us/windows/win32/direct3d9/d3dxmatrixrotationyawpitchroll

所以需要自行推导右手系公式,已知各个轴旋转矩阵公式:

R(\theta_{x})=\begin{bmatrix} 1 & 0 & 0\\ 0 & cos(\theta_{x}) & sin(\theta_{x})\\ 0 & -sin(\theta_{x}) & cos(\theta_{x}) \end{bmatrix}R(\theta_{y})=\begin{bmatrix} cos(\theta_{y}) & 0 & -sin(\theta_{y})\\ 0 & 1 & 0\\ sin(\theta_{y}) & 0 & cos(\theta_{y}) \end{bmatrix}R(\theta_{z})=\begin{bmatrix} cos(\theta_{z}) & sin(\theta_{z}) & 0\\ -sin(\theta_{z}) & cos(\theta_{z}) & 0\\ 0 & 0 & 1 \end{bmatrix}

欧拉角变换顺序为YXZ,则先计算YX矩阵

R(\theta_{y})\cdot R(\theta_{x})=\begin{bmatrix} cos(\theta_{y}) & sin(\theta_{y})\cdot sin(\theta_{x}) & -sin(\theta_{y})\cdot cos(\theta_{x})\\ 0 & cos(\theta_{x}) & sin(\theta_{x})\\ sin(\theta_{y}) & -cos(\theta_{y})\cdot sin(\theta_{x}) & cos(\theta_{y})\cdot cos(\theta_{x}) \end{bmatrix}

最终YXZ矩阵

R(\theta_{y})\cdot R(\theta_{x})\cdot R(\theta_{z})=\begin{bmatrix} cos(\theta_{y})\cdot cos(\theta_{z})-sin(\theta_{y})\cdot sin(\theta_{x})\cdot sin(\theta_{z}) & cos(\theta_{y})\cdot sin(\theta_{z})+sin(\theta_{y})\cdot sin(\theta_{x})\cdot cos(\theta_{z}) & -sin(\theta_{y})\cdot cos(\theta_{x}))\\ -cos(\theta_{x})\cdot sin(\theta_{z}) & cos(\theta_{x})\cdot cos(\theta_{z}) & sin(\theta_{x})\\ sin(\theta_{y})\cdot cos(\theta_{z})+cos(\theta_{y})\cdot sin(\theta_{x})\cdot sin(\theta_{z}) & sin(\theta_{y})\cdot sin(\theta_{z})-cos(\theta_{y})\cdot sin(\theta_{x})\cdot cos(\theta_{z}) & cos(\theta_{y})\cdot cos(\theta_{x})) \end{bmatrix}

可以直接得知 sin(\theta_{x})=r12,即 \theta_{x}=arcsin(r12),然后需要分三种情况

  1. \theta_{x}\in \left (-\frac{\pi }{2}, \frac{\pi }{2}\right ),可知tan(\theta_{y})=\frac {sin(\theta_{y})\cdot cos(\theta_{x})}{cos(\theta_{y})\cdot cos(\theta_{x})},即 \theta_{y}=arctan(\frac {-r02} {r22}),同理 \theta_{z}=arctan(\frac {-r10} {r11})
  2. 当 \theta_{x}=\frac{\pi}{2},则 sin(\theta_{x})=1,YXZ矩阵可简化为
    R(\theta_{yxz})=\begin{bmatrix} cos(\theta_{y})\cdot cos(\theta_{z})-sin(\theta_{y})\cdot sin(\theta_{z}) & cos(\theta_{y})\cdot sin(\theta_{z})+sin(\theta_{y})\cdot cos(\theta_{z}) & 0\\ 0 & 0 & 1\\ sin(\theta_{y})\cdot cos(\theta_{z})+cos(\theta_{y})\cdot sin(\theta_{z}) & sin(\theta_{y})\cdot sin(\theta_{z})-cos(\theta_{y})\cdot cos(\theta_{z}) & 0 \end{bmatrix}
    根据两角和公式,可得
    R(\theta_{yxz})=\begin{bmatrix} cos(\theta_{y}+\theta_{z}) & sin(\theta_{y}+\theta_{z}) & 0\\ 0 & 0 & 1\\ sin(\theta_{y}+\theta_{z}) & -cos(\theta_{y}+\theta_{z}) & 0 \end{bmatrix},即 \theta_{y}+\theta_{z}=arctan(\frac {r01}{r00}),且结果不唯一
  3. 当 \theta_{x}=-\frac {\pi}{2},则 sin(\theta_{x})=-1,YXZ矩阵简化为
    R(\theta_{yxz})=\begin{bmatrix} cos(\theta_{y})\cdot cos(\theta_{z})+sin(\theta_{y})\cdot sin(\theta_{z}) & cos(\theta_{y})\cdot sin(\theta_{z})-sin(\theta_{y})\cdot cos(\theta_{z}) & 0\\ 0 & 0 & -1\\ sin(\theta_{y})\cdot cos(\theta_{z})-cos(\theta_{y})\cdot sin(\theta_{z}) & sin(\theta_{y})\cdot sin(\theta_{z})+cos(\theta_{y})\cdot cos(\theta_{z}) & 0 \end{bmatrix}
    可得
    R(\theta_{yxz})=\begin{bmatrix} cos(\theta_{y}-\theta_{z}) & -sin(\theta_{y}-\theta_{z}) & 0\\ 0 & 0 & -1\\ sin(\theta_{y}-\theta_{z}) & cos(\theta_{y}-\theta_{z}) & 0 \end{bmatrix},即 \theta_{y}-\theta_{z}=arctan(\frac {-r01}{r00})

基于以上思路,就能实现D3DXMATRIX到欧拉角的转换代码

D3DXVECTOR3* D3DXMatrixToEulerAngles(D3DXVECTOR3* pOut, const D3DXMATRIX* pM)
{if (pM->_23 < 0.999f) // some fudge for imprecision{if (pM->_23 > -0.999f) // some fudge for imprecision{pOut->x = asin(pM->_23);pOut->y = atan2(-pM->_13, pM->_33);pOut->z = atan2(-pM->_21, pM->_22);}else{// WARNING.  Not unique.  YA - ZA = atan2(-r01,r00)pOut->x = -D3DX_PI * 0.5f;pOut->y = atan2(-pM->_12, pM->_11);pOut->z = 0.0f;}}else{// WARNING.  Not unique.  YA + ZA = atan2(r01,r00)pOut->x = D3DX_PI * 0.5f;pOut->y = atan2(pM->_12, pM->_11);pOut->z = 0.0f;}return pOut;
}

 

这篇关于矩阵Matrix到欧拉角Euler转换的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



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

相关文章

hdu 4565 推倒公式+矩阵快速幂

题意 求下式的值: Sn=⌈ (a+b√)n⌉%m S_n = \lceil\ (a + \sqrt{b}) ^ n \rceil\% m 其中: 0<a,m<215 0< a, m < 2^{15} 0<b,n<231 0 < b, n < 2^{31} (a−1)2<b<a2 (a-1)^2< b < a^2 解析 令: An=(a+b√)n A_n = (a +

hdu 6198 dfs枚举找规律+矩阵乘法

number number number Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Problem Description We define a sequence  F : ⋅   F0=0,F1=1 ; ⋅   Fn=Fn

PDF 软件如何帮助您编辑、转换和保护文件。

如何找到最好的 PDF 编辑器。 无论您是在为您的企业寻找更高效的 PDF 解决方案,还是尝试组织和编辑主文档,PDF 编辑器都可以在一个地方提供您需要的所有工具。市面上有很多 PDF 编辑器 — 在决定哪个最适合您时,请考虑这些因素。 1. 确定您的 PDF 文档软件需求。 不同的 PDF 文档软件程序可以具有不同的功能,因此在决定哪个是最适合您的 PDF 软件之前,请花点时间评估您的

C# double[] 和Matlab数组MWArray[]转换

C# double[] 转换成MWArray[], 直接赋值就行             MWNumericArray[] ma = new MWNumericArray[4];             double[] dT = new double[] { 0 };             double[] dT1 = new double[] { 0,2 };

[论文笔记]LLM.int8(): 8-bit Matrix Multiplication for Transformers at Scale

引言 今天带来第一篇量化论文LLM.int8(): 8-bit Matrix Multiplication for Transformers at Scale笔记。 为了简单,下文中以翻译的口吻记录,比如替换"作者"为"我们"。 大语言模型已被广泛采用,但推理时需要大量的GPU内存。我们开发了一种Int8矩阵乘法的过程,用于Transformer中的前馈和注意力投影层,这可以将推理所需

数据流与Bitmap之间相互转换

把获得的数据流转换成一副图片(Bitmap) 其原理就是把获得倒的数据流序列化到内存中,然后经过加工,在把数据从内存中反序列化出来就行了。 难点就是在如何实现加工。因为Bitmap有一个专有的格式,我们常称这个格式为数据头。加工的过程就是要把这个数据头与我们之前获得的数据流合并起来。(也就是要把这个头加入到我们之前获得的数据流的前面)      那么这个头是

线性代数|机器学习-P35距离矩阵和普鲁克问题

文章目录 1. 距离矩阵2. 正交普鲁克问题3. 实例说明 1. 距离矩阵 假设有三个点 x 1 , x 2 , x 3 x_1,x_2,x_3 x1​,x2​,x3​,三个点距离如下: ∣ ∣ x 1 − x 2 ∣ ∣ 2 = 1 , ∣ ∣ x 2 − x 3 ∣ ∣ 2 = 1 , ∣ ∣ x 1 − x 3 ∣ ∣ 2 = 6 \begin{equation} ||x

高斯平面直角坐标讲解,以及地理坐标转换高斯平面直角坐标

高斯平面直角坐标系(Gauss-Krüger 坐标系)是基于 高斯-克吕格投影 的一种常见的平面坐标系统,主要用于地理信息系统 (GIS)、测绘和工程等领域。该坐标系将地球表面的经纬度(地理坐标)通过一种投影方式转换为平面直角坐标,以便在二维平面中进行距离、面积和角度的计算。 一 投影原理 高斯平面直角坐标系使用的是 高斯-克吕格投影(Gauss-Krüger Projection),这是 横

【线性代数】正定矩阵,二次型函数

本文主要介绍正定矩阵,二次型函数,及其相关的解析证明过程和各个过程的可视化几何解释(深蓝色字体)。 非常喜欢清华大学张颢老师说过的一段话:如果你不能用可视化的方式看到事情的结果,那么你就很难对这个事情有认知,认知就是直觉,解析的东西可以让你理解,但未必能让你形成直觉,因为他太反直觉了。 正定矩阵 定义 给定一个大小为 n×n 的实对称矩阵 A ,若对于任意长度为 n 的非零向量 ,有 恒成

VC环境下整型转换为字符串型(2)

在串口下位机的发送中,可能会用到需要发送数字,显示为字符串型的 和上一篇文字《串口中字符串转换为整型》一正一反,知识点学习会了: #include<iostream.h> #include <stdio.h> #include <string.h>   void inttostr(int m,unsigned char * str) { int length=0;   int tmp,te