2014-09-05 113 views
0

我在三維空間繪製了點繪圖,四個多邊形以與y和x軸成角度的方式切割數據立方體。在3d座標周圍繪製多邊形,同時也圍繞着框包圍

我想,對於盒子中的每個黑色數據點,計算以數據點爲中心的正方形頂點的座標。使用這些座標,我可以繪製一個polgyon,就像我現在所做的一樣。這個正方形的尺寸需要與第7行定義的寬度值相同。繪製的正方形必須是傾斜的,因此它正好位於現有的繪製平面上。

有沒有人知道最好的方法來解決這個問題?另一個困難的事情是,如果廣場離開盒子,它應該包裹在盒子的另一邊。盒子可以水平和垂直疊放在相同的盒子裏,無限地鋪瓷磚。

我的代碼可以belw發現(對不起它的混亂):

import matplotlib.pyplot as pyplot 
import numpy as np 
from mpl_toolkits.mplot3d import Axes3D 
from mpl_toolkits.mplot3d.art3d import Poly3DCollection 

angle = np.arctan2(1,4) 
xangle = np.arctan2(1,4) 
width = 100/np.cos(angle) 
print 'angle:', angle*(180/np.pi) 
print 'xangle:', xangle*(180/np.pi) 
print 'width:', width 

x1  = [0, 0, 0, 0, 50, 50, 50, 50] 
y1  = [50,50,50,50,50,50,50,50] 
z1  = [12.5,37.5,62.5,87.5,25,50,75,0] 

x2 = [0,0,0,0,0,0,0,0,50,50,50,50,50,50,50,50] 
y2 = [0,50,0,50,0,50,0,50,0,50,0,50,0,50,0,50] 
z2 = [0,12.5,25,37.5,50,62.5,75,87.5,12.5,25,37.5,50,62.5,75,87.5,0] 

fig = pyplot.figure() 
ax = fig.add_subplot(111, projection = '3d') 

ax.set_xlim(0,100) 
ax.set_ylim(0,100) 
ax.set_zlim(0,100) 
ax.set_xlabel('X') 
ax.set_ylabel('Y') 
ax.set_zlabel('Z') 
#ax.view_init(elev=90, azim=90) 
#ax.scatter(x1, y1, z1, zdir='z', s=20, c='g') 
ax.scatter(x2, y2, z2, zdir='z', s=20, c='r') #THESE ARE RICHARD'S COORDINATES notice how they do not lie on the plane 

xa = [0,100,100,0] 
ya = [0,0,100,100] 
za = [0,-6.25,18.75,25] 
verts = [zip(xa,ya,za)] 
ax.add_collection3d(Poly3DCollection(verts)) 

xb = [0,100,100,0] 
yb = [0,0,100,100] 
zb = [25,-6.25+25,18.75+25,50] 
verts = [zip(xb,yb,zb)] 
ax.add_collection3d(Poly3DCollection(verts)) 

xc = [0,100,100,0] 
yc = [0,0,100,100] 
zc = [50,-6.25+25*2,18.75+25*2,75] 
verts = [zip(xc,yc,zc)] 
ax.add_collection3d(Poly3DCollection(verts)) 

xd = [0,100,100,0] 
yd = [0,0,100,100] 
zd = [75,-6.25+25*3,18.75+25*3,100] 
verts = [zip(xd,yd,zd)] 
ax.add_collection3d(Poly3DCollection(verts)) 

#pyplot.show()  

x = [0] 
y = [0] 
z = [0] 
for i in range(1,100): 
    new_x = x[(len(x)-1)] + 50 
    new_y = y[(len(y)-1)] + 12.5 
    new_z = z[(len(z)-1)] 



    if new_x >= 100: 
     new_x = new_x - 100 
     new_z = new_z + 6.25 
    if new_y >= 100: 
     new_y = new_y - 100 
    if new_z >= 100: 
     new_z = new_z - 100 

    if new_x == 0 and new_y == 0 and new_z == 0: 
     print 'done!', i 

    x.append(new_x) 
    y.append(new_y) 
    z.append(new_z) 


ax.scatter(x, y, z, zdir='z', s=20, c='k', zorder=1) 
pyplot.show() 

回答

0

完成! (儘管沒有環繞盒子..)

import matplotlib.pyplot as pyplot 
import numpy as np 
from mpl_toolkits.mplot3d import Axes3D 
from mpl_toolkits.mplot3d.art3d import Poly3DCollection 
import random 

angle = np.arctan2(1,4) 
xangle = np.arctan2(1,4) 
width = 100/np.cos(angle) 
print 'angle:', angle*(180/np.pi) 
print 'xangle:', xangle*(180/np.pi) 
print 'width:', width 

def totuple(a): 
    try: 
     return tuple(totuple(i) for i in a) 
    except TypeError: 
     return a 

def plotSquare(ax,cx,cy,cz, yaw, pitch, diameter): 

    colour1 = random.randint(0,255)/256.0 
    colour2 = random.randint(0,255)/256.0 
    colour3 = random.randint(0,255)/256.0 

    centre = np.array([cx,cy,cz]) 
    radius = diameter/2 
    #0,0,0 to 100,25,125 diff 
    #100,25,125 /2 
    #50,12.5,62.5 /50 
    #1.0,0.25,1.25 
    d1offset = np.array([np.cos(pitch)*radius,(np.cos(yaw)*radius)+(np.sin(pitch)*radius),np.sin(yaw)*radius]) 

    c1 = centre - d1offset 
    c2 = centre + d1offset 

    #100,0,25 to 0,25,100 diff 
    #-100,25,75 /2 
    #-50,12.5,37.5 /50 
    #-1.0,0.25,0.75 
    d2offset = np.array([-np.cos(yaw)*radius,(np.cos(pitch)*radius)-(np.sin(yaw)*radius),np.sin(pitch)*radius]) 

    c3 = centre - d2offset 
    c4 = centre + d2offset 

    verts = [[totuple(c1),totuple(c3),totuple(c2),totuple(c4)]] 
    ax.add_collection3d(Poly3DCollection(verts, facecolors=[colour1,colour2,colour3])) 

x1  = [0, 0, 0, 0, 50, 50, 50, 50] 
y1  = [50,50,50,50,50,50,50,50] 
z1  = [12.5,37.5,62.5,87.5,25,50,75,0] 

x2 = [0,0,0,0,0,0,0,0,50,50,50,50,50,50,50,50] 
y2 = [0,50,0,50,0,50,0,50,0,50,0,50,0,50,0,50] 
z2 = [0,12.5,25,37.5,50,62.5,75,87.5,12.5,25,37.5,50,62.5,75,87.5,0] 

fig = pyplot.figure() 
ax = fig.add_subplot(111, projection = '3d') 

ax.set_xlim(0,100) 
ax.set_ylim(0,100) 
ax.set_zlim(0,100) 
ax.set_xlabel('X') 
ax.set_ylabel('Y') 
ax.set_zlabel('Z') 
#ax.view_init(elev=90, azim=90) 
#ax.scatter(x1, y1, z1, zdir='z', s=20, c='g') 
ax.scatter(x2, y2, z2, zdir='z', s=20, c='r') #EXISTING COORDINATES notice how they do not lie on the plane 

xa = [0,100,100,0] 
ya = [0,0,100,100] 
za = [0,-6.25,18.75,25] 
verts = [zip(xa,ya,za)] 
ax.add_collection3d(Poly3DCollection(verts)) 

xb = [0,100,100,0] 
yb = [0,0,100,100] 
zb = [25,-6.25+25,18.75+25,50] 
verts = [zip(xb,yb,zb)] 
ax.add_collection3d(Poly3DCollection(verts)) 

xc = [0,100,100,0] 
yc = [0,0,100,100] 
zc = [50,-6.25+25*2,18.75+25*2,75] 
verts = [zip(xc,yc,zc)] 
ax.add_collection3d(Poly3DCollection(verts)) 

xd = [0,100,100,0] 
yd = [0,0,100,100] 
zd = [75,-6.25+25*3,18.75+25*3,100] 
verts = [zip(xd,yd,zd)] 
ax.add_collection3d(Poly3DCollection(verts)) 

x = [0] 
y = [0] 
z = [0] 
for i in range(1,100): 
    new_x = x[(len(x)-1)] + 50 
    new_y = y[(len(y)-1)] + 12.5 
    new_z = z[(len(z)-1)] 

    if new_x >= 100: 
     new_x = new_x - 100 
     new_z = new_z + 6.25 
     #new_y = new_y + (50-12.5) 
    if new_y >= 100: 
     new_y = new_y - 100 
    if new_z >= 100: 
     new_z = new_z - 100 

    if new_x == 0 and new_y == 0 and new_z == 0: 
     print 'done!', i 

    x.append(new_x) 
    y.append(new_y) 
    z.append(new_z) 


ax.scatter(x, y, z, zdir='z', s=20, c='k', zorder=1) 

storedcoordinates = zip(x,y,z) 
for x,y,z in storedcoordinates: 
    plotSquare(ax,x,y,z,xangle,angle, width/2) 

pyplot.show()