Triángulo de superficie de retorno de scipy.spatial.Delaunay 3D

Tengo este problema Intento triangular puntos de nube por scipy.spatial.Delaunay. Solía:

tri = Delaunay(points) # points: np.array() of 3d points indices = tri.simplices vertices = points[indices] 

Pero, este código devuelve el tetraedro. ¿Cómo es posible volver triángulo de superficie solamente?

Gracias

Para que funcione como código, debe parametrizar la superficie a 2D. Por ejemplo, en el caso de la bola (r, theta, psi), el radio es constante (descartarlo) y los puntos están dados por (theta, psi) que es 2D.

Scipy Delaunay es una triangulación tridimensional, por lo que si asigna puntos 3D, devolverá objetos 3D. Dale puntos 2D y devuelve objetos 2D.

A continuación se muestra un script que utilicé para crear poliedros para openSCAD. U y V son mi parametrización (xey) y estas son las coordenadas que le doy a Delaunay. Tenga en cuenta que ahora las “propiedades de triangulación de Delaunay” se aplican solo en las coordenadas u, v (los angularjs se maximizan en uv -space no xyz -space, etc.).

El ejemplo es una copia modificada de http://matplotlib.org/1.3.1/mpl_toolkits/mplot3d/tutorial.html que originalmente usa la función de triangulación (¿mapas a Delaunay eventualmente?)

 import numpy as np import matplotlib.pyplot as plt from mpl_toolkits.mplot3d import Axes3D import matplotlib.tri as mtri from scipy.spatial import Delaunay # u, v are parameterisation variables u = np.array([0,0,0.5,1,1]) v = np.array([0,1,0.5,0,1]) x = u y = v z = np.array([0,0,1,0,0]) # Triangulate parameter space to determine the triangles #tri = mtri.Triangulation(u, v) tri = Delaunay(np.array([u,v]).T) print 'polyhedron(faces = [' #for vert in tri.triangles: for vert in tri.simplices: print '[%d,%d,%d],' % (vert[0],vert[1],vert[2]), print '], points = [' for i in range(x.shape[0]): print '[%f,%f,%f],' % (x[i], y[i], z[i]), print ']);' fig = plt.figure() ax = fig.add_subplot(1, 1, 1, projection='3d') # The triangles in parameter space determine which x, y, z points are # connected by an edge #ax.plot_trisurf(x, y, z, triangles=tri.triangles, cmap=plt.cm.Spectral) ax.plot_trisurf(x, y, z, triangles=tri.simplices, cmap=plt.cm.Spectral) plt.show() 

Pirámide lo que el ejemplo anterior traza

A continuación se muestra la salida de texto (ligeramente más estructurada):

 polyhedron( faces = [[2,1,0], [3,2,0], [4,2,3], [2,4,1], ], points = [[0.000000,0.000000,0.000000], [0.000000,1.000000,0.000000], [0.500000,0.500000,1.000000], [1.000000,0.000000,0.000000], [1.000000,1.000000,0.000000], ]); 

Parece que quieres calcular el casco convexo de tu nube de puntos. Creo que esto es lo que quieres hacer:

 from scipy.spatial import ConvexHull hull = ConvexHull(points) indices = hull.simplices vertices = points[indices] 

Siguiendo la respuesta de Jaime, pero elaborando un poco más con un ejemplo:

 import matplotlib as mpl import matplotlib.pyplot as plt import mpl_toolkits.mplot3d as a3 import numpy as np import scipy as sp from scipy import spatial as sp_spatial def icosahedron(): h = 0.5*(1+np.sqrt(5)) p1 = np.array([[0, 1, h], [0, 1, -h], [0, -1, h], [0, -1, -h]]) p2 = p1[:, [1, 2, 0]] p3 = p1[:, [2, 0, 1]] return np.vstack((p1, p2, p3)) def cube(): points = np.array([ [0, 0, 0], [0, 0, 1], [0, 1, 0], [0, 1, 1], [1, 0, 0], [1, 0, 1], [1, 1, 0], [1, 1, 1], ]) return points points = icosahedron() # points = cube() hull = sp_spatial.ConvexHull(points) indices = hull.simplices faces = points[indices] print('area: ', hull.area) print('volume: ', hull.volume) fig = plt.figure() ax = fig.add_subplot(111, projection='3d') ax.dist = 30 ax.azim = -140 ax.set_xlim([0, 2]) ax.set_ylim([0, 2]) ax.set_zlim([0, 2]) ax.set_xlabel('x') ax.set_ylabel('y') ax.set_zlabel('z') for f in faces: face = a3.art3d.Poly3DCollection([f]) face.set_color(mpl.colors.rgb2hex(sp.rand(3))) face.set_edgecolor('k') face.set_alpha(0.5) ax.add_collection3d(face) plt.show() 

Que debe representar la siguiente figura:

introduzca la descripción de la imagen aquí