我想在没有循环的情况下在两次(X 和 Y)旋转后找到立方体的坐标。
立方体坐标存储为顶点:
cube_vertices = np.array([[0, 0, 0],
[1, 0, 0],
[1, 1, 0],
[0, 1, 0],
[0, 0, 1],
[1, 0, 1],
[0, 1, 1],
[1, 1, 1]])
并且我主要使用边:
cube_edges = np.array([[cube_vertices[0], cube_vertices[1]],
[cube_vertices[0], cube_vertices[3]],
[cube_vertices[1], cube_vertices[2]],
[cube_vertices[3], cube_vertices[2]],
[cube_vertices[1], cube_vertices[5]],
[cube_vertices[2], cube_vertices[7]],
[cube_vertices[3], cube_vertices[6]],
[cube_vertices[0], cube_vertices[4]],
[cube_vertices[4], cube_vertices[5]],
[cube_vertices[4], cube_vertices[6]],
[cube_vertices[6], cube_vertices[7]],
[cube_vertices[5], cube_vertices[7]]])
我存储它来查找交点这些边缘带有平面。旋转器给出为每个坐标
cube_edges
重复 12 次旋转,因此我可以沿尺寸为 12(边数)的第 0 轴和尺寸为 2(边的两端)的第 1 轴相乘坐标:
phi, theta = 0.1, 0.1
Rx = np.tile(np.array([[1, 0, 0],
[0, np.cos(theta), -np.sin(theta)],
[0, np.sin(theta), np.cos(theta)]]), (12, 2, 1, 1))
Ry = np.tile(np.array([[np.cos(phi), 0, np.sin(phi)],
[0, 1, 0],
[-np.sin(phi), 0, np.cos(phi)]]), (12, 2, 1, 1))
Rxy = Rx * Ry
cube_edges
的形状是
(12, 2, 3)
,
Rxy
的形状是
(12, 2, 3, 3)
对于大小为 (3) 的每点坐标的所有 3x3 单旋转,乘法应沿前两个维度 (12, 2) 进行。我不知道如何利用 np.tensordot 或类似的东西来达到此目的:
rotated_edges = np.tensordot(Rxy, cube_edges)
结果形状
rotated_edges
应该与
cube_edges
(12, 2, 3)
相同。
谢谢!
可以使用 NumPy 的广播和点积来实现这一点,而无需使用
tensordot
。方法如下:
import numpy as np
# 立方体顶点和边(你的代码)
cube_vertices = np.array([[0, 0, 0],
[1, 0, 0],
[1, 1, 0],
[0, 1, 0],
[0, 0, 1],
[1, 0, 1],
[0, 1, 1],
[1, 1, 1]])
cube_edges = np.array([[cube_vertices[0], cube_vertices[1]],
[cube_vertices[0], cube_vertices[3]],
[cube_vertices[1], cube_vertices[2]],
[cube_vertices[3], cube_vertices[2]],
[cube_vertices[1], cube_vertices[5]],
[cube_vertices[2], cube_vertices[7]],
[cube_vertices[3], cube_vertices[6]],
[cube_vertices[0], cube_vertices[4]],
[cube_vertices[4], cube_vertices[5]],
[cube_vertices[4], cube_vertices[6]],
[cube_vertices[6], cube_vertices[7]],
[cube_vertices[5], cube_vertices[7]]])
# 旋转矩阵(你的代码)
phi, theta = 0.1, 0.1
Rx = np.tile(np.array([[1, 0, 0],
[0, np.cos(theta), -np.sin(theta)],
[0, np.sin(theta), np.cos(theta)]]), (12, 2, 1, 1))
Ry = np.tile(np.array([[np.cos(phi), 0, np.sin(phi)],
[0, 1, 0],
[-np.sin(phi), 0, np.cos(phi)]]), (12, 2, 1, 1))
Rxy = Rx * Ry
# 使用广播进行矩阵乘法
rotated_edges = np.sum(Rxy * cube_edges[:, :, np.newaxis, :], axis=3)
# 打印结果形状
print(rotated_edges.shape) # 输出: (12, 2, 3)
说明:
-
广播:
cube_edges[:, :, np.newaxis, :]
将cube_edges
的形状从(12, 2, 3)
扩展为(12, 2, 1, 3)
。这允许它与形状为(12, 2, 3, 3)
的Rxy
进行广播,从而执行元素乘法,有效地将每个 3x3 旋转矩阵应用于cube_edges
中的相应点。 -
点积:
np.sum(..., axis=3)
沿最后一个轴 (axis=3
) 计算点积,这对应于矩阵乘法中的求和运算。
最终结果是
rotated_edges
数组,其形状为
(12, 2, 3)
,包含旋转后的边坐标。