旋转轴错误的 3D 旋转

问题描述 投票:0回答:1

我在使用 3d 旋转矩阵来实现魔方模拟器时遇到一个小问题。我的问题是,当尝试围绕全局 x 和 y 轴(3d 中)旋转我的立方体时,我最终会围绕 全局 x 轴和立方体的 y 轴。例如以下一张图片为起点:the original position

以下一张图片为例,当我尝试通过将鼠标向左移动来绕 y 轴旋转时会发生什么:incorrectly rotating around the cube's y axis

下一张图片作为我尝试通过向下移动鼠标绕 x 轴旋转时发生的情况的示例:correctly rotating around the global x axis

在这里您可以看到我用来执行旋转的代码:

from math import cos,sin
import numpy as np
def rotate(mat,xangle,yangle,zangle):  #these angles are by how much i want to rotate around a certain                   axis (in radians)
    xrotation_matrix = np.matrix([[1,0,0],
                                  [0,cos(xangle),-sin(xangle)],
                                  [0,sin(xangle),cos(xangle)]])
    yrotation_matrix = np.matrix([[cos(yangle),0,sin(yangle)],
                                  [0,1,0],
                                  [-sin(yangle),0,cos(yangle)]])
    zrotation_matrix = np.matrix([[cos(zangle),-sin(zangle),0],
                                  [sin(zangle),cos(zangle),0],
                                  [0,0,1]])
    rotated3d = np.dot(zrotation_matrix,mat.reshape((3,1)))  #mat is a point in the form np.matrix([x,y,z])
    rotated3d = np.dot(yrotation_matrix,rotated3d)
    rotated3d = np.dot(xrotation_matrix,rotated3d)
    return rotated3d

有关代码如何工作的额外上下文(尽管有点不必要),以下是我计算如何获取旋转角度的方法:

def get_full_turn(self,mousepos):
    xchange = mousepos[0]-self.startdrag[0]
    ychange = mousepos[1]-self.startdrag[1]
    self.xangle -= self.xadding
    self.yangle -= self.yadding
    self.xadding = ychange/100
    self.yadding = xchange/100
    self.xangle += self.xadding
    self.yangle += self.yadding

如何使立方体绕全局 x 和全局 y 轴旋转,以便我可以正确旋转它? (请非常简单地解释,因为我只是一个充满热情,但又是新 A-level 的学生)

到目前为止,我已经尝试用旋转矩阵反转乘法的顺序(一些网站显示了类似的解决方案),但结果非常相似(只有 1 个轴绕全局轴旋转,而其他轴绕当前轴旋转)。

python numpy 3d rotation rubiks-cube
1个回答
0
投票

第二张图片信息量不大,但我认为问题在于立方体的中心不在

(0, 0, 0)
位置。 旋转矩阵相对于
(0, 0, 0)
顶点旋转顶点。

来自 Wolfram alpha 的信息更丰富的示例(但仅适用于 2D)。

如果有问题,解决办法就是移位矩阵。首先,将立方体移动到矩阵 M_shify 的位置,其中心位于

(0, 0, 0)
。然后用矩阵旋转。然后使用反向移位矩阵(移位参数乘以-1)

此外,最好使用 matmul 运算符

@
进行矩阵乘法。

对于 2D 矩阵 numpy.dot 相当于 matmul 运算符:

rotated3d = np.dot(zrotation_matrix,mat.reshape((3,1)))
    rotated3d = np.dot(yrotation_matrix,rotated3d)
    rotated3d = np.dot(xrotation_matrix,rotated3d)

相当于

rotated3d = zrotation_matrix @ yrotation_matrix @ xrotation_matrix @ rotated3d
© www.soinside.com 2019 - 2024. All rights reserved.