需要3D旋转算法

4
给定两个正交单位向量A和B,以及两个不同的正交单位向量C和D,我需要一个3x3方向余弦矩阵或四元数,它可以将A旋转以与C对齐,并将B旋转以与D对齐。
这些向量都是3维向量(x,y,z)。
我有一个暴力算法,但我几乎确定有一种更简单的解决方法。我的网络搜索还没有揭示出一个。
我正在使用C#,但如果您有C、FORTRAN、Basic等内容,我可以转换它。或者,我可以使用数学上书写的术语。
该应用程序用于确定航天器所需的方向,以便刚性附着在其上的光学设备能够正确对准拍摄。 (必须同时对齐两个向量,即瞄准方向和关于瞄准方向旋转光学装置的适当旋转。)该计算可能在由实时感测数据提供的循环中使用,并且暴力解决方案速度太慢。
4个回答

3
我重新阅读了您的问题和下面的答案(虽然正确),但并没有给您想要的东西。这个链接是关于构建一个3x3旋转矩阵的。

由于它们都是正交单位向量,你只需要再添加一个来构造一个基(使用叉积)。现在你有两个基础{A,B,AXB}和{C,D,CxD}。将{A,B}移动到{C,D}的旋转将重新表达一个向量a1A + a2B + a3(AXB)作为b1C + b2D + b3(CxD)。因为它是线性的,你只需要知道它在基础上的行为(这确定了线性变换)。因此,以{A,B,...}为我们的基础,并让变换为T,我们看到T(1,0,0)= C,T(0,1,0)= D和T(0,0,1)= CxD。记住A =(1,0,0)等等。但这个矩阵的列只是M =(C,D,CxD)。

为了使用这个矩阵,您必须在左乘M之前将每个向量表示为{A,B,CxD}基础中的形式。您可以用同样的方式做到这一点。实际上,如果N是从您的正常基础转换到{A,B,...}的矩阵,并且上面的M将其转换为{C,D ...},那么MN(此处为左乘)将从您的基础转换为{C,D,...}并提供所需的旋转。
现在,所有的向量都以{C,D,...}基础为基础表示:(
解决方案是另一个变换矩阵。这个矩阵将从{A,B,...}映射到您的主要基础,并撤消N,也称为逆矩阵,表示为N ^ -1。因此,您的最终矩阵是(N ^ -1)MN。好消息是因为N是正交的,所以您只需要它的转置。
关键是选择您的主要基础,使您处理的矩阵更加简单。

2
这是经过测试的解决方案:如果A和B是正交单位向量,要旋转到D和E,它们也是正交单位向量 (注意变量名称从原问题中更改。) 然后计算叉积:C = B X A和F = E X D然后所需的旋转矩阵为: DxAx+ExBx+FxCx,DxAy+ExBy+FxCy,DxAz+ExBz+FxCz, DyAx+EyBx+FyCx,DyAy+EyBy+FyCy,DyAz+EyBz+FyCz, DzAx+EzBx+FzCx,DzAy+EzBy+FzCy,DzAz+EzBz+Fz*Cz非常简单,计算速度非常快,没有奇异性。 - Mark T

1

1

考虑到航天器的成本高达数亿美元,您可能希望找到一个能够轻松完成此类任务并要求他们生成一个经过验证和优化的解决方案,包括代码,而不是仅依靠这里的描述。(除非这只是一种练习。)

此外,您选择的解决方案应该非常依赖于航天器上可用的推进器;您希望旋转使用尽可能少的燃料,这将取决于它们对航天器的内在影响。我假设您已经设置了问题,使得一个旋转轴围绕z轴旋转;您是否还可以独立地围绕x和y旋转,或者只有另一个轴?某些旋转是否比其他旋转更昂贵(例如由于沿某些轴的不同惯性矩)?

考虑到这些限制,我非常犹豫给出如下建议:找到将A移动到C所需的旋转轴(A x C),并进行旋转(参见维基百科关于绕轴旋转的内容)。然后通过将旋转矩阵乘以B来计算B的变化,并计算B和D之间的夹角;最后,沿着(B x D)轴旋转--此时该轴必须与C轴相同--以修正差异(得到另一个旋转矩阵)。将两个矩阵相乘,完成。


你的想法是正确的,但在这个问题上想得太多了。这是为了对卫星系统进行详细模拟,并具有硬件在环的潜力。因此,我们不会在硬件上花费太多。而且,我们只关心(在这个模块中)所需的方向,而不关心如何到达那里。到达那里的确是一个完全不同的问题,将由完全不同的软件集来完成,除了你提到的问题外,还必须执行避免将任何敏感传感器指向太阳等任务。 - Mark T

0

虽然我知道这篇文章发表已经有一段时间了,但是如果你也遇到了列/行主要性和左/右手混淆的问题,并且想将Mark T的优秀结果编码成WPF,你可以像这样做:

static public Matrix3D TwistToNewAxes(Vector3D A, Vector3D B, Vector3D D, Vector3D E)
    {
        Vector3D C = Vector3D.CrossProduct(B, A);
        Vector3D F = Vector3D.CrossProduct(E, D);

        Matrix3D result = Matrix3D.Identity;

        result.M11 = D.X * A.X + E.X * B.X + F.X * C.X;
        result.M21 = D.X * A.Y + E.X * B.Y + F.X * C.Y;
        result.M31 = D.X * A.Z + E.X * B.Z + F.X * C.Z;
        result.M12 = D.Y * A.X + E.Y * B.X + F.Y * C.X;
        result.M22 = D.Y * A.Y + E.Y * B.Y + F.Y * C.Y;
        result.M32 = D.Y * A.Z + E.Y * B.Z + F.Y * C.Z;
        result.M13 = D.Z * A.X + E.Z * B.X + F.Z * C.X;
        result.M23 = D.Z * A.Y + E.Z * B.Y + F.Z * C.Y;
        result.M33 = D.Z * A.Z + E.Z * B.Z + F.Z * C.Z;

        return result;


    }

非常感谢 Mark!


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接