【问题标题】:Rotation matrix that minimizes distance最小化距离的旋转矩阵
【发布时间】:2009-10-26 10:50:03
【问题描述】:

假设我在 3D 空间中有两个点(a 和 b)和一个称为 n 的固定轴/单位向量。

我想创建一个旋转矩阵,以最小化点 a(未旋转)和旋转点 b 之间的欧几里得距离。

例如:

 Q := matrix_from_axis_and_angle (n, alpha);

 find the unknown alpha that minimizes sqrt(|a - b*Q|)

顺便说一句 - 如果使用单位四元数可以更轻松地表达解决方案/算法,请继续使用它们。我只是使用矩阵来表达我的问题,因为它们使用更广泛。


哦 - 我知道有一些退化的情况(a 或 b 完全符合 n ect。)这些可以忽略。我只是在寻找可以计算单个解决方案的情况。

【问题讨论】:

  • 假设所有的旋转都是关于原点的,如果你旋转 b 所以它落在向量上到 a 这是否不能确保最小(或最大)距离?
  • 或者我们假设 n 是固定的?
  • n 已修复...不幸的是我无法更改它。否则就很简单了。

标签: math 3d geometry


【解决方案1】:

听起来很简单。假设单位向量 n 意味着围绕通过点 x0 的平行于 n 的线旋转。如果 x0 != 原点,将坐标系平移 -x0 以获得相对于新坐标系原点 0 的点 a'b',并使用这两个点代替 a 和 b。

1) 计算向量 ry = n x a

2) 计算单位向量 uy = 方向 ry 上的单位向量

3) 计算单位向量ux = uy x n

您现在有一个三元组的相互垂直的单位向量 ux、uy 和 n,它们形成了一个右手坐标系。可以证明:

 a = dot(a,n) * n  +  dot(a,ux) * ux

这是因为单位向量 uy 平行于 ry,ry 垂直于 a 和 n。 (从第 1 步开始)

4) 沿单位向量 ux, uy 计算 b 的分量。 a 的组件是 (ax,0),其中 ax = dot(a,ux)。 b 的组件是 (bx,by),其中 bx = dot(b,ux),by = dot(b,uy)。由于是右手坐标系,所以 ax 始终为正,因此您实际上不需要计算它。

5) 计算 theta = atan2(by, bx)。

您的旋转矩阵是相对于坐标系 (ux,uy,n) 围绕 n 轴旋转角度 -theta 的矩阵。

如果 a 与 n 平行(步骤 1 和 2)或 b 与 n 平行(步骤 4、5),这会产生退化的答案。

【讨论】:

    【解决方案2】:

    我认为您可以将问题改写为:

    点到 3d 空间中的 2d 圆的距离是多少。

    可以在here找到答案

    所以需要的步骤如下:

    • 围绕向量 n 旋转点 b 会在 3d 空间中为您提供一个 2d 圆
    • 使用上述方法,找出到该圆(以及圆上的点)的距离
    • 圆上的点就是您要查找的旋转点 b。
    • 推导出旋转角度

    ...或者什么;^)

    【讨论】:

      【解决方案3】:

      当a到n线的向量与b到n线的向量对齐时,距离将最小化。

      将 a 和 b 投影到垂直于 n 的平面中,并在二维中求解问题。您到达那里的旋转是最小化距离所需的旋转。

      【讨论】:

        【解决方案4】:

        令 P 为垂直于 n 的平面。 我们可以找到 a 在 P 平面中的投影,(对于 b 也是如此):

        a' = a - (dot(a,n)) n 
        b' = b - (dot(b,n)) n 
        

        其中 dot(a,n) 是 a 和 n 的点积

        a' 和 b' 位于 P 平面内。

        我们现在已将问题简化为二维。耶!

        a'和b'之间的(旋转)角度等于b绕n轴摆动以最接近a所需的(旋转)角度。 (想想 b 会投射在 P 平面上的阴影)。

        a'和b'之间的夹角很容易找到:

        dot(a',b') = |a'| * |b'| * cos(theta)
        

        求解θ。

        现在你可以在这里找到给定 theta 和 n 的旋转矩阵: http://en.wikipedia.org/wiki/Rotation_matrix

        Jason S 正确地指出,一旦你知道了 theta,你仍然必须决定将 b 绕 n 轴顺时针或逆时针旋转。

        如果 (a x b) 与 n 的方向相同,则 dot((a x b),n) 为正数,如果 (a x b) 与 n 方向相反,则为负数。 (只要 a 和 b 都不与 n 共线,它就永远不会为零。)

        如果 (a x b) 与 n 方向相同,则 b 必须绕 n 轴顺时针旋转角度 theta。

        如果 (a x b) 位于相反方向,则 b 必须绕 n 轴顺时针旋转角度 -theta。

        【讨论】:

        • 你的theta值只在180度内唯一;您需要某种方式来选择 theta 或 theta + 180 度。
        • 当使用点积方程求解 a' 和 b' 之间的角度时,习惯上将 theta 取为 0 和 pi 弧度之间。只要 a 和 b 不与 n 共线,角度 theta 是唯一的。
        • 我明白这一点。按照惯例,角度 theta = inv_cos(...) 是唯一的,如您所说,通常映射到正范围 [0,pi]。但是解决这个问题所需的旋转角度是 [0,2*pi) 范围内的唯一角度。我之前的评论略有错误,您需要选择 +theta 或 -theta。其中一个角度将摆动 b,因此它与向量 a 和 n 共面。另一个角度不会。
        • (即你需要找到a'和b'之间的有向角。点积方程只帮助你找到无向 a' 和 b' 之间的角度。这不是错误的方法,但是在使用该方程求解 theta 之后,您仍然需要在顺时针和逆时针旋转之间消除歧义,以确定哪个方向是正确的。)
        • 谢谢 Jason S。你是对的,我忽略了确定旋转应该是顺时针还是逆时针。我已经确定了答案。
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-03-03
        • 1970-01-01
        • 2019-09-04
        • 2011-03-03
        • 1970-01-01
        相关资源
        最近更新 更多