使用numpy插值旋转角度

5
我有一个“单一”的观点。
x = ..
y = ..
p = np.matrix([[x],[y]])

我希望将该点围绕原点旋转,每次旋转d度,以获取N = 360/d个点。例如,我设想以下函数。

points = interpolate360(d, p)

点的形状应该是(2,N)

我可以使用循环为每次旋转使用新的旋转矩阵,然后连接结果,但我希望有一种向量化的解决方案。

1个回答

5

在大多数情况下,使用numpy的matrix可能不是最佳选择。解决问题的一种方法是创建一个三维数组,其中[n, :, :]保存第n个角度的旋转矩阵。你不能拥有一个3D matrix,所以如果混合使用数组和矩阵类型并仍然希望依赖于*执行矩阵乘法,它可能会变得混乱。如果您坚持使用数组,并使用np.dot来可预测地处理矩阵乘法,则以下代码可以很好地工作。它实际上也会接受一个matrix,但首先将其转换为ndarray

def interpolate360(d, p):
    p = np.array(p)
    angles = np.arange(0, 2 * np.pi, d * np.pi / 180)
    sin = np.sin(angles)
    cos = np.cos(angles)

    rot_matrices = np.empty((angles.shape[0], 2, 2))
    rot_matrices[..., 0, 0] = cos
    rot_matrices[..., 0, 1] = -sin
    rot_matrices[..., 1, 0] = sin
    rot_matrices[..., 1, 1] = cos

    return np.dot(rot_matrices, p)

如下面的示例所示,如果您的输入是一维行向量、二维单列向量或包含多个列向量的二维数组,则此方法可行:
>>> interpolate360(90, [0, 1])
array([[  0.00000000e+00,   1.00000000e+00],
       [ -1.00000000e+00,   6.12323400e-17],
       [ -1.22464680e-16,  -1.00000000e+00],
       [  1.00000000e+00,  -1.83697020e-16]])
>>> interpolate360(90, [[0], [1]])
array([[[  0.00000000e+00],
        [  1.00000000e+00]],

       [[ -1.00000000e+00],
        [  6.12323400e-17]],

       [[ -1.22464680e-16],
        [ -1.00000000e+00]],

       [[  1.00000000e+00],
        [ -1.83697020e-16]]])
>>> interpolate360(90, [[1, 0], [0, 1]])
array([[[  1.00000000e+00,   0.00000000e+00],
        [  0.00000000e+00,   1.00000000e+00]],

       [[  6.12323400e-17,  -1.00000000e+00],
        [  1.00000000e+00,   6.12323400e-17]],

       [[ -1.00000000e+00,  -1.22464680e-16],
        [  1.22464680e-16,  -1.00000000e+00]],

       [[ -1.83697020e-16,   1.00000000e+00],
        [ -1.00000000e+00,  -1.83697020e-16]]])

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