Как установить начало сетки с помощью mplot3d?

Следуя примеру в документе scikit-image, я создаю сферическую поверхностная сетка с алгоритмом марширующих кубов. Я хочу центрировать оболочку единичной сферы в начале координат, определяемом сеткой 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, как это следует из сетки?


person Armut    schedule 17.09.2018    source источник
comment
Функция из учебника называется measure.marching_cubes_lewiner и принимает два аргумента.   -  person ImportanceOfBeingErnest    schedule 18.09.2018
comment
@ImportanceOfBeingErnest: второй аргумент является необязательным для установки значений изоповерхностей. В marching_cubes по умолчанию используется алгоритм Левинера, поэтому оба варианта работают. Но я отредактировал вопрос, чтобы избежать путаницы.   -  person Armut    schedule 18.09.2018
comment
В моей версии skimage нет файла marching_cubes. Но код в его нынешнем виде должен работать; какую проблему вы испытываете?   -  person ImportanceOfBeingErnest    schedule 18.09.2018
comment
Я хочу, чтобы сфера была сосредоточена в 0,0,0. Я не знаю, как это сделать.   -  person Armut    schedule 18.09.2018


Ответы (1)


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()

введите здесь описание изображения

person ImportanceOfBeingErnest    schedule 17.09.2018
comment
Большое спасибо за ответ. Не могли бы вы подробнее рассказать об операциях над вершинами? Кстати, import numpy as np отсутствует. - person Armut; 18.09.2018