pythonmatplotlib3ddelaunay

Delaunay triangulation on a cube


I have to create a 3d cube with a set of points for school. But when I'm trying to use Delaunay triangulation I'm getting a bad result. Does anyone has any idea how to fix that ? I'm truly a beginner with this kind of tools, sorry if it's an obvious mistake.

import matplotlib.pyplot as plt
from scipy.spatial import Delaunay
import numpy as np

ax = plt.axes(projection='3d')
ax.view_init(15, -30)
points = np.vstack([x, y, z]).T
tri = Delaunay(points)
ax.plot_trisurf(x,y,z, triangles = tri.simplices ,
    linewidth=0.5, facecolors='cyan', linewidths=1, edgecolors='r', alpha=.70, antialiased=True)

Cloud point: Cloud Point

Once triangulated: Once triangulated

I already tried changing some parameters in the Delaunay function but nothing seems to work.


Solution

  • A Delaunay tessellation generates simplices: triangles in dimension 2, tetrahedra in dimension 3. So here you get tetrahedra. You can extract their faces (triangles) and then proceed with ax.plot_trisurf.

    import matplotlib.pyplot as plt
    from scipy.spatial import Delaunay
    import numpy as np
    
    # extract the four triangular faces of a tetrahedron
    def simplex2triangles(sx):
        return np.array([
          [sx[0], sx[1], sx[2]],  
          [sx[0], sx[1], sx[3]],  
          [sx[0], sx[2], sx[3]],  
          [sx[1], sx[2], sx[3]]  
        ])
    
    # cube vertices
    points= np.array([
        [0,0,0],
        [4,0,0],
        [4,4,0],
        [0,4,0],
        [0,0,4],
        [4,0,4],
        [4,4,4],
        [0,4,4]
    ])
    
    # apply Delaunay tetrahedralization
    tri = Delaunay(points)
    # extract tetrahedra
    tetrahedra = tri.simplices
    # extract all triangles
    triangles = np.vstack(np.apply_along_axis(simplex2triangles, 1, tri.simplices))
    # there are duplicated triangles, remove them (remark: it could remain some dups up to the order...)
    triangles = np.unique(triangles, axis = 0)
    
    # plot
    x = points[:, 0]
    y = points[:, 1]
    z = points[:, 2]
    ax = plt.axes(projection='3d')
    ax.view_init(15, -30)
    ax.plot_trisurf(x, y, z, triangles = triangles, 
        linewidth=0.5, linewidths=1, edgecolors='r', alpha=.70, antialiased=True)
    

    I don't know why facecolors does not work.

    enter image description here Also note I'm rather novice in Python.