请注意,虽然它听起来很相似,但这不是常见的"如何将一个矢量旋转到另一个矢量"问题.
我想从两组3个点得到一个仿射变换(矩阵或四元数+矢量形式).这些可以被视为刚体上的"标记点",或者作为"向前和向上"向量的端点.翻译和旋转是必要的,缩放不是必需的.此外,四元数+向量解决方案将是一个加号,因为它将允许我将1/3多个实例塞入绘图批次(8个制服而不是12个).目的是建立一个系统,以直观的方式确定(铰接的或非铰接的)身体的姿势,而不需要维护和行走复杂的层次结构.
第一个明显的简化是通过选择一个点并从相应的"开始"点减去"目的地"来消除平移部分.现在我们只需要处理轮换.
有一种众所周知的,计算上廉价的构造四元数的解决方案,它将一个矢量旋转到另一个矢量上,即q(交叉(v1,v2); sqrt(v1.len_sq*v2.len_sq)+点(v1,v2))或q(cross(v1,v2); 1 + dot(v1,v2))用于单位长度矢量.不幸的是,这种方法没有"向上方向"的概念,因此总是在最短的弧上旋转(这将使对象不对齐).天真的做法是简单地将这种方法用于两个向量并将四元数相乘,但显然它不会那么容易.需要做的是选择两个向量中的一个(让我们称之为"向前"),并为此创建一个四元数,然后使用此四元数旋转另一个("向上")向量,然后构造第二个四元数对于旋转的"向上"向量(和目标"向上"向量),最后将第二个乘以第一个四元数.据我所知,这是正确的,但它也非常复杂.
现在......至于旋转矩阵,我知道"三元组方法",我理解如下: - 对矢量对(开始和结束)进行正交化 - 这导致两个正交基,它们是相应的旋转矩阵,用于启动并从"共同参考框架"结束.这究竟是什么参考框架并不重要,重要的是两者都是相同的. - S是从"公共帧"到起始帧的变换,D是到结束帧的变换.- 因此,S -1*D*v转换从开始到结束坐标系的任何点(通过公共参考系).- S -1 == S T因为它是一个标准正交矩阵,并且S T*x = x*S - 因此:S T*D*v = D*S*v
这应该可行,但对于实际上应该非常非常简单的事情来说,它似乎仍然相当复杂.
有更简单,更直接的解决方案吗?
仅处理旋转部分,您的第二种方法将起作用,并且我怀疑它会很好地起作用。或者,您可以混合使用这两种方法,这可能会更容易一些。假设您上面构造了两对两个向量,每对都在其自己的向量空间中。计算每一对的正交基,并在一个向量空间中将它们称为 X 0和 X 1,在另一个向量空间中将其对应的向量 Y 0和 Y 1称为 Y 0和 Y 1 。您现在必须计算两个四元数旋转:
1)q 0将X 0和X 1分别旋转到X' 0和X' 1,使得X' 0 = Y 0。X' 1和 Y 1现在应与平面法线 X' 0 = Y 0共面。
2) q 1将X' 1旋转至X'' 1 = Y 1。您需要做的就是计算向量之间的角度,因为您已经知道旋转向量将是 X' 1 x Y 1 = X' 0 = Y 0
您可以计算 q = q 1 * q 0以一步执行旋转。