如何使用mplot3d为网格设置原点?

3

根据 scikit-image 文档 中的示例,我使用 marching cubes 算法生成了一个球形表面网格。我希望将单位球壳居中放置在由 x、y、z 网格定义的原点上。然而,我无法做到这一点,因为我不知道如何将 x、y、z 信息与 mpl_toolkits.mplot3d.art3d.Poly3DCollection 结合使用。以下是代码:

import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d.art3d import Poly3DCollection
from skimage import measure
import numpy as np

x, y, z = np.ogrid[-4:4:20j, -4:4:20j, -4:4:20j]
r = np.sqrt(x ** 2 + y ** 2 + z ** 2)
verts, faces, normals, values = measure.marching_cubes_lewiner(r,level=1)
fig = plt.figure(figsize=(10, 10))
ax = fig.add_subplot(111, projection='3d')
mesh = Poly3DCollection(verts[faces])
mesh.set_edgecolor('k')
ax.add_collection3d(mesh)
plt.show()

问题在于marching_cubes_lewiner函数没有考虑x,y,z。我该如何将生成的球体置于0,0,0处,与网格暗示的位置一致?

教程中的函数名为measure.marching_cubes_lewiner,它需要两个参数。 - ImportanceOfBeingErnest
@ImportanceOfBeingErnest:第二个参数是可选的,用于设置等值面的值。marching_cubes默认使用lewiner算法,所以两者都可以。但是,我编辑了问题以避免混淆。 - Armut
我的skimage版本没有marching_cubes。但是现在的代码应该可以工作;你遇到了什么问题? - ImportanceOfBeingErnest
我希望球体居中于0,0,0。我不知道如何做到这一点。 - Armut
1个回答

3
measure.marching_cubes_lewiner函数需要用到网格中的点索引来计算拓扑结构,但它似乎没有提供指定实际网格或偏移量的方法。
因此,您可以按照需要操作生成的verts。例如,您可以首先将其乘以网格点之间的差异,从而有效地缩放输出,然后再加上网格的偏移量。在这种情况下,转换公式为newverts = 0.42105 * oldverts - 4
import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d.art3d import Poly3DCollection
from skimage import measure

x, y, z = np.ogrid[-4:4:20j, -4:4:20j, -4:4:20j]
r = np.sqrt(x ** 2 + y ** 2 + z ** 2)

verts, faces, normals, values = measure.marching_cubes_lewiner(r, level=1)

verts *= np.array([np.diff(ar.flat)[0] for ar in [x,y,z]])
verts += np.array([x.min(),y.min(),z.min()])

fig = plt.figure(figsize=(10, 10))
ax = fig.add_subplot(111, projection='3d')
mesh = Poly3DCollection(verts[faces])
mesh.set_edgecolor('k')
ax.add_collection3d(mesh)
ax.set_xlim(-2, 2) 
ax.set_ylim(-2, 2)
ax.set_zlim(-2, 2)
plt.show()

enter image description here


非常感谢您的回答。您能详细说明一下关于顶点的操作吗?另外,代码中缺少 import numpy as np - Armut

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接