我在使用 3d 旋转矩阵来实现魔方模拟器时遇到一个小问题。我的问题是,当尝试围绕全局 x 和 y 轴(3d 中)旋转我的立方体时,我最终会围绕 全局 x 轴和立方体的 y 轴。例如以下一张图片为起点:
以下一张图片为例,当我尝试通过将鼠标向左移动来绕 y 轴旋转时会发生什么:
下一张图片作为我尝试通过向下移动鼠标绕 x 轴旋转时发生的情况的示例:
在这里您可以看到我用来执行旋转的代码:
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 个轴绕全局轴旋转,而其他轴绕当前轴旋转)。
第二张图片信息量不大,但我认为问题在于立方体的中心不在
(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