有没有一种简单的方法可以将 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 得到最终的向量。将此向量添加到点 ab,我们得到新坐标 cd.

使用一些基本的 numpy 操作来帮助我们,我们可以将上面的内容转化为代码(ab 是网格的底部坐标,旋转后将保持不变,cd 是新坐标)。此外,当您添加旋转的 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()