Как визуализировать многогранники, определенные их вершинами, в 3D с помощью matplotlib и / или графика в автономном режиме? - PullRequest
1 голос
/ 01 августа 2020

Я хотел бы визуализировать 3 многогранника, определяемых 3 numpy массивами формы (8, 3).

Я ищу что-то вроде этого:

введите описание изображения здесь

Мои данные следующие:

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]])

1 Ответ

2 голосов
/ 01 августа 2020

Кажется, что у вас есть точки в 3D, но нет информации о краях и полигонах. Предположим, что многогранники выпуклые, scipy.spatial s ConvexHull может найти все многоугольники на выпуклой оболочке. Выпуклая оболочка состоит из треугольников, которые можно добавить к трехмерному графику как 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()

3D plot

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()

ребра куба

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...