在 Matplotlib 中的 3D 空间中的外部和内部多边形之间填充

问题描述 投票:0回答:0

我有一个带空隙的 3D 梁截面(从 2D Shapley 多边形开始),我需要在 Matplotlib 3D 空间中绘制它。我根据光束的长度添加 z 坐标,并首先过滤所有涉及的多边形,并使用以下代码在 Matplotlib 3D 空间中绘制它们。目前我能够填补空白(见附图)但这不是我想要的。

  1. 如何填充空隙和外部多边形(我的意思是实心部分)。 2. 另一个问题是为什么它不按比例(纵横比在不同方向似乎不同)

    将 numpy 导入为 np 从 sympy import Line,Polygon as Polyg 从 mpl_toolkits.mplot3d 导入 Axes3D 从 mpl_toolkits.mplot3d.art3d 导入 Poly3DCollection 将 matplotlib.pyplot 导入为 plt 将 numpy 导入为 np 从 shapely.geometry 导入多边形、线串、点 从 shapely.geometry.polygon 导入 orient

    @静态方法 def by_two_polygons(shaplypoly,长度=10000,make_ccw=True): """ 从 pyny 中提取。静态方法。创建一个封闭的pyny.Polyhedron连接 两个多边形。两个多边形必须具有相同数量的 顶点。创建的多面体的面必须是平面的, 否则,将引发错误。

     The Polyhedron will have the *poly1* and *poly2* as "top" and
     "bottom" and the rest of its faces will be generated by matching
     the polygons' vertices in twos.
    
     .. warning:: If an error is raised, probably the Polyhedron
         have non-planar faces.
     .. warning:: If the Polyhedra are not created with this method
         or ``Place.add_extruded_obstacles()``, holes will not be
         added.
     """
     if type(shaplypoly) == Polygon:
         xe, ye = shaplypoly.exterior.xy
         epoly_cord = list(zip(xe, ye))
         #make np array
         e = np.array(epoly_cord)
         ipoly_cord = []
         if shaplypoly.interiors:
             for i, interior in enumerate(shaplypoly.interiors):
                 ppx, ppy = zip(*interior.coords)
                 ipoly = Polygon(list(zip(ppx, ppy)))
                 ipoly_cord.append(list(zip(ppx, ppy)))
    
         # add extra z variable and assign two polygons beam start location and beam end location
         poly1_points = np.insert(e, 2, 0, axis=1)
         poly2_points = np.insert(e, 2, length, axis=1)
    
         poly1 = poly1_points
         poly2 = poly2_points
    
     vertices = np.dstack((poly1, poly2))
     polygons = []
     polygonsi = []
     for i in np.arange(vertices.shape[0]) - 1:
         polygons.append(np.array([vertices[i, :, 1],
                                   vertices[i + 1, :, 1],
                                   vertices[i + 1, :, 0],
                                   vertices[i, :, 0]]))
     polygons.append(poly1)
     polygons.append(poly2)
    
     if shaplypoly.interiors:
         for iploy in ipoly_cord:
             i=iploy
             polyi1_points = np.insert(i, 2, 0, axis=1)
             polyi2_points = np.insert(i, 2, length, axis=1)
             verticesi = np.dstack((polyi1_points, polyi2_points))
    
             for i in np.arange(verticesi.shape[0]) - 1:
                 polygonsi.append(np.array([verticesi[i, :, 1],
                                           verticesi[i + 1, :, 1],
                                           verticesi[i + 1, :, 0],
                                           verticesi[i, :, 0]]))
             polygonsi.append(polyi1_points)
             polygonsi.append(polyi2_points)
    
     return polygons,polygonsi
    

    类 plot3Dbeam(对象): def init(self, shapelypoly, length): self.shapelypoly = shapelypoly self.length = 长度 self.epoly_cord = self.extract_poly()[0] self.ipoly_cords = self.extract_poly()1 xe, ye = self.shapelypoly.exterior.xy self.ymax = max(ye) self.ymin = min(ye) self.xmax = max(xe) self.xmin = min(xe)

         # making polygons for two ends of beams with z cordninates
         #self.e = np.array(self.epoly_cord)
         #self.poly1_points = np.insert(self.e, 2, 0, axis=1)
         #self.poly2_points = np.insert(self.e, 2, self.length, axis=1)
    
    
    
     def extract_poly(self):
         xe, ye = self.shapelypoly.exterior.xy
         epoly_cord = list(zip(xe, ye))
         ipoly_cord = []
         if self.shapelypoly.interiors:
             for i, interior in enumerate(self.shapelypoly.interiors):
                 ppx, ppy = zip(*interior.coords)
                 ipoly = Polygon(list(zip(ppx, ppy)))
                 ipoly_cord.append(list(zip(ppx, ppy)))
         return epoly_cord, ipoly_cord
    
     def plot_exbeam(self):
         A = by_two_polygons(self.shapelypoly, self.length, make_ccw=True)[0]
         B = by_two_polygons(self.shapelypoly, self.length, make_ccw=True)[1]
    
         fig = plt.figure()
         ax = Axes3D(fig, auto_add_to_figure=False)
         #ax.set_xlim3d(0, self.xmax-self.xmin)
         #ax.set_ylim3d(0, self.length)
         #ax.set_zlim3d(0, self.ymax-self.ymin)
         ax.set_box_aspect([1, 1, 1])
         fig.add_axes(ax)
         for i in range(0, len(A)):
             x, y, z = zip(*A[i])
             x1 = [*(x)]
             y1 = [*(y)]
             z1 = [*(z)]
             ax.plot(x1, z1, y1, 'b')  # interchange the axis to get correct oriantation
    
         for i in range(0, len(B)):
             xi, yi, zi = zip(*B[i])
             x2 = [*(xi)]
             y2 = [*(yi)]
             z2 = [*(zi)]
             ax.plot(x2, z2, y2, 'r')  # interchange the axis to get correct oriantation
             #xx=[a_i - b_i for a_i, b_i in zip(x1, x2)]
             #yy= [a_i - b_i for a_i, b_i in zip(y1, y2)]
             #zz=[a_i - b_i for a_i, b_i in zip(z1, z2)]
    
             verts = [list(zip(x2, z2, y2))]  # this is important variable to fill in between later
             ax.add_collection3d(Poly3DCollection(verts, facecolors='cyan', linewidths=1, edgecolors='b', alpha=.25))
    
         ax.set_xlabel('x')
         ax.set_ylabel('y')
         ax.set_zlabel('z')
         ax.view_init(30, 120)
         plt.show()
    

    实心多边形示例

    #poly_1 = [(0.0,0.0),(378.5,0.0),(506.3928608,1349.62385),(613.5,1424.62385),(1137.53385,1137.53385,1424.62385) 1515.45991),(1033.4,1720.910743),(-1033.4,1720.910743),(-1033.4,1515.459991),(-1150.0,115.0,1515.45991) , (-506.3928608, 1349.62385), (-378.5, 0.0), (0.0, 0.0)] shell = [(0.0,0.0),(378.5,0.0),(506.3928608,1349.62385),(613.5,1424.62385),(1137.53385,1124.62385) ,(1033.4,1720.910743),(-1033.4,1720.910743),(-1033.4,1515.459991),(-1150.0,1515.459991),(-11150.0 -506.3928608, 1349.62385), (-378.5, 0.0), (0.0, 0.0)] hole1 = [(0.0,300.0),(309.0,358.0),(418.0,1475.254307),(445.179014,1475.254307),(445.179014,1500.545525) , 1475.254307), (-309.0, 358.0), (0.0, 300.0)] 孔 2=[(0.0, 50), (200, 50), (200, 250), (-200, 250), (-200, 50),(0, 50)] 孔 1 = 列表(反转(孔 1)) 孔 2 = 列表(反转(孔 2)) 洞=(洞1,洞2) 多边形=东方(多边形(壳,孔))

    poly = Polygon(polygon) # shapley poly default ploy in app plot3Dbeam(poly,length=20000).plot_exbeam()

matplotlib polygon shapley
© www.soinside.com 2019 - 2024. All rights reserved.