首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >四元数基变换

四元数基变换
EN

Stack Overflow用户
提问于 2013-04-22 12:45:54
回答 2查看 4.6K关注 0票数 3

我有一个四元数,基于一个坐标系,其中Y轴向上,X轴在右边,Z轴朝我看。

现在,我想基于这个四元数在另一个应用程序(C++)中移动一个字符。如果坐标系统是相同的,这就没有问题了,但是这个应用程序使用的是不同的坐标系。Z在上面,X在右边,Y通过显示器(向内)。

我试着简单地旋转四元数来调整坐标系,但是每次旋转,它看起来都不太正确。

我的想法是,我需要某种基变换,但我不知道如何用四元数来实现这一点,有人知道如何在四元数上执行基转换吗?

编辑

我使用特征C++库来表示四元数。以下是我使用的四元数:

代码语言:javascript
复制
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轴:

代码语言:javascript
复制
Qrshoulder=Qrshoulder*QX90; 
Qrshoulder=QX90*Qrshoulder;
Qrshoulder=Qrshoulder*nQX90;
Qrshoulder=nQX90*Qrshoulder;

这不管用。我还尝试了其他几个乘法,我几乎尝试了每一个似乎合乎逻辑的旋转。我是confused..it,这似乎是四元数乘法做不到的

编辑2

我有绝对和等级等级的四元数。分层四元数提供了从父骨到child..the的三维空间中的旋转量,绝对四元数是乘以层次的骨方向。

另一方面,我想要动画的角色背后有一个引擎,这个引擎已经使骨骼倍增,所以我肯定需要使用分级旋转。但问题是,当我使用分层旋转时,Y轴总是位于骨的方向上。

我从诺尔诺奇的回答中得到的答案是:

代码语言:javascript
复制
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向上的。我不知道如何改变这一点,我甚至不知道这是否是我的问题。

EN

回答 2

Stack Overflow用户

发布于 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)添加到全局绝对旋转中。见下文。

代码语言:javascript
复制
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指南的迭代结构。然而,这是全局变换矩阵关于其转动分量的状态背后的想法。

票数 2
EN

Stack Overflow用户

发布于 2021-10-31 08:58:42

由于新空间Q‘中的正交基具有不同的惯用性,所以没有给出你想要的东西的q的旋转。

获取所需内容的一种方法是提取输入四元数q的X、Y、Z向量,如下所示:

代码语言:javascript
复制
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)中提取的。

现在按需要交换轴。

代码语言:javascript
复制
X' = X
Y' = -Z
Z' = Y

最后,利用新的基向量X',Y',Z‘构造了一个新的四元数。最近,我在回答这个问题时讨论了如何构造一个四元数的正交基:Quaternion from Orthogonal Basis

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/16147460

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档