我知道如果我想旋转矢量,则需要对四元数进行归一化.
但有没有任何理由不自动规范化四元数?如果有,那么四元数运算会导致非标准化四元数?
对不起,如果这个问题有点模糊.我还在尝试绕着四元数缠绕我.
四元数旋转只是一个带有X,Y,Z的矢量,物体将朝哪个方向旋转,还有一个滚动条可以将物体转动到它的轴上?
这么简单吗?
意思是如果X = 0,Z = 0且Y = 1,对象将面朝上?
如果你有Y = 0,Z = 0和X = 1,对象将面向右边?
(假设X右,Y向上和Z深度)
所以我正在编写一个程序,其中对象围绕着spaceim风格移动,以便学习如何在3D空间中平滑地移动物体.在稍微弄清楚欧拉角度之后,看起来它们并不适合任意方向的自由形式3D运动,所以我决定继续寻找最适合这项工作的东西 - 四元数.我打算让对象始终围绕其局部XYZ轴旋转,而不是围绕全局XYZ轴旋转.
我试图使用四元数实现旋转系统,但有些东西不起作用.沿单轴旋转物体时,如果没有进行先前的旋转,则物体沿给定轴旋转精细.但是,当执行一个接一个的旋转后,第二个旋转并不总是沿着它应该旋转的局部轴 - 例如,绕Z轴旋转约90°后,围绕Y轴旋转仍然发生在全局Y轴周围,而不是与全局X轴对齐的新的局部Y轴.
呵呵.让我们一步一步来看看.错误必须在某处.
第1步 - 捕获输入
我认为最好使用Euler角度(或Pitch-Yaw-Roll方案)来捕捉玩家输入.此时,箭头键控制俯仰和偏航,而Q和E控制滚动.我捕获了播放器输入(我正在使用SFML 1.6):
///SPEEDS
float ForwardSpeed = 0.05;
float TurnSpeed = 0.5;
//Rotation
sf::Vector3<float> Rotation;
Rotation.x = 0;
Rotation.y = 0;
Rotation.z = 0;
//PITCH
if (m_pApp->GetInput().IsKeyDown(sf::Key::Up) == true)
{
Rotation.x -= TurnSpeed;
}
if (m_pApp->GetInput().IsKeyDown(sf::Key::Down) == true)
{
Rotation.x += TurnSpeed;
}
//YAW
if (m_pApp->GetInput().IsKeyDown(sf::Key::Left) == true)
{
Rotation.y -= TurnSpeed;
}
if (m_pApp->GetInput().IsKeyDown(sf::Key::Right) == true)
{
Rotation.y += TurnSpeed;
}
//ROLL
if (m_pApp->GetInput().IsKeyDown(sf::Key::Q) == true)
{
Rotation.z -= TurnSpeed; …Run Code Online (Sandbox Code Playgroud) 我很难将设备运动(传感器融合)映射到SceneKit节点旋转.问题的前提如下,
我有球体,并且相机定位在球体内部,使得球体的几何中心和相机节点的中心重合.我想要实现的是当我围绕一个点物理旋转时,运动也需要准确地映射到相机上.
实施细节如下:
我有一个节点,一个球体作为几何,并且是一个子节点.我正在使用传感器融合来获得姿态四元数,然后将它们转换为欧拉角.代码是:
- (SCNVector3)eulerAnglesFromCMQuaternion:(CMQuaternion) {
GLKQuaternion gq1 = GLKQuaternionMakeWithAngleAndAxis(GLKMathDegreesToRadians(90), 1, 0, 0);
GLKQuaternion gq2 = GLKQuaternionMake(q.x, q.y, q.z, q.w);
GLKQuaternion qp = GLKQuaternionMultiply(gq1, gq2);
CMQuaternion rq = {.x = qp.x, .y = qp.y, .z = qp.z, .w = qp.w};
CGFloat roll = atan2(-rq.x*rq.z - rq.w*rq.y, .5 - rq.y*rq.y - rq.z*rq.z);
CGFloat pitch = asin(-2*(rq.y*rq.z + rq.w*rq.x));
CGFloat yaw = atan2(rq.x*rq.y - rq.w*rq.z, .5 - rq.x*rq.x - rq.z*rq.z);
return SCNVector3Make(roll, pitch, yaw);
}
Run Code Online (Sandbox Code Playgroud)
转换方程式来自 3D Math Primer for Graphics …
基本上,给定一个quaterion(qx,qy,qz,qw)...我怎样才能将它转换为OpenGL旋转矩阵?我也对哪个矩阵行是"向上","向右","向前"等感兴趣...我在矢量中需要四元数的相机旋转...
因此,我编写了一个面向新程序员的基于四元数的3D相机,因此它们非常容易集成并开始使用.
在我开发它时,首先我将用户输入作为欧拉角,然后根据该帧的输入生成一个四元数.然后,我将拍摄相机的四元数并将其乘以我们为输入生成的四元数,理论上应该简单地将输入旋转添加到相机旋转的当前状态,事情就会变得既肥胖又快乐.让我们称之为:积累四元数,因为我们只存储和添加四元数.
但是我注意到这个方法存在问题.我使用的越多,即使我只是在一个欧拉角上旋转,比如Yaw,在一些迭代中,它会开始流血到另一个,Pitch说.这很轻微,但相当不可接受.
所以我做了一些更多的研究,并发现一篇文章说明积累欧拉角更好,所以相机将它的当前旋转存储为欧拉角,并且输入只是每帧添加到它们.然后我从每个帧生成一个四元数,然后用它来生成我的旋转矩阵.这解决了旋转出血问题进入不正确的轴.
那么任何Stackoverflow成员都能对这个问题有所了解吗?这是一种正确的做事方式吗?
我有一个由四元数旋转的模型.我只能设置旋转,我不能添加或减去任何东西.我需要获取轴的值,然后为它添加一个角度(可能是度数或弧度?),然后再重新添加修改后的四元数.
我怎样才能做到这一点?(在每个轴上回答).
我正在尝试将Matrix3d旋转转换为a Quaternion<double>,但到目前为止我只得到了奇怪的编译器错误.我正在使用的代码是:
Quaternion<double> getQuaternionFromRotationMatrix(const Matrix3d& mat)
{
AngleAxisd aa;
aa = mat;
Quaternion<double> q = aa;// conversion error
return q;
}
Run Code Online (Sandbox Code Playgroud)
而编译错误:
path/src/Utils.cpp: In function ‘Eigen::Quaternion<double> Utils::getQuaternionFromRotationMatrix(const Matrix3d&)’:
path/src/Utils.cpp:55:26: error: conversion from ‘Eigen::AngleAxisd {aka Eigen::AngleAxis<double>}’ to non-scalar type ‘Eigen::Quaternion<double>’ requested
In file included from /usr/local/include/eigen3/Eigen/Core:283:0,
from /usr/local/include/eigen3/Eigen/Dense:1,
from path/include/Utils.h:4,
from path/src/Utils.cpp:1:
/usr/local/include/eigen3/Eigen/src/Core/Assign.h: In member function ‘Derived& Eigen::DenseBase<Derived>::lazyAssign(const Eigen::DenseBase<OtherDerived>&) [with OtherDerived = Eigen::Matrix<double, 3, 1>, Derived = Eigen::Block<Eigen::Matrix<double, 4, 4>, 4, -0x00000000000000001, true, true>]’:
/usr/local/include/eigen3/Eigen/src/Core/Assign.h:534:123: instantiated from ‘static …Run Code Online (Sandbox Code Playgroud) 我在WebGL中渲染一个简单的环面.旋转顶点工作正常,但我的法线有问题.当围绕单个轴旋转时,它们保持正确的方向,但是当围绕第二个轴的旋转增加时,法线开始以错误的方式向上旋转,直到其中一个旋转为180°,然后法线在完全相反的情况下旋转他们应该.我假设问题在于用于旋转的四元数,但我无法确定哪里出错了.
这是一个(略有修改,但它仍然显示问题)我的项目的jsfiddle:https://jsfiddle.net/dt509x8h/1/
在小提琴的html部分有一个包含来自obj的所有数据的div -file我正在阅读以生成圆环(尽管分辨率较低).
顶点着色器:
attribute vec4 aVertexPosition;
attribute vec3 aNormalDirection;
uniform mat4 uMVPMatrix;
uniform mat3 uNMatrix;
varying vec3 nrm;
void main(void) {
gl_Position = uMVPMatrix * aVertexPosition;
nrm = aNormalDirection * uNMatrix;
}
Run Code Online (Sandbox Code Playgroud)
片段着色器:
varying vec3 nrm;
void main(void) {
gl_FragColor = vec4(nrm, 1.0);
}
Run Code Online (Sandbox Code Playgroud)
更新矩阵(在输入时运行):
mat4.perspective(pMatrix, Math.PI*0.25, width/height, clipNear, clipFar); //This is actually not run on input, it is just here to show the creation of the perspective matrix
mat4.fromRotationTranslation(mvMatrix, rotation, position);
mat3.normalFromMat4(nMatrix, mvMatrix);
mat4.multiply(mvpMatrix, pMatrix, …Run Code Online (Sandbox Code Playgroud) 我想将对象从3ds max导出到我的C++/DirectX应用程序,我有方向导出问题.
3ds max使用右手Z-up坐标系,我的应用程序使用左手Y-up坐标系.我{x, y, z, w}在整个问题中使用了组件符号.
我在3ds max中有3个骨骼(或任何其他分层对象):
要导出它们的方向,我使用MaxScript:
if hasParent then
localOrientation = boneNode.transform.rotationPart * inverse boneNode.parent.transform.rotationPart
else
localOrientation = boneNode.transform.rotationPart
Run Code Online (Sandbox Code Playgroud)
我将此localOrientation保存到文件:
BoneRoot no_parent 0.707107 0.0 0.0 0.707107 //stands for (-90, 0, 0) Euler rotation in 3ds max UI
Bone001 BoneRoot 0.0 -0.382683 0.0 0.92388 //local orientation (parent space)
Bone002 Bone001 -0.353553 -0.612372 0.353553 -0.612372
Run Code Online (Sandbox Code Playgroud)
我已经读到尽管3ds max唱右手坐标系,它还是使用了左手系统transform.rotationPart.
我的问题是,如何将本地轮换从该文件转换为我的应用程序?也许我应该只对根骨骼应用一些转换?我尝试将其应用于每个骨骼方向:
Quaternion convertFrom3dsMax(const Quaternion …Run Code Online (Sandbox Code Playgroud) quaternions ×10
3d ×4
c++ ×3
matrix ×3
euler-angles ×2
math ×2
opengl ×2
3dsmax ×1
angle ×1
core-motion ×1
eigen ×1
geometry ×1
gl-matrix ×1
graphics ×1
java ×1
objective-c ×1
rotation ×1
scenekit ×1
sfml ×1
trigonometry ×1
webgl ×1