有没有一种简单的方法可以将 3d 网格旋转 90 度?
Is there an easy way to rotate a 3d mesh by 90 degree in plotly?
我使用 plotly.graph_objects.Mesh3d 函数在 plotly 中创建了一个 3d 网格。请看下图
有没有简单的方法可以将这个 3d 网格旋转 90 度?请参阅下一张图片作为我想要旋转的指示。
虽然我不知道您是如何创建 3d 网格矩形表面的,但我可以通过将表面四个角的 x、y、z 坐标以及 Delaunay 轴传递给 go.Mesh3d
。 Delaunay 轴告诉 Plotly 垂直于您的表面的方向,以便构建网格。您可以将 Delaunay 轴指定为 'x'
或 'y'
并且表面将正确渲染:
import plotly.graph_objects as go
x = [11.5,11.5,14.5,14.5]
y = [19,19,13,13]
z = [436,441,436,441]
fig = go.Figure(data=[
go.Mesh3d(
x=x,
y=y,
z=z,
delaunayaxis='y'
)
])
fig.show()
当您旋转平面使其平行于xy平面时,平面底部的两个原始z坐标将保持不变,但可以使用垂直属性计算两个新平面的坐标向量。
考虑下图(未准确绘制矢量,但希望以下解释有意义)。当您将 3d 网格平面向下旋转到 z=436 时,新的蓝色矢量必须垂直于绿色矢量并且长度为 5(与您绘制的原始 3d 网格平面中从 436 到 441 的距离相同)。绿色向量可以分解为用红色表示的 x 和 y 分量。如果绿色向量的方向为(v_x, v_y)
,那么蓝色向量的方向为(-v_y, v_x)
。然后我们可以将这个向量归一化(除以它的长度)并将它乘以 5 得到最终的向量。将此向量添加到点 a
和 b
,我们得到新坐标 c
和 d
.
使用一些基本的 numpy 操作来帮助我们,我们可以将上面的内容转化为代码(a
和 b
是网格的底部坐标,旋转后将保持不变,c
和 d
是新坐标)。此外,当您添加旋转的 3d 网格时,您需要将 Delaunay 轴更改为 z,因为 z 轴垂直于我们的新表面:
import numpy as np
## make points a and b the bottom two points
a = np.array((x[0], y[0], z[0]))
b = np.array((x[2], y[2], z[2]))
v = b-a
## create a perpendicular unit vector
v_perp_unit = np.array([-1*v[1], v[0], v[2]]) / np.linalg.norm(v)
v_length = max(z) - min(z)
v_perp = v_length*v_perp_unit
## calculate the coordinates of the final two points
c = a+v_perp
d = b+v_perp
x_new = [a[0],b[0],c[0],d[0]]
y_new = [a[1],b[1],c[1],d[1]]
z_new = [a[2],b[2],c[2],d[2]]
fig = go.Figure(data=[
go.Mesh3d(
x=x_new,
y=y_new,
z=z_new,
delaunayaxis='z'
)
])
fig.show()
如果将新旋转的 3d 网格平面添加为跟踪,则可以看到原始平面并检查两个平面是否确实垂直:
fig.add_trace(
go.Mesh3d(
x=x_new,
y=y_new,
z=z_new,
delaunayaxis='z'
)
)
fig.show()
我使用 plotly.graph_objects.Mesh3d 函数在 plotly 中创建了一个 3d 网格。请看下图
有没有简单的方法可以将这个 3d 网格旋转 90 度?请参阅下一张图片作为我想要旋转的指示。
虽然我不知道您是如何创建 3d 网格矩形表面的,但我可以通过将表面四个角的 x、y、z 坐标以及 Delaunay 轴传递给 go.Mesh3d
。 Delaunay 轴告诉 Plotly 垂直于您的表面的方向,以便构建网格。您可以将 Delaunay 轴指定为 'x'
或 'y'
并且表面将正确渲染:
import plotly.graph_objects as go
x = [11.5,11.5,14.5,14.5]
y = [19,19,13,13]
z = [436,441,436,441]
fig = go.Figure(data=[
go.Mesh3d(
x=x,
y=y,
z=z,
delaunayaxis='y'
)
])
fig.show()
当您旋转平面使其平行于xy平面时,平面底部的两个原始z坐标将保持不变,但可以使用垂直属性计算两个新平面的坐标向量。
考虑下图(未准确绘制矢量,但希望以下解释有意义)。当您将 3d 网格平面向下旋转到 z=436 时,新的蓝色矢量必须垂直于绿色矢量并且长度为 5(与您绘制的原始 3d 网格平面中从 436 到 441 的距离相同)。绿色向量可以分解为用红色表示的 x 和 y 分量。如果绿色向量的方向为(v_x, v_y)
,那么蓝色向量的方向为(-v_y, v_x)
。然后我们可以将这个向量归一化(除以它的长度)并将它乘以 5 得到最终的向量。将此向量添加到点 a
和 b
,我们得到新坐标 c
和 d
.
使用一些基本的 numpy 操作来帮助我们,我们可以将上面的内容转化为代码(a
和 b
是网格的底部坐标,旋转后将保持不变,c
和 d
是新坐标)。此外,当您添加旋转的 3d 网格时,您需要将 Delaunay 轴更改为 z,因为 z 轴垂直于我们的新表面:
import numpy as np
## make points a and b the bottom two points
a = np.array((x[0], y[0], z[0]))
b = np.array((x[2], y[2], z[2]))
v = b-a
## create a perpendicular unit vector
v_perp_unit = np.array([-1*v[1], v[0], v[2]]) / np.linalg.norm(v)
v_length = max(z) - min(z)
v_perp = v_length*v_perp_unit
## calculate the coordinates of the final two points
c = a+v_perp
d = b+v_perp
x_new = [a[0],b[0],c[0],d[0]]
y_new = [a[1],b[1],c[1],d[1]]
z_new = [a[2],b[2],c[2],d[2]]
fig = go.Figure(data=[
go.Mesh3d(
x=x_new,
y=y_new,
z=z_new,
delaunayaxis='z'
)
])
fig.show()
如果将新旋转的 3d 网格平面添加为跟踪,则可以看到原始平面并检查两个平面是否确实垂直:
fig.add_trace(
go.Mesh3d(
x=x_new,
y=y_new,
z=z_new,
delaunayaxis='z'
)
)
fig.show()