0

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.

JohanC
  • 71,591
  • 8
  • 33
  • 66
  • See also https://stackoverflow.com/questions/29800749/delaunay-triangulation-of-points-from-2d-surface-in-3d-with-python Basically, Delaunay on 3D points generates tetrahedra, not triangles. – JohanC May 18 '23 at 10:39
  • See also https://stackoverflow.com/q/49098466/2912349 for approaches using `ConvexHull` – Paul Brodersen May 18 '23 at 13:02

1 Answers1

0

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.

Stéphane Laurent
  • 75,186
  • 15
  • 119
  • 225