简体   繁体   English

有没有一种简单的方法可以在 plotly 中将 3d 网格旋转 90 度?

[英]Is there an easy way to rotate a 3d mesh by 90 degree in plotly?

I've created a 3d mesh in plotly using the plotly.graph_objects.Mesh3d function.我使用 plotly.graph_objects.Mesh3d ZC1C425268E18385D14AB504F 在 plotly 中创建了 3d 网格。 Please see the next picture.请看下一张图片。

在此处输入图像描述

Is there an easy way to rotate this 3d mesh by 90 degree?有没有一种简单的方法可以将这个 3d 网格旋转 90 度? Please see the next picture as an indication how I want to rotate.请看下一张图片作为我想如何旋转的指示。

在此处输入图像描述

Although I don't know how exactly you created the 3d mesh rectangular surface, I can recreate it by passing the x,y,z coordinates of the four corners of your surface, as well as the Delaunay axis to go.Mesh3d .虽然我不知道您究竟是如何创建 3d 网格矩形曲面的,但我可以通过将曲面四个角的 x、y、z 坐标以及 Delaunay 轴传递给go.Mesh3d来重新创建它。 The Delaunay axis tells Plotly the direction perpendicular to your surface in order to construct the mesh. Delaunay 轴告诉 Plotly 垂直于您的表面的方向,以便构建网格。 You could specify the Delaunay axis to be either 'x' or 'y' and the surface will be render correctly:您可以将 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()

在此处输入图像描述

When you rotate your plane so that lies parallel to the xy plane, the two original z-coordinates at the bottom of the plane will remain fixed, but the coordinates of the two new planes can be calculated using properties of perpendicular vectors.当您旋转平面以使其与 xy 平面平行时,平面底部的两个原始 z 坐标将保持固定,但可以使用垂直向量的属性计算两个新平面的坐标。

Consider the below diagram (vectors not drawn accurately but hopefully the following explanation makes sense).考虑下图(矢量未准确绘制,但希望以下解释有意义)。 When you rotate your 3d mesh plane down to z=436, the new blue vector must be perpendicular to the green vector and have a length of 5 (the same distance from 436 to 441 in the original 3d mesh plane you drew).当您将 3d 网格平面向下旋转到 z=436 时,新的蓝色矢量必须垂直于绿色矢量并且长度为 5(在您绘制的原始 3d 网格平面中从 436 到 441 的距离相同)。 The green vector can be decomposed into x and y components represented in red.绿色向量可以分解为红色表示的 x 和 y 分量。 If the green vector has direction (v_x, v_y) , then the blue vector will have direction (-v_y, v_x) .如果绿色向量具有方向(v_x, v_y) ,则蓝色向量将具有方向(-v_y, v_x) Then we can normalize this vector (divide by its length) and multiply it by 5 to get the final vector.然后我们可以对这个向量进行归一化(除以它的长度)并乘以 5 得到最终的向量。 Add this vector to points a and b and we get our new coordinates c and d .将此向量添加到点ab ,我们得到新的坐标cd

![在此处输入图像描述

Using some basic numpy operations to help us, we can translate the above into code ( a and b are the bottom coordinates of the mesh that will stay the same after rotation, and c and d are the new coordinates).使用一些基本的 numpy 操作来帮助我们,我们可以将上面的内容转换为代码( ab是网格的底部坐标,旋转后将保持不变, cd是新坐标)。 Also when you add the rotated 3d mesh, you'll want to change the Delaunay axis to z since the z-axis is perpendicular to our new surface:此外,当您添加旋转的 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()

在此处输入图像描述

If you add the newly rotated 3d mesh plane as a trace, you can see that the original and check that the two planes are indeed perpendicular:如果添加新旋转的 3d 网格平面作为迹线,可以看到原来的并检查两个平面确实垂直:

fig.add_trace(
    go.Mesh3d(
        x=x_new,
        y=y_new,
        z=z_new,
        delaunayaxis='z'
    )
)
    
fig.show()

在此处输入图像描述

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM