【问题标题】:Find rotation matrix to align two vectors查找旋转矩阵以对齐两个向量
【发布时间】:2021-04-09 07:52:37
【问题描述】:

我试图找到旋转矩阵来对齐两个向量。

我有一个向量 A = [ax, ay, az],我想将它与向量 B = [1, 0, 0](x 轴单位向量)对齐。

找到如下解释并尝试实现:https://math.stackexchange.com/questions/180418/calculate-rotation-matrix-to-align-vector-a-to-vector-b-in-3d/897677#897677

def align_vectors(a, b):
     v = np.cross(a, b)
     s = np.linalg.norm(v)
     c = np.dot(a, b)

     v1, v2, v3 = v
     h = 1 / (1 + c)

     Vmat = np.array([[0, -v3, v2],
                      [v3, 0, -v1],
                      [-v2, v1, 0]])

     R = np.eye(3, dtype=np.float64) + Vmat + (Vmat.dot(Vmat) * h)
     return R

当我应用它来查找点的旋转时,这就是我所拥有的:

x_axis = np.array([1, 0, 0], dtype=np.float64)
direction = np.array([-0.02, 1.004, -0.02], dtype=np.float64)
Ralign = align_vectors(x_axis, direction)
point = 1000 * np.array([-0.02, 1.004, -0.02], dtype=np.float64) # Point in the direction of the unit vector
result = Ralign.dot(point)

结果点未与单位向量对齐。

【问题讨论】:

  • 数学交换中的答案假设ab 是单位向量。您需要重做数学以将长度包括在计算中。或先将它们标准化。

标签: python rotation


【解决方案1】:

如果您只想旋转一个矢量a 以与b 对齐,而不是整个坐标都包含该矢量,请使用简单的矢量投影和a 的长度:

a_norm = np.linalg.norm(a)
b_norm = np.linalg.norm(b)
result = b * a_norm / b_norm

以下解决了输入不是向量归一化的单位向量的问题。

def align_vectors(a, b):
    b = b / np.linalg.norm(b) # normalize a
    a = a / np.linalg.norm(a) # normalize b
    v = np.cross(a, b)
    # s = np.linalg.norm(v)
    c = np.dot(a, b)

    v1, v2, v3 = v
    h = 1 / (1 + c)

    Vmat = np.array([[0, -v3, v2],
                  [v3, 0, -v1],
                  [-v2, v1, 0]])

    R = np.eye(3, dtype=np.float64) + Vmat + (Vmat.dot(Vmat) * h)
    return R

测试:


def angle(a, b):
    """Angle between vectors"""
    a = a / np.linalg.norm(a)
    b = b / np.linalg.norm(b)
    return np.arccos(a.dot(b))

point = np.array([-0.02, 1.004, -0.02])
direction = np.array([1., 0., 0.])
rotation = align_vectors(point, direction)

# Rotate point in align with direction. The result vector is aligned with direction
result = rotation.dot(point)
print(result)
print('Angle:', angle(direction, point)) # 0.0
print('Length:', np.isclose(np.linalg.norm(point), np.linalg.norm(result))) # True


# Rotate direction by the matrix, result does not align with direction but the angle between the original vector (direction) and the result2 are the same.
result2 = rotation.dot(direction)
print(result2)
print('Same Angle:', np.isclose(angle(point,result), angle(direction,result2))) # True
print('Length:', np.isclose(np.linalg.norm(direction), np.linalg.norm(result2))) # True

【讨论】:

  • 非常感谢。此方法看起来与 Rodriguez 公式非常相似。但是,正弦系数不适用于偏斜矩阵。知道为什么这个表格是推荐的吗?
  • 这里的旋转矩阵对齐ab(将a投影到b上并保持长度不变)。因此,将a 表示的向量空间与b 对齐。 Rodriguez 将坐标系旋转关于 向量k。参见维基百科上的this figure。结果向量与k(on wiki) 对齐当且仅当输入向量是。画一些图来看看这些向量是如何相关的。
  • 谢谢。我可以看到这两者是相关的,可以根据我们可用的信息来使用。如果第二个被命名为“罗德里格斯公式”,那么第一个被赋予什么名称?
猜你喜欢
  • 2017-12-21
  • 1970-01-01
  • 2018-11-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-10-01
相关资源
最近更新 更多