四元数适用于它们之间的插值旋转.到现在为止还挺好.
如果我有一个网络游戏,将旋转转移为vector3f还是应该使用四元数?为了使游戏更流畅,我可能需要在最后发送的旋转和当前旋转之间进行插值.
但是我可以在从Yaw/Pitch/Roll创建的两个四元数之间插入旋转吗?
Quaternion a = Quaternion.FromYawPitchRoll(x1,y1,z1);
Quaternion b = Quaternion.FromYawPitchRoll(x2,y2,z2);
a.Interpolate(b, value); // will this work correctly?
Run Code Online (Sandbox Code Playgroud) 新手stackoverflow参与者,新手3D程序员,远离数学wiz ...所以我会尝试尽可能清楚地构建这个问题,希望它有意义,并希望得到一个不是一英里的答案.
我使用three.js编写了一个非常酷的应用程序,让用户可以飞过3D空间并探索太阳系.飞行模型松散地基于three.js包中的Fly.Controller示例/扩展,它教会我使用四元数来保持所有轴旋转相对于彼此合理.飞行部分都很棒.
这是我的困境:当使用四元数时,我如何推断出"正常"(我不知道还有什么称之为)旋转值来确定我面临的方向?使用四元数时,相机对象内的"旋转"结构保持为0,0,0.因此,虽然我可以在任何角度自由地飞越太空,但我无法弄清楚如何确定我实际面对的方向.是否有内置的three.js功能,或其他简单的方法来转换它?
我在网上发现了一些类似的,令人困惑的指针,但我无法解读并在三个.js中使用.谢谢.
我读了一些关于使用SSE内在函数的内容,并尝试了用双精度实现四元数旋转的运气.以下是我写的正常和SSE函数,
void quat_rot(quat_t a, REAL* restrict b){
///////////////////////////////////////////
// Multiply vector b by quaternion a //
///////////////////////////////////////////
REAL cross_temp[3],result[3];
cross_temp[0]=a.el[2]*b[2]-a.el[3]*b[1]+a.el[0]*b[0];
cross_temp[1]=a.el[3]*b[0]-a.el[1]*b[2]+a.el[0]*b[1];
cross_temp[2]=a.el[1]*b[1]-a.el[2]*b[0]+a.el[0]*b[2];
result[0]=b[0]+2.0*(a.el[2]*cross_temp[2]-a.el[3]*cross_temp[1]);
result[1]=b[1]+2.0*(a.el[3]*cross_temp[0]-a.el[1]*cross_temp[2]);
result[2]=b[2]+2.0*(a.el[1]*cross_temp[1]-a.el[2]*cross_temp[0]);
b[0]=result[0];
b[1]=result[1];
b[2]=result[2];
}
有了SSE
inline void cross_p(__m128d *a, __m128d *b, __m128d *c){
const __m128d SIGN_NP = _mm_set_pd(0.0, -0.0);
__m128d l1 = _mm_mul_pd( _mm_unpacklo_pd(a[1], a[1]), b[0] );
__m128d l2 = _mm_mul_pd( _mm_unpacklo_pd(b[1], b[1]), a[0] );
__m128d m1 = _mm_sub_pd(l1, l2);
m1 = _mm_shuffle_pd(m1, m1, 1);
m1 = _mm_xor_pd(m1, SIGN_NP);
l1 = _mm_mul_pd( a[0], _mm_shuffle_pd(b[0], b[0], …Run Code Online (Sandbox Code Playgroud) 我正在使用glm创建一个相机类,我遇到了一些lookat函数的问题.我使用四元数来表示旋转,但我想使用glm的预先编写的lookat函数来避免重复代码.这是我现在的lookat功能:
void Camera::LookAt(float x, float y, float z) {
glm::mat4 lookMat = glm::lookAt(position, glm::vec3(x, y, z), glm::vec3(0, 1, 0));
rotation = glm::toQuat(lookMat);
}
Run Code Online (Sandbox Code Playgroud)
但是,当我打电话时LookAt(0.0f,0.0f,0.0f),我的相机没有旋转到那一点.当我glm::eulerangles(rotation)在lookat 调用之后调用时,我得到一个具有以下值的vec3:(180.0f,0.0f,180.0f).position是(0.0f,0.0f,-10.0f),所以我根本不应该有任何旋转来看0,0,0.这是构建视图矩阵的函数:
glm::mat4 Camera::GetView() {
view = glm::toMat4(rotation) * glm::translate(glm::mat4(), position);
return view;
}
Run Code Online (Sandbox Code Playgroud)
为什么我没有得到正确的四元数,如何修复我的代码?
受crytek关于使用四元数在四元数中为较小顶点存储切线空间的介绍的启发,我得出了一个合乎逻辑的结论:如果可以使用四元数来存储切线空间,那么您还可以在顶点之间触发四元数并使用它们直接旋转法线.这将消除重新正交化切线空间矢量或重建其中一个的需要,并且它将切出每个片段的矩阵 - 矢量乘法,用单个四元数向量乘法替换它.
我试图在我的OpenGL应用程序中使用我自制的四元数类实现它,我遇到了一些问题.我知道我的四元数可以用矩阵构造,将四元数乘以向量,得到与矩阵乘以向量相同的结果 - 我已经在cpu方面成功完成了.然而,一旦我开始在GLSL中使用它们,一切都会变得混乱.
值得注意的是,事实上我可以辨别出法线贴图的模式,所以我觉得我走在了正确的轨道上.不幸的是,似乎我的颜色变得混乱.
这是我在glsl中使用的四元数数学:
vec4 multQuat(vec4 q1, vec4 q2)
{
return vec4(
(q1.w * q2.y) + (q1.y * q2.w) + (q1.x * q2.z) - (q1.z * q2.x),
(q1.w * q2.z) + (q1.z * q2.w) + (q1.y * q2.x) - (q1.x * q2.y),
(q1.w * q2.w) - (q1.x * q2.x) - (q1.y * q2.y) - (q1.z * q2.z),
(q1.w * q2.x) + (q1.x * q2.w) + (q1.z * q2.y) - (q1.y * q2.z)
);
}
vec3 rotateVector(vec4 …Run Code Online (Sandbox Code Playgroud) 我正在学习单位四元数以及如何使用它们来表示和组合旋转.维基百科称它们在数值上比矩阵表示更稳定,但没有给出参考.任何人都可以向我解释(最好用一些数学推理)为什么使用单位四元数来处理旋转(例如对于OpenGL应用程序而不是旋转矩阵)在数值上更稳定?是因为避免了万向节锁?
math rotation quaternions rotational-matrices numerical-stability
我有一个初始四元数,q0.我得到了角速度测量,我整合了速度,所以我得到了50Hz左右的3个角度.如何根据3个角度制作四元数?我不能只做3个四元数,是吗?
所以说清楚.
Q.new = Q.new*Q.update(-α,β,γ)
Q.new表示我在四元数中的当前方向,我想通过乘以Q.update四元数来更新它.如何用角度制作Q.update?
谢谢!
我有以下问题:来自运动捕捉装置的四元数(q1)需要通过由第二个被跟踪物体导出的另一个方向四元数(q2)的偏航角(并且仅偏航!)进行校正,以便俯仰和滚动q1与之前相同,但q1具有q2的偏航.
工作解决方案是将quat转换为矩阵,然后我进行计算以提取旋转角度,然后进行航向修正.但是这直接在某个轴的方向上(例如在0°-359°之后)导致"翻转".还尝试了其他不方便的转换.
是否有可能直接在四元数上进行数学运算而不转换为矩阵或欧拉角(即我可以将校正后的四元数设置为被跟踪对象的四元数)?
如上所述 - 校正应该仅包括围绕上轴的旋转(偏航).我对数学课程的编程可能性不多(不幸的是,Virtools的VSL Script在这个方向上非常有限).有人有什么建议吗?
我希望在我的游戏中将我的汽车向左旋转90度.
当我使用这段代码时:
glm::quat rot(info.Rotation.w,info.Rotation.x,info.Rotation.y,info.Rotation.z);
glm::quat done(glm::rotate(rot,glm::eulerAngles(rot)+glm::vec3(90.0f,0.0,0.0)));
info.Rotation.x = done.x;
info.Rotation.y = done.y;
info.Rotation.z = done.z;
info.Rotation.w = done.w;
Run Code Online (Sandbox Code Playgroud)
汽车得到一个奇怪的旋转.
但是,以下代码根本不会改变汽车的旋转(正如我所期望的那样,只是为了确保GLM与游戏中的quats兼容):
glm::quat rot(info.Rotation.w,info.Rotation.x,info.Rotation.y,info.Rotation.z);
glm::quat done(rot);
info.Rotation.x = done.x;
info.Rotation.y = done.y;
info.Rotation.z = done.z;
info.Rotation.w = done.w;
Run Code Online (Sandbox Code Playgroud)
每当我尝试检查旋转是否随之改变时:
glm::quat rot(info.Rotation.w,info.Rotation.x,info.Rotation.y,info.Rotation.z);
glm::quat done(glm::rotate(rot,vec3(0.0,0.0,0.0)));
info.Rotation.x = done.x;
info.Rotation.y = done.y;
info.Rotation.z = done.z;
info.Rotation.w = done.w;
Run Code Online (Sandbox Code Playgroud)
汽车轮换仅设置为游戏中的0,0,0,0轮换.我希望这个代码保持旋转不受影响,因为我期望以下代码将汽车向左旋转90度:
glm::quat rot(info.Rotation.w,info.Rotation.x,info.Rotation.y,info.Rotation.z);
glm::quat done(glm::rotate(rot,vec3(90.0,0.0,0.0)));
info.Rotation.x = done.x;
info.Rotation.y = done.y;
info.Rotation.z = done.z;
info.Rotation.w = done.w;
Run Code Online (Sandbox Code Playgroud)
但这不符合我的要求.它只是设置旋转,而不是将其添加到'rot'.
我究竟做错了什么?
我有两个具有已知单位向量的笛卡尔坐标系:
系统A(x_A,y_A,z_A)
和
系统B(x_B,y_B,z_B)
两个系统共享相同的原点(0,0,0).我正在尝试计算四元数,以便系统B中的向量可以在系统A中表示.
我熟悉四元数的数学概念.我已经从这里实现了所需的数学:http://content.gpwiki.org/index.php/OpenGL%3aTutorials%3aUsing_Quaternions_to_represent_rotation
一种可能的解决方案是计算欧拉角并将其用于3个四元数.将它们相乘将导致最后一个,以便我可以转换我的向量:
v(A)= q*v(B)*q_conj
但是,这将再次纳入万向锁,这是不使用欧拉在开始角度的原因.
任何idead如何解决这个问题?