1

I'm playing a bit with scikit-image marching cubes algorithm. Here is a simplified version of the example given in the docs.

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


x = np.linspace(-1, 1, 11)

X, Y, Z = np.meshgrid(x, x, x, indexing = 'ij')

def f(x, y, z):
    return x

verts, faces = measure.marching_cubes(f(X, Y, Z), 0.6)

fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')

mesh = Poly3DCollection(verts[faces])
ax.add_collection3d(mesh)

ax.set_xlim(0, 10)
ax.set_ylim(0, 10)
ax.set_zlim(0, 10)

plt.show()

Here is the resulting surface:

enter image description here

It appears that coordinates of vertices are given in terms of array index rather than coordinates of the meshgrid. How can I transform the coordinates of vertices so that they map to the meshgrid, like in the image below?

enter image description here

I can do that by hand:

mesh = Poly3DCollection((verts[faces] / 5) - 1)

but there must be some numpy magic here.

Thanks.

1 Answer 1

2

IMHO, no magic here. There is no 'plug and play' transformations in mplot3d.

for automation, you can just make your 'by hand' job with a function :

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

x=y=z= np.linspace(-1, 1, 11)

grid=np.meshgrid(x,y,z)

def f(x, y, z):
    return x*x+y*y+z*z   # more fun ;)

def scale_marching(x,verts):
    return x[0]+ (x[-1]-x[0])/len(x)*verts

verts, faces = measure.marching_cubes(f(*grid), 1.5)    
verts=scale_marching(x,verts)

ax = plt.figure().add_subplot(111, projection='3d') 
ax.add_collection3d(Poly3DCollection(verts[faces]))
ax.auto_scale_xyz(*grid)

holes

Sign up to request clarification or add additional context in comments.

1 Comment

This is what I've done (more general) def scale_marching(verts, x, y, z): verts[:,0] = x[0] + (x[-1] - x[0]) / (len(x) - 1) * verts[:,0] verts[:,1] = y[0] + (y[-1] - y[0]) / (len(y) - 1) * verts[:,1] verts[:,2] = z[0] + (z[-1] - z[0]) / (len(z) - 1) * verts[:,2]. Note len(x) - 1.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.