可能重复:
是否有将四元数旋转转换为欧拉角旋转的算法?
嘿伙计们,我一直在互联网上搜索,我找不到一种方法将四元数符号的旋转转换为欧拉角.有办法吗?谢谢.
我正在研究车辆控制并使用9DOF传感器(加速度计,磁力计和陀螺仪).对于偏航角,我在pi rad处有一个不连续性问题.(180度).我用PID控制器控制车辆,当车辆转过180度时,标志突然变化(从180变为-180),这使得控制器表现得很奇怪.当它转动超过-180度时也会出现同样的问题.
作为方法,我使用方向余弦矩阵来计算欧拉角.(sparkfun传感器的推荐方法.)
我的问题是我应该使用什么样的方法?在使用PID控制器控制偏航角的情况下如何处理这种不连续性.
我正在研究OpenGL中的一些简单的3D图形(java LWGJL),我正在试图弄清楚如何将偏航,俯仰和滚动转换为我的运动Vector的x,y和z分量.我知道如何通过俯仰和偏航来做到这一点(如这里所解释的),但是我没有找到任何解释如何将滚动整合到这个公式中.
我知道偏航和俯仰是在3d空间中定义矢量所需的全部,但我也需要在此实例中滚动.在基本的WASD配置中,我有相对于相机的不同动作的键(A本地左侧,W本地向前,SPACE本地向上),因此滚动会影响相机的移动方式(例如D,用一卷pi/2 按下(默认情况下)将摄像机向右移动(在世界坐标系中),但是D用一卷pi 按下可以将摄像机向上移动到世界坐标中)).
这是我到目前为止的代码:
//b = back
//f = forward
//r = right
//l = left
//u = up
//d = down
private void move()
{
double dX = 0, dY = 0, dZ = 0;
if (f ^ b)
{
dZ += cos(yaw) * cos(pitch) * (b ? 1 : -1);
dX += sin(yaw) * cos(pitch) * (b ? 1 : -1);
dY += -sin(pitch) …Run Code Online (Sandbox Code Playgroud) 我目前正致力于构建一个显示全景照片的查看器.我将图像放在CSS多维数据集的内部,并且正在研究如何使用javascript中的deviceorientation事件来控制它.
我发现并实现了一种算法,将原始数据从deviceorientation事件转换为euler角度,但我不确定如何使用CSS 3d旋转变换将这些数据挂钩以旋转立方体.
我的目标是能够让用户拿起手机并环顾全景,类似于那里的一些商业软件.
我正在考虑使用three.js来实现这一点,但是这个特定项目的库大小太大了.我们希望保持低开销.
这是我目前拥有的代码笔:
http://codepen.io/michaelsharpe/pen/wzpvD
任何帮助将不胜感激!谢谢!
UPDATE
我现在有一些基本功能.这是更新的代码:
http://codepen.io/michaelsharpe/pen/wFaeI
您需要关闭屏幕旋转,并且必须将手机倾斜到横向视图中.我现在的新问题是如何在手机处于纵向位置以及打开屏幕旋转时使整个工作完成.
我正在尝试实现一个功能,可以将欧拉角转换为四元数,然后使用Eigen返回"YXZ".稍后这应该用于让用户给你Euler角度并作为Quaternion旋转并为用户转换Back.事实上,我真的很擅长数学但是我尽力了.如果这个矩阵是正确的或任何东西,我不知道.代码可以工作,但我认为我的结果是关闭的.知道我哪里走错了吗?这就是我的Quat.cpp的样子:
#include "Quat.h"
#include <Eigen/Geometry>
#include <Eigen/Dense>
#include <cmath>
#include <iostream>
using namespace Eigen;
Vector3f Quat::MyRotation(const Vector3f YPR)
{
Matrix3f matYaw(3, 3), matRoll(3, 3), matPitch(3, 3), matRotation(3, 3);
const auto yaw = YPR[2]*M_PI / 180;
const auto pitch = YPR[0]*M_PI / 180;
const auto roll = YPR[1]*M_PI / 180;
matYaw << cos(yaw), sin(yaw), 0.0f,
-sin(yaw), cos(yaw), 0.0f, //z
0.0f, 0.0f, 1.0f;
matPitch << cos(pitch), 0.0f, -sin(pitch),
0.0f, 1.0f, 0.0f, // X
sin(pitch), 0.0f, cos(pitch);
matRoll << 1.0f, 0.0f, 0.0f,
0.0f, …Run Code Online (Sandbox Code Playgroud) 所以我在网上搜索,我在想象万向节锁如何发生时遇到了一些问题。根据我所看到的,当两个或多个轴对齐失去一定的自由度时就会发生这种情况,但我无法想象这些轴将如何开始对齐?
我的意思是,当我围绕 x 轴旋转对象时(例如),y 轴和 z 轴是否不会随 X 轴旋转以保持垂直?他们要如何对齐?同样,每当我绕 Y 或 Z 轴旋转时,其他 2 个轴会一起旋转并保持垂直,不是吗?
为了更清楚地了解我的想象问题,请观看此视频。5:05 https://youtu.be/Mm8tzzfy1Uw?t=305
您会看到,当他绕 X 轴旋转时,绿色和蓝色环保留在那里,根据我的想象,绿色 (Y) 和蓝色 (Z) 轴应该旋转。我不明白为什么环仍然与世界轴对齐?
我已经在互联网上搜索了几个小时,了解一些有关如何理解返回的欧拉角的文档cv2.decomposeProjectionMatrix。
我的问题看起来很简单,我有一张飞机的二维图像。
我希望能够从该图像中得出飞机相对于相机的方向。最终,我正在寻找外观和凹陷(即方位角和仰角)。我有与图像中选择的 2D 特征相对应的 3D 坐标 - 在我的代码中列出如下。
# --- Imports ---
import os
import cv2
import numpy as np
# --- Main ---
if __name__ == "__main__":
# Load image and resize
THIS_DIR = os.path.abspath(os.path.dirname(__file__))
im = cv2.imread(os.path.abspath(os.path.join(THIS_DIR, "raptor.jpg")))
im = cv2.resize(im, (im.shape[1]//2, im.shape[0]//2))
size = im.shape
# 2D image points
image_points = np.array([
(230, 410), # Nose
(55, 215), # right forward wingtip
(227, 170), # right aft outboard horizontal
(257, …Run Code Online (Sandbox Code Playgroud) 我使用 EigeneulerAngles从旋转矩阵中获取滚动角、俯仰角和偏航角,如下所示:
const Eigen::Vector3f yaw_pitch_roll = rotation.eulerAngles(2, 1, 0);
其中rotation是 类型的一些有效旋转矩阵Eigen::Matrix3f。
我观察到的是:如果所有三个角度都接近于零,即如果旋转矩阵接近恒等式,则某些或所有三个所得角度有时会偏离 Pi,即 180 度。
这也可能发生在某些其他旋转中,但到目前为止我只观察到它接近恒等式。
因为这是一个复杂的问题,通常会导致很多混乱(我之前已经问过这个问题的变体,但从来没有以正确的方式提出这个问题,也没有得到答案),我将尽量把它说清楚可能的。
事实:
我正在尝试做的事情:
我正在尝试在人形骨骼结构上播放动画,并使用扭矩(旋转力)将物理布娃娃推入与骨骼结构大致相同的姿势。
问题:
我可以在四元数中完全工作,直到需要将扭矩应用于刚体。该AddTorque 函数在欧拉角中有效工作,这意味着我不能使用四元数。我可以轻松地从四元数中提取欧拉角,但它们不可靠并且会导致布娃娃严重变形。
我需要的:
我需要从 Forward、Up 和 Right 向量计算可靠的 3D Euler 角(例如,那些不会从 + 翻转到 - “随机”)。我意识到这有点复杂,但这就是我在这里问的原因:我缺乏自己解决这个问题的知识和经验。
鉴于矢量本身是可靠的,我认为没有理由不能从它们计算出可靠的欧拉角。另外,我不知道我想要或需要欧拉角的旋转顺序,但我相信以后修改会很容易。
任何帮助将非常感激!
我正在处理动作捕捉数据,我想在处理中进行“蒙皮”。因此,基本上,我从数据中获得的每两个点都必须在其间添加一个 3D 对象(我现在将使用一个盒子,放置和旋转坐标是 3D 对象的中心)并旋转它,以便它在所有三个维度上与连接两点的向量对齐。
在这里,我们可以在左侧看到两点之间最初放置的框,在右侧看到现在正确旋转的框:

我知道在处理中旋转对象的唯一方法是使用rotateX()、rotateY()、rotateZ()函数,它们使用欧拉角围绕全局(?)轴旋转对象。
现在我正在努力寻找一种正确计算这种旋转的方法。
我已经编写了一个用于计算两个向量之间的角度的函数:
float calcVectorAngle(PVector p1, PVector p2) {
return acos((p1.dot(p2)) / (mag(p1.x, p1.y, p1.z) * mag(p2.x, p2.y, p2.z)));
}
Run Code Online (Sandbox Code Playgroud)
然后我尝试将向量(两点之间)与每个旋转轴之一的单位向量结合起来:
float x = calcVectorAngle(vector, new PVector(1,0,0));
float y = calcVectorAngle(vector, new PVector(0,1,0));
float z = calcVectorAngle(vector, new PVector(0,0,1));
Run Code Online (Sandbox Code Playgroud)
但是当我使用这些值旋转对象时,旋转完全关闭。
代码示例:
PVector p1;
PVector p2;
PVector boxSize = new PVector(500, 100, 100);
void setup() {
size(1000,1000,P3D);
p1 = new PVector(100, 100, 0);
p2 = new PVector(900, 900, -1000);
}
void draw() {
background(125);
strokeWeight(2); …Run Code Online (Sandbox Code Playgroud)