Ошибка при рендеринге 3d-куба с помощью matplotlib - PullRequest
0 голосов
/ 09 октября 2018

Я хочу визуализировать 3D-куб, используя matplotlib.Куб отображается, но при определенных направлениях наблюдаются глюки: enter image description here

Пурпурная сторона кровоточит при взгляде спереди.Как я могу это исправить?

Это мой код:

import numpy as np
import math
from matplotlib import pyplot as plt
from mpl_toolkits.mplot3d.art3d import Poly3DCollection, Line3DCollection

a=0.5
cube = np.array([
[-a,-a,-a], \
[+a,-a,-a], \
[+a,+a,-a], \
[-a,+a,-a], \
            \
[-a,-a,+a], \
[+a,-a,+a], \
[+a,+a,+a], \
[-a,+a,+a]  \
])

bottom = [0,1,2,3]
top    = [4,5,6,7]
front  = [0,1,5,4]
right  = [1,2,6,5]
back   = [2,3,7,6]
left   = [0,3,7,4]

def rotation(theta = np.random.random_sample(3) * math.pi * 2, R = np.zeros((3,3))):
    cx,cy,cz = np.cos(theta)
    sx,sy,sz = np.sin(theta)
    R.flat = (cx*cz - sx*cy*sz, cx*sz + sx*cy*cz, sx*sy,
        -sx*cz - cx*cy*sz, -sx*sz + cx*cy*cz,
        cx*sy, sy*sz, -sy*cz, cy)
    return R 

def render_rotation(rot):
    fig = plt.figure()
    ax = fig.add_subplot(111, projection='3d')
    ax.view_init(elev=0, azim=0)
    ax.grid(False)
    plt.axis('off')
    ax.set_proj_type('persp')
    # rotate cube
    rotated=np.linalg.linalg.dot(rotation(rot), cube.transpose()).transpose()
    def render_side(idx, clr):
        ax.add_collection3d(Poly3DCollection([
            [rotated[idx[0]]+a, rotated[idx[1]]+a, rotated[idx[2]]+a, rotated[idx[3]]+a]
        ], facecolors=clr, linewidths=0)) 
    render_side(top   , 'red')
    render_side(front , 'green')
    render_side(right , 'blue')
    render_side(bottom, 'cyan')
    render_side(back  , 'magenta')
    render_side(left  , 'yellow')
    plt.show()
    plt.close()
render_rotation(np.array([0,0,0]))

Редактировать: Комментарий ImportanceOfBeingErnest был решением.

Я простопришлось немного изменить мою функцию рендеринга:

clrs=[]
verts=[]
def render_side(idx, clr):
    clrs.append(clr)
    verts.append([
        rotated[idx[0]]+a, 
        rotated[idx[1]]+a, 
        rotated[idx[2]]+a, 
        rotated[idx[3]]+a])
render_side(top   , 'red')
render_side(front , 'green')
render_side(right , 'blue')
render_side(bottom, 'cyan')
render_side(back  , 'magenta')
render_side(left  , 'yellow')
ax.add_collection3d(Poly3DCollection(verts, facecolors=clrs, linewidths=0)) 

1 Ответ

0 голосов
/ 14 октября 2018

Комментарий ImportanceOfBeingErnest был решением.Исправление для render_rotation использует только один Poly3DCollection:

def render_rotation(rot):
    fig = plt.figure()
    ax = fig.add_subplot(111, projection='3d')
    ax.view_init(elev=0, azim=0)
    ax.grid(False)
    plt.axis('off')
    ax.set_proj_type('persp')
    # rotate cube
    clrs=[]
    verts=[]
    def render_side(idx, clr):
        clrs.append(clr)
        verts.append([
            rotated[idx[0]]+a, 
            rotated[idx[1]]+a, 
            rotated[idx[2]]+a, 
            rotated[idx[3]]+a])
    render_side(top   , 'red')
    render_side(front , 'green')
    render_side(right , 'blue')
    render_side(bottom, 'cyan')
    render_side(back  , 'magenta')
    render_side(left  , 'yellow')
    ax.add_collection3d(Poly3DCollection(verts, facecolors=clrs, linewidths=0)) 
    plt.show()
    plt.close()
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...