C++ 计算三维空间中两点的四元数/旋转

C++ 计算三维空间中两点的四元数/旋转,c++,3d,rotation,quaternions,C++,3d,Rotation,Quaternions,我有一个kinect应用程序,它将关节的位置作为三维空间中的点发送给我。 接头的顺序如下图所示。 现在我想在另一个使用COLLADA坐标系的应用程序中移动它们。 我的想法是:如果我想旋转肩部,我需要向量Rshoulder-Relbow并将其存储为VX,然后我需要找到两个正交向量Y和Z,然后计算一个四元数。我可能完全错了,但这只是我目前的心态 简而言之:如何成功地将Y向上系统中的两个给定点的旋转计算为Z向上系统的旋转?在执行任何其他操作之前,您应该首先将这些点转换为内部坐标系。交换Y轴和Z轴很

我有一个kinect应用程序,它将关节的位置作为三维空间中的点发送给我。 接头的顺序如下图所示。

现在我想在另一个使用COLLADA坐标系的应用程序中移动它们。

我的想法是:如果我想旋转肩部,我需要向量Rshoulder-Relbow并将其存储为VX,然后我需要找到两个正交向量Y和Z,然后计算一个四元数。我可能完全错了,但这只是我目前的心态


简而言之:如何成功地将Y向上系统中的两个给定点的旋转计算为Z向上系统的旋转?

在执行任何其他操作之前,您应该首先将这些点转换为内部坐标系。交换Y轴和Z轴很简单-只需交换Y轴和Z轴坐标即可。如果要使用矩阵链执行所有操作,可以制作一个矩阵来执行此操作:

swapYZ_xyz = [ 1 0 0 ]    or,   swapYZ_xyzw = [ 1 0 0 0 ]
             [ 0 0 1 ]                        [ 0 0 1 0 ]
             [ 0 1 0 ]                        [ 0 1 0 0 ]
                                              [ 0 0 0 1 ]
请注意,此转换不是旋转:它是反射。这里需要反射-没有旋转可以根据问题的要求将左手坐标系映射到右手坐标系,而反射总是在左手坐标系和右手坐标系之间转换

这也是为什么四元数表示对于整个坐标转换没有任何意义:四元数自然只表示旋转

一旦你在你的内部坐标系中有了所有的东西,确定每个关节的旋转是一个更复杂的问题,我不会在这里详细解决这个问题,原因如下

首先,如果没有其他信息,每个关节的旋转都没有很好的定义。要看到这一点,假设您有一组与给定关节位置一致的旋转:然后可以将两个关节之间的任何骨骼旋转到任何角度,在不更改关节位置的情况下更改两个关节的旋转。为了消除这种冗余,您需要在某些关节处指定其他约束-也就是说,您需要对有关如何允许弯头旋转的知识进行编码

第二,一旦你解决了上面的模糊问题,你仍然会遇到定义不清的情况——例如,如果手臂是直的,你实际上无法分辨上臂是如何相对于你的手和肩膀旋转的。任何解算器都需要以某种方式处理这种情况-记住,您的数据将是嘈杂的

最好的整体解决方案可能是创建姿势的数学模型,然后运行一个函数来集成嘈杂的输入数据。这是一项重要的任务,但它可以让您以稳健的方式处理嘈杂的数据和暂时的歧义