【问题标题】:python : plotting a wireframe 3D cuboidpython:绘制线框 3D 长方体
【发布时间】:2015-08-23 06:28:51
【问题描述】:

我想在 python 中绘制 3d 长方体。

输入: 中心(中心 3 分) 半径(3 个半径值,每个维度一个)

理想情况下它应该是一个线框图(我需要看看里面有什么)。我不完全确定如何去做。使用 python matplotlib 或 Mayavi 就可以了。

谢谢!

到目前为止,我已经尝试了以下代码..但只绘制了一个立方体

from mpl_toolkits.mplot3d import Axes3D
import matplotlib.pyplot as plt
import numpy as np
from itertools import product, combinations
fig = plt.figure()
ax = fig.gca(projection='3d')
ax.set_aspect("equal")

#draw cube
r = [-1, 1]
for s, e in combinations(np.array(list(product(r,r,r))), 2):
    if np.sum(np.abs(s-e)) == r[1]-r[0]:
        ax.plot3D(*zip(s,e), color="b")
plt.show()

此代码中缺少的是它只是一个立方体(不是长方体)并且它仅以 0 为中心(我实际上想提供中心)

经过一番思考,我想出了这个。这似乎是正确的。如果您认为它不正确,请告诉我...这是不安装 myavi、pygame、povray 的最简单方法(我很难在 ipython、conda、我的 windows 笔记本电脑上安装这些)

from mpl_toolkits.mplot3d import Axes3D
import matplotlib.pyplot as plt
import numpy as np
from itertools import product, combinations
fig = plt.figure()
ax = fig.gca(projection='3d')
ax.set_aspect("equal")

#draw cube

r1 = [-1, 1]
r2 = [-2, 2]
r3 = [-3, 3]
center =[5,5,5]

for s, e in combinations(np.array(list(product(r1,r2,r3))), 2):
    s=np.array(center)+np.array(s)
    e=np.array(center)+np.array(e)
    ax.scatter3D(*center, color="r") 
    if np.linalg.norm(s-e) == 2*r1[1] or np.linalg.norm(s-e) == 2*r2[1] or np.linalg.norm(s-e) == 2*r3[1]:
        print zip(s,e)
        ax.plot3D(*zip(s,e), color="b")  
plt.show()

【问题讨论】:

  • 我试过这个链接...这仅适用于立方体stackoverflow.com/questions/11140163/… ....我不完全确定如何将其修改为一个长方体,其中我给出 3 个中心和 3 个半径
  • 你能用代码的形式告诉我们你尝试过的更具体吗
  • 我在问题中包含了我尝试过的代码。

标签: python plot mayavi wireframe


【解决方案1】:

我也遇到过同样的问题,试着给出如下答案。

def cuboid_data(center, size):
"""
   Create a data array for cuboid plotting.


   ============= ================================================
   Argument      Description
   ============= ================================================
   center        center of the cuboid, triple
   size          size of the cuboid, triple, (x_length,y_width,z_height)
   :type size: tuple, numpy.array, list
   :param size: size of the cuboid, triple, (x_length,y_width,z_height)
   :type center: tuple, numpy.array, list
   :param center: center of the cuboid, triple, (x,y,z)


  """


    # suppose axis direction: x: to left; y: to inside; z: to upper
    # get the (left, outside, bottom) point
    o = [a - b / 2 for a, b in zip(center, size)]
    # get the length, width, and height
    l, w, h = size
    x = [[o[0], o[0] + l, o[0] + l, o[0], o[0]],  # x coordinate of points in bottom surface
         [o[0], o[0] + l, o[0] + l, o[0], o[0]],  # x coordinate of points in upper surface
         [o[0], o[0] + l, o[0] + l, o[0], o[0]],  # x coordinate of points in outside surface
         [o[0], o[0] + l, o[0] + l, o[0], o[0]]]  # x coordinate of points in inside surface
    y = [[o[1], o[1], o[1] + w, o[1] + w, o[1]],  # y coordinate of points in bottom surface
         [o[1], o[1], o[1] + w, o[1] + w, o[1]],  # y coordinate of points in upper surface
         [o[1], o[1], o[1], o[1], o[1]],          # y coordinate of points in outside surface
         [o[1] + w, o[1] + w, o[1] + w, o[1] + w, o[1] + w]]    # y coordinate of points in inside surface
    z = [[o[2], o[2], o[2], o[2], o[2]],                        # z coordinate of points in bottom surface
         [o[2] + h, o[2] + h, o[2] + h, o[2] + h, o[2] + h],    # z coordinate of points in upper surface
         [o[2], o[2], o[2] + h, o[2] + h, o[2]],                # z coordinate of points in outside surface
         [o[2], o[2], o[2] + h, o[2] + h, o[2]]]                # z coordinate of points in inside surface
    return x, y, z



def test():
    import matplotlib as mpl
    from mpl_toolkits.mplot3d import Axes3D
    import numpy as np
    center = [0, 0, 0]
    length = 32 * 2
    width = 50 * 2
    height = 100 * 2
    import matplotlib.pyplot as plt
    fig = plt.figure()
    ax = fig.gca(projection='3d')
    X, Y, Z = cuboid_data(center, (length, width, height))
    ax.plot_surface(X, Y, Z, color='b', rstride=1, cstride=1, alpha=0.1)
    ax.set_xlabel('X')
    ax.set_xlim(-100, 100)
    ax.set_ylabel('Y')
    ax.set_ylim(-100, 100)
    ax.set_zlabel('Z')
    ax.set_zlim(-100, 100)
    plt.show()


if __name__ == '__main__':
    test()

这是结果:

【讨论】:

    【解决方案2】:

    这是一个长方体的线框图。

    def plot_cuboid(center, size):
        """
           Create a data array for cuboid plotting.
    
    
           ============= ================================================
           Argument      Description
           ============= ================================================
           center        center of the cuboid, triple
           size          size of the cuboid, triple, (x_length,y_width,z_height)
           :type size: tuple, numpy.array, list
           :param size: size of the cuboid, triple, (x_length,y_width,z_height)
           :type center: tuple, numpy.array, list
           :param center: center of the cuboid, triple, (x,y,z)
       """
        # suppose axis direction: x: to left; y: to inside; z: to upper
        # get the (left, outside, bottom) point
        import numpy as np
        ox, oy, oz = center
        l, w, h = size
    
        x = np.linspace(ox-l/2,ox+l/2,num=10)
        y = np.linspace(oy-w/2,oy+w/2,num=10)
        z = np.linspace(oz-h/2,oz+h/2,num=10)
        x1, z1 = np.meshgrid(x, z)
        y11 = np.ones_like(x1)*(oy-w/2)
        y12 = np.ones_like(x1)*(oy+w/2)
        x2, y2 = np.meshgrid(x, y)
        z21 = np.ones_like(x2)*(oz-h/2)
        z22 = np.ones_like(x2)*(oz+h/2)
        y3, z3 = np.meshgrid(y, z)
        x31 = np.ones_like(y3)*(ox-l/2)
        x32 = np.ones_like(y3)*(ox+l/2)
    
        from mpl_toolkits.mplot3d import Axes3D
        import matplotlib.pyplot as plt
        fig = plt.figure()
        ax = fig.gca(projection='3d')
        # outside surface
        ax.plot_wireframe(x1, y11, z1, color='b', rstride=1, cstride=1, alpha=0.6)
        # inside surface
        ax.plot_wireframe(x1, y12, z1, color='b', rstride=1, cstride=1, alpha=0.6)
        # bottom surface
        ax.plot_wireframe(x2, y2, z21, color='b', rstride=1, cstride=1, alpha=0.6)
        # upper surface
        ax.plot_wireframe(x2, y2, z22, color='b', rstride=1, cstride=1, alpha=0.6)
        # left surface
        ax.plot_wireframe(x31, y3, z3, color='b', rstride=1, cstride=1, alpha=0.6)
        # right surface
        ax.plot_wireframe(x32, y3, z3, color='b', rstride=1, cstride=1, alpha=0.6)
        ax.set_xlabel('X')
        ax.set_xlim(-100, 100)
        ax.set_ylabel('Y')
        ax.set_ylim(-100, 100)
        ax.set_zlabel('Z')
        ax.set_zlim(-100, 100)
        plt.show()
    
    
    
    def test():
        center = [0, 0, 0]
        length = 32 * 2
        width = 50 * 2
        height = 100 * 2
        plot_cuboid(center, (length, width, height))
    
    
    if __name__ == '__main__':
        test()
    

    这是结果。

    【讨论】:

      【解决方案3】:

      每个人都忘记了可以很好地处理 3D 的 POVray。不过,它不会渲染线框,但您可以使用半透明纹理来查看框内的内容。

      #!/usr/bin/python
      # -*- coding: utf-8 -*-
      
      import os
      
      center='-1, -1, -1'
      radius='1, 1, 1'
      
      
      pov='camera { location <0, 2, -3> look_at  <0, 1,  2> }\n\
      light_source { <2, 4, -3> color rgb 1*1.5}\n\
      background {color rgb <0.00, 0.00, 0.00>}\n\
      box {<'+center+'>, < '+radius+'>\n\
      pigment { color rgbt <0.67, 1.00, 0.39, 0.80> }\n\
      rotate <52, 6, 0>\n\
      scale 0.9\n\
      translate <0, 1.2, 1>}\n\
      '
      
      f=open('scene.pov', 'w')
      f.write(pov)
      f.close()
      
      os.system('povray +W400 +H300 +A +FN  scene.pov')
      

      输出“场景.png”

      您需要阅读 povray 的文档。

      【讨论】:

        猜你喜欢
        • 2022-11-10
        • 2018-08-22
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-01-15
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多