Reputation: 5071
I would like to visualize 3 polyhedrons defined by 3 numpy arrays of shape (8, 3).
I am looking for something like that:
My data are the following:
A = np.array([[0.92523719, 0.26843252, 0.77794309],
[0.73156748, 0.27794309, 0.57476281],
[0.62113842, 0.37886158, 0.87886158],
[0.72205691, 0.07476281, 0.76843252],
[0.57476281, 0.23156748, 0.72205691],
[0.77794309, 0.42523719, 0.73156748],
[0.87886158, 0.12113842, 0.62113842],
[0.76843252, 0.22205691, 0.92523719]])
B = np.array([[0.23156748, 0.72205691, 0.57476281],
[0.26843252, 0.77794309, 0.92523719],
[0.12113842, 0.62113842, 0.87886158],
[0.22205691, 0.92523719, 0.76843252],
[0.27794309, 0.57476281, 0.73156748],
[0.37886158, 0.87886158, 0.62113842],
[0.07476281, 0.76843252, 0.72205691],
[0.42523719, 0.73156748, 0.77794309]])
C = np.array([[0.73156748, 0.77794309, 0.42523719],
[0.62113842, 0.87886158, 0.12113842],
[0.77794309, 0.92523719, 0.26843252],
[0.57476281, 0.73156748, 0.27794309],
[0.87886158, 0.62113842, 0.37886158],
[0.72205691, 0.57476281, 0.23156748],
[0.76843252, 0.72205691, 0.07476281],
[0.92523719, 0.76843252, 0.22205691]])
Upvotes: 3
Views: 4561
Reputation: 80439
You seem to have points in 3D, but no edge nor polygon information. Supposing the polyhedra are convex, scipy.spatial
's ConvexHull
can find all the polygons on the convex hull. The convex hull exists of triangles that can be added to a 3D plot as a Poly3DCollection
.
from mpl_toolkits.mplot3d.art3d import Poly3DCollection
from mpl_toolkits.mplot3d import Axes3D
from matplotlib import pyplot as plt
import numpy as np
from scipy.spatial import ConvexHull
A = np.array([[0.92523719, 0.26843252, 0.77794309], [0.73156748, 0.27794309, 0.57476281], [0.62113842, 0.37886158, 0.87886158], [0.72205691, 0.07476281, 0.76843252], [0.57476281, 0.23156748, 0.72205691], [0.77794309, 0.42523719, 0.73156748], [0.87886158, 0.12113842, 0.62113842], [0.76843252, 0.22205691, 0.92523719]])
B = np.array([[0.23156748, 0.72205691, 0.57476281], [0.26843252, 0.77794309, 0.92523719], [0.12113842, 0.62113842, 0.87886158], [0.22205691, 0.92523719, 0.76843252], [0.27794309, 0.57476281, 0.73156748], [0.37886158, 0.87886158, 0.62113842], [0.07476281, 0.76843252, 0.72205691], [0.42523719, 0.73156748, 0.77794309]])
C = np.array([[0.73156748, 0.77794309, 0.42523719], [0.62113842, 0.87886158, 0.12113842], [0.77794309, 0.92523719, 0.26843252], [0.57476281, 0.73156748, 0.27794309], [0.87886158, 0.62113842, 0.37886158], [0.72205691, 0.57476281, 0.23156748], [0.76843252, 0.72205691, 0.07476281], [0.92523719, 0.76843252, 0.22205691]])
fig = plt.figure()
ax = fig.add_subplot(111, projection="3d")
for cube, color in zip([A, B, C], ['r', 'g', 'b']):
hull = ConvexHull(cube)
# draw the polygons of the convex hull
for s in hull.simplices:
tri = Poly3DCollection([cube[s]])
tri.set_color(color)
tri.set_alpha(0.5)
ax.add_collection3d(tri)
# draw the vertices
ax.scatter(cube[:, 0], cube[:, 1], cube[:, 2], marker='o', color='purple')
plt.show()
Supposing the longest side of each triangle is a face diagonal of the cube, we could search for the two shortest sides and draw them in black:
from mpl_toolkits.mplot3d.art3d import Poly3DCollection
from mpl_toolkits.mplot3d import Axes3D
from matplotlib import pyplot as plt
import numpy as np
from scipy.spatial import ConvexHull, distance
A = np.array([[0.92523719, 0.26843252, 0.77794309], [0.73156748, 0.27794309, 0.57476281], [0.62113842, 0.37886158, 0.87886158], [0.72205691, 0.07476281, 0.76843252], [0.57476281, 0.23156748, 0.72205691], [0.77794309, 0.42523719, 0.73156748], [0.87886158, 0.12113842, 0.62113842], [0.76843252, 0.22205691, 0.92523719]])
B = np.array([[0.23156748, 0.72205691, 0.57476281], [0.26843252, 0.77794309, 0.92523719], [0.12113842, 0.62113842, 0.87886158], [0.22205691, 0.92523719, 0.76843252], [0.27794309, 0.57476281, 0.73156748], [0.37886158, 0.87886158, 0.62113842], [0.07476281, 0.76843252, 0.72205691], [0.42523719, 0.73156748, 0.77794309]])
C = np.array([[0.73156748, 0.77794309, 0.42523719], [0.62113842, 0.87886158, 0.12113842], [0.77794309, 0.92523719, 0.26843252], [0.57476281, 0.73156748, 0.27794309], [0.87886158, 0.62113842, 0.37886158], [0.72205691, 0.57476281, 0.23156748], [0.76843252, 0.72205691, 0.07476281], [0.92523719, 0.76843252, 0.22205691]])
fig = plt.figure()
ax = fig.add_subplot(111, projection="3d")
for cube, color in zip([A, B, C], ['r', 'g', 'b']):
hull = ConvexHull(cube)
for s in hull.simplices:
tri = Poly3DCollection([cube[s]])
tri.set_color(color)
tri.set_alpha(0.5)
tri.set_edgecolor('none')
ax.add_collection3d(tri)
edges = []
if distance.euclidean(cube[s[0]], cube[s[1]]) < distance.euclidean(cube[s[1]], cube[s[2]]):
edges.append((s[0], s[1]))
if distance.euclidean(cube[s[1]], cube[s[2]]) < distance.euclidean(cube[s[2]], cube[s[0]]):
edges.append((s[1], s[2]))
else:
edges.append((s[2], s[0]))
else:
edges.append((s[1], s[2]))
if distance.euclidean(cube[s[0]], cube[s[1]]) < distance.euclidean(cube[s[2]], cube[s[0]]):
edges.append((s[0], s[1]))
else:
edges.append((s[2], s[0]))
for v0, v1 in edges:
ax.plot(xs=cube[[v0, v1], 0], ys=cube[[v0, v1], 1], zs=cube[[v0, v1], 2], color='black')
ax.scatter(cube[:, 0], cube[:, 1], cube[:, 2], marker='o', color='purple')
plt.show()
Upvotes: 10