我有一个四元数,基于一个坐标系,其中Y轴向上,X轴在右边,Z轴朝我看。
现在,我想基于这个四元数在另一个应用程序(C++)中移动一个字符。如果坐标系统是相同的,这就没有问题了,但是这个应用程序使用的是不同的坐标系。Z在上面,X在右边,Y通过显示器(向内)。
我试着简单地旋转四元数来调整坐标系,但是每次旋转,它看起来都不太正确。
我的想法是,我需要某种基变换,但我不知道如何用四元数来实现这一点,有人知道如何在四元数上执行基转换吗?
编辑
我使用特征C++库来表示四元数。以下是我使用的四元数:
Quaternion<float> QX90( Eigen::AngleAxisf( M_PI /2.0, Eigen::Vector3f::UnitX() ) );
Quaternion<float> nQX90( Eigen::AngleAxisf( -M_PI /2.0, Eigen::Vector3f::UnitX() ) );
Quaternion<float> Qrshoulder = .... //the Quaternion in the Y up coordinate system我试着旋转X轴:
Qrshoulder=Qrshoulder*QX90;
Qrshoulder=QX90*Qrshoulder;
Qrshoulder=Qrshoulder*nQX90;
Qrshoulder=nQX90*Qrshoulder;这不管用。我还尝试了其他几个乘法,我几乎尝试了每一个似乎合乎逻辑的旋转。我是confused..it,这似乎是四元数乘法做不到的
编辑2
我有绝对和等级等级的四元数。分层四元数提供了从父骨到child..the的三维空间中的旋转量,绝对四元数是乘以层次的骨方向。
另一方面,我想要动画的角色背后有一个引擎,这个引擎已经使骨骼倍增,所以我肯定需要使用分级旋转。但问题是,当我使用分层旋转时,Y轴总是位于骨的方向上。
我从诺尔诺奇的回答中得到的答案是:
Quaternion<float> QNX( Eigen::AngleAxisf( 0, Eigen::Vector3f(1,0,0) ) );
rot=(QNX*QX90*Qrshoulder).toRotationMatrix();
targetNode->setRotation( Eigen::Transform3f( rot ) );这既不适用于等级制度,也不适用于绝对方向。下面这篇文章描述了我得到的四元数:http://msdn.microsoft.com/en-us/library/hh973073.aspx
我想我错过的是,当我使用层次化的方向时,我得到了我所需要的正确的旋转量,但是由于Y轴是沿着骨头的,所以坐标系完全混乱了,而在我的collada中,坐标系总是Z向上的。我不知道如何改变这一点,我甚至不知道这是否是我的问题。
发布于 2013-04-22 15:10:27
你能给我看一下你试过的旋转吗?听起来你的次要基础是在负X轴旋转90度之后的原始基础。
你可以用四元数w,x,y,z= cos(PI / 4),sin(PI / 4),0,0,基于角轴向量(PI / 2),1,0,0来表示。您还可以将原始四元数转换为矩阵形式,并将仿射旋转矩阵连接起来。我现在忘记了罪过的顺序。
也要小心,你是按照什么顺序乘你的向量和矩阵。(v‘= Rv) != (v’= vR)
编辑1
问题是,四元数没有与生俱来的惯用或依附于特定的基础。它们仅仅是指参考原点而定义的关于方向分量的运动量。此外,它们不存储关于以前轮调的明确信息。
因此,最后一个四元数,也就是在一个上下文中,对Z轴旋转35度的表示,仍然是在另一个上下文中围绕Z轴旋转35度。因为你的第二个基础是一个旋转X远离你原来的基础,这应该是可行的。
其他需要考虑的事项:
你提到肩部--这是一种等级结构吗?如果是的话,这个特定的四元数是该分支的真正的最终/全局四元数,还是引用了另一个本地上下文(并被连接)?
在什么环境下,您要在其他应用程序中实现这个四元数?如果它是相同的层次结构,那么在开始递归呈现之前,尝试用这个校正的四元数来转换您的ModelView,然后在完成时进行转换(或者使用矩阵堆栈)。
编辑2
什么是QNX?您定义了一个没有关联运动的轴。如果尝试使用零或“空”四元数,则为w、x、y、z= 1、0、0、0。
四元数乘法,除非在库的实现中被修改,是从右(基旋转)到左(新的旋转)。我查过艾根,没有提到在文档里换东西。
而且,每个旋转都会将全局轴与对象一起转换,因此正如我前面提到的,在呈现分层模型之前,应该将这个校正的四元数(QX90)添加到全局绝对旋转中。见下文。
Identity Matrix (clean slate) Rotations in effect: [ ]
Rotation 1 [1]
Draw some object [1]
Identity Matrix [ ]
Rotation Q (QX90) [Q]
Rotation A (hip) [A*Q]
Draw hip [A*Q]
Rotation B (spine) [B*A*Q]
Draw spine [B*A*Q]
Rotation C (shoulder) [C*B*A*Q]
Draw shoulder [C*B*A*Q]我只递归地呈现了分层模型,而不是您发布的MSDN指南的迭代结构。然而,这是全局变换矩阵关于其转动分量的状态背后的想法。
发布于 2021-10-31 08:58:42
由于新空间Q‘中的正交基具有不同的惯用性,所以没有给出你想要的东西的q的旋转。
获取所需内容的一种方法是提取输入四元数q的X、Y、Z向量,如下所示:
X = <1-2*qY*qY-2*qZ*qZ, 2*qX*qY+2*qZ*qW, 2*qX*qZ-2*qY*qW>
Y = <2*qX*qY-2*qZ*qW, 1-2*qX*qX-2*qZ*qZ, 2*qZ*qY+2*qX*qW>
Z = <2*qX*qZ+2*qY*qW, 2*qZ*qY-2*qX*qW, 1-2*qX*qX-2*qY*qY>其中qX,qY,qZ,qW是Q的元素,X,Y,Z是基向量。这是从四元数到矩阵的函数(四元数::getMatrix)中提取的。
现在按需要交换轴。
X' = X
Y' = -Z
Z' = Y最后,利用新的基向量X',Y',Z‘构造了一个新的四元数。最近,我在回答这个问题时讨论了如何构造一个四元数的正交基:Quaternion from Orthogonal Basis。
https://stackoverflow.com/questions/16147460
复制相似问题