x、y、z 张量的 2 步 3D 旋转

2-step 3D rotation of x,y,z tensors

在 Python 中,使用 PyTorch,我尝试旋转 3 个立方体 xyz,首先是关于 x - 轴,然后绕 z 轴。但是,围绕 z 轴的旋转似乎以一种我不希望的方式表现。

我正在创建 3 个立方体以在下方旋转,然后将它们绕 x 轴旋转 90 度,然后再绕 z 轴旋转 90 度。

import torch 
from numpy import pi 
import matplotlib.pyplot as plt

def rotation(x,y,z,theta,phi):
    ### A function for rotating about the x and then z axes ###
    xx = (x*torch.cos(theta)) - (((y*torch.cos(phi)) - (z*torch.sin(phi)))*torch.sin(theta))
    yy = (x*torch.sin(theta)) + (((y*torch.cos(phi)) - (z*torch.sin(phi)))*torch.cos(theta))
    zz = (y*torch.sin(phi)) + (z*torch.cos(phi))
    return xx,yy,zz

### Creating the 3 cubes: x, y, z ###
l = torch.arange(-2,3,1)
x,y,z=torch.meshgrid(l,l,l)

###  Scaling the cubes so they can be differentiated from one another ###
x = x.clone().T
y = y.clone().T*2
z = z.clone().T*3

### Defining the amount of rotation about the x and z axes
phi = torch.tensor([pi/2]).to(torch.float) # about the x axis
theta = torch.tensor([pi/2]).to(torch.float) # about the z axis

### Performing the rotation
x_r,y_r,z_r = rotation(x, y, z, theta, phi)

通过可视化每个立方体的第一个切片,我可以看到旋转没有成功,乍一看,立方体似乎实际上是绕 x 轴旋转,然后绕 y 轴旋转。

有没有一种特定的方法可以让 Python 处理像我这样缺少的旋转,例如轴随着旋转而变化,这意味着初始的 rotation matrix operation 不再适用?


额外信息

如果要将 theta 替换为 0 而不是 pi/2,可以看出,通过查看每个旋转立方体的第一个切片,第一次旋转的行为符合预期:

可视化代码:

plt.figure()
plt.subplot(231)
x_before = plt.imshow(x[0,:,:])
plt.xlabel('x-before'); plt.colorbar(x_before,fraction=0.046, pad=0.04)
plt.subplot(232)
y_before = plt.imshow(y[0,:,:])
plt.xlabel('y-before'); plt.colorbar(y_before,fraction=0.046, pad=0.04)
plt.subplot(233)
z_before = plt.imshow(z[0,:,:])
plt.xlabel('z-before'); plt.colorbar(z_before,fraction=0.046, pad=0.04)
plt.subplot(234)
x_after = plt.imshow(x_r[0,:,:])
plt.xlabel('x-after'); plt.colorbar(x_after,fraction=0.046, pad=0.04)
plt.subplot(235)
y_after = plt.imshow(y_r[0,:,:])
plt.xlabel('y-after'); plt.colorbar(y_after,fraction=0.046, pad=0.04)
plt.subplot(236)
z_after = plt.imshow(z_r[0,:,:])
plt.xlabel('z-after'); plt.colorbar(z_after,fraction=0.046, pad=0.04)
plt.tight_layout()

这听起来像是一个全局轴与局部轴的问题 - 您首先绕 X 轴旋转 90 度,这会移动您的立方体,使其局部 Y 轴最终指向全局 Z 轴。围绕全局 Z 应用下一个 90 度旋转看起来像围绕局部 Y 轴旋转。

要解决这个问题,您需要应用不同的旋转来实现您想要的方向(在这种情况下,围绕全局 Y 旋转 -90 度,因为局部 Z 轴现在面向负全局 Y 轴),或者编写一个不同的旋转函数,它可以围绕任何向量旋转并跟踪立方体的局部轴(通过使它们通过与立方体本身相同的旋转)。

您也可以在局部坐标系中工作,方法是按相反的顺序应用旋转,即围绕 Y 全局旋转 90,然后围绕 X 全局旋转 90 等同于 X 中的局部旋转然后 Y.