我有一个带空隙的 3D 梁截面(从 2D Shapley 多边形开始),我需要在 Matplotlib 3D 空间中绘制它。我根据光束的长度添加 z 坐标,并首先过滤所有涉及的多边形,并使用以下代码在 Matplotlib 3D 空间中绘制它们。目前我能够填补空白(见附图)但这不是我想要的。
如何填充空隙和外部多边形(我的意思是实心部分)。 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() 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()