需要 3D 旋转算法

发布于 2024-09-16 18:52:37 字数 378 浏览 6 评论 0原文

给定两个正交单位向量 A 和 B,以及两个不同的正交单位向量 C 和 D,我需要 3x3 方向余弦矩阵或四元数,它将旋转 A 以与 C 对齐,并将旋转 B 以与 D 对齐。

向量是所有 3 向量 (x, y, z)。

我有一个强力算法,但我几乎可以肯定有一个更简单的解决方案。我的网络搜索还没有发现这一点。

我正在使用 C#,但如果您有 C、FORTRAN 或 Basic(等)语言的内容,我可以将其转换。或者,我可以使用数学上写出的术语。

该应用程序正在确定航天器所需的方向,以便牢固地连接到航天器上的光学设备能够正确对齐以拍照。 (必须实现瞄准镜方向和光学装置绕瞄准镜的适当旋转,因此需要立即对准两个矢量。)该计算可以在由实时感测数据馈送的循环中使用,并且暴力解决方案太慢。

Given two orthogonal unit vectors, A and B, and two different orthogonal unit vectors C and D, I need the 3x3 direction cosine matrix or a quaternion which will rotate A to align with C AND will rotate B to align with D.

The vectors are all 3-vectors (x, y, z).

I have a brute force algorithm, but I am almost certain there is a much simpler solution. And my web searches have not yet revealed one.

I am using C#, but if you have something in C, or FORTRAN, or Basic (etc.) I can convert it. Or, I can use the terms written out mathematically.

The application is determining the orientation needed for a spacecraft so an optical device attached rigidly to it will be properly aligned to take a picture. (Both the bore sight direction and the appropriate rotation of the optic device about bore sight must be attained, thus the need to align TWO vectors at once.) The computation may be used in a loop fed by real-time sensed data, and the brute force solution is too slow.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

我三岁 2024-09-23 18:52:37

我重读了你的问题,下面的答案(虽然是正确的)并没有给你你想要的。此链接是关于构造 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)

要按原样使用这个矩阵,你必须在基础 {A, B , CxD},然后将其左乘以 M。以同样的方式执行此操作。事实上,N 是从您的正常基础转换为 {A, B, ..} 的矩阵,上面的 M 将其转换为 {C, D...},然后 MN (此处为左乘)将从您的基础转换为到 {C, D, ..} 并提供您想要的旋转。

所以现在,所有向量都以基础 {C, D, ..} 表示:(

解决方案是另一个变换矩阵。这个矩阵从 {A, B, ..} 映射到您的主要基础并撤消 N,也称为逆矩阵,表示为 N^-1 ,所以你的最终矩阵是 (N^-1)MN ,好消息是因为 N 是正交的,所以你只需要它的转置即可

。你最常处理的矩阵很漂亮。

I reread your question and the answer below (while right) doesn't give you what you want. This link is about constructing a 3x3 rotation matrix.

since they are both orthogonal unit vectors, you just need to add one more too each to construct a basis (use the cross product for this). So now you have two basis {A, B, AxB} and {C, D, CxD}. A rotation that moves {A, B} onto {C, D} will re-express a vector a1A + a2B + a3(AXB) as b1C + b2D + b3(CxD). because it's linear you only need to know how it behaves on the basis (This uniquely determines the linear transformation). So, taking {A, B, ..} as our basis and letting the transformation be T, we see that T(1, 0, 0) = C, T(0, 1, 0) = D and T(0, 0, 1) = CxD. Remember A = (1, 0, 0) etc. But the columns of this matrix are just M =(C, D, CxD)

To use this matrix as it stands, you have to express every vector in the basis {A, B, CxD} before you left-multiply it by M. You do this in the same way. In fact, it N is the matrix which translates from your normal basis to {A, B, ..} and M above translates that to {C, D...}, then MN (left multiplication here) will translate from your basis to {C, D, ..} and provide the rotation you want.

So now, all of your vectors are expressed in the basis {C, D, ..} :(

The solution is yet another transformation matrix. This one maps from {A, B, ..} to your primary basis and undoes N, also known as the inverse and denoted N^-1. So your final matrix is (N^-1)MN. The good news is that because N is orthogonal, you just need it's transpose.

The trick is to choose your primary basis so that the matrices you deal with most are pretty.

错々过的事 2024-09-23 18:52:37

https://alleg.svn.sourceforge。 net/svnroot/alleg/allegro_outdated/branches/allegro/src/math3d.c

几乎完整的 3d 图形代码....查看底部的函数,从 .. 开始

get_align_matrix_f

,对于 quaterian 也是如此...

https://alleg.svn.sourceforge。 net/svnroot/alleg/allegro_outdated/branches/allegro/src/quat.c

也在矩阵中,它可能不会给你从向量 A 到 C 的最短(或直接)路径,所以如果你正在制作动画视觉效果上,最好使用quats。

https://alleg.svn.sourceforge.net/svnroot/alleg/allegro_outdated/branches/allegro/src/math3d.c

almost complete code for 3d graphics....check out functions at the bottom starting with..

get_align_matrix_f

and here goes same for quaterian...

https://alleg.svn.sourceforge.net/svnroot/alleg/allegro_outdated/branches/allegro/src/quat.c

also in matrix, it may not give you shortest ( or direct ) path from vactor A to C, so if you are animating the visuals, its better to use quats.

蒲公英的约定 2024-09-23 18:52:37

考虑到航天器的成本高达数亿美元,您可能希望找到可以在睡梦中完成此类事情的人,并要求他们使用代码生成防弹且优化的解决方案,而不是依赖此处的描述。 (除非这只是一个练习。)

此外,您选择的解决方案应该在很大程度上取决于航天器上可用的推进器;你希望旋转使用尽可能少的燃料,这将取决于它们对航天器的本质作用。我假设您已将问题设置为使一个旋转轴围绕 z 轴;你可以独立地绕 x 和 y 旋转,还是只有一个其他轴?某些旋转是否比其他旋转更昂贵(例如,由于沿某些轴的惯性矩不同)?

考虑到这些警告,我非常犹豫是否给出这样的建议:找到(A x C),将 A 移动到 C 上并旋转所需的旋转轴(有关沿轴旋转的信息,请参阅维基百科)。然后找出它对 B 的影响(通过将旋转矩阵乘以 B)并计算 B 和 D 之间的角度;最后,沿 (B x D) 轴旋转(此时最好与 C 轴相同)以修复该差异(给出另一个旋转矩阵)。将两个矩阵相乘,瞧,你就完成了。

Given that spacecraft cost hundreds of millions of dollars, you might want to find someone who can do this sort of thing in their sleep and ask them to generate a bulletproof and optimized solution, with code, rather than relying on descriptions here. (Unless this is just an exercise.)

Also, the solution you pick should depend very heavily on the thrusters available on the spacecraft; you want the rotation to use as little fuel as possible, and that's going to depend on what they intrinsically do to the spacecraft. I assume that you've set the problem up so that one axis of rotation is around the z axis; can you rotate independently around x and y also, or do you only have one other axis? Are some rotations more expensive than others (e.g. due to a different moment of inertia along some axes)?

Given these caveats, I'm pretty hesitant to give advice like: find (A x C), the axis of rotation needed to move A onto C and rotate (see Wikipedia for rotation along an axis). Then figure out what that does to B (by multiplying the rotation matrix by B) and compute the angle between B and D; finally, rotate along the (B x D) axis--which had better be the same as the C axis at this point--to fix that difference (giving another rotation matrix). Mutliply the two matrices, and voila, you're done.

热风软妹 2024-09-23 18:52:37

在原始帖子之后我知道,但如果您也遇到列/行主要和左/右手混淆问题,如果您想将 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!

Somewhat after the original post I know but in case you too are suffering from column/row major and left/right hand confusion issues, if you wanted to encode Mark T's splendid result into WPF you'd do it like this:

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;


    }

Many thanks Mark!

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文