我想取一个凹的复杂多边形(包含孔洞),然后将其垂直挤压成一个多面体,纯粹是为了可视化。我从一个形状优美的Polygon
开始,如下所示:
poly = Polygon(
[(0,0), (10,0), (10,10), (5,8), (0,10), (1,7), (0,5), (1,3)],
holes=[
[(2,2),(4,2),(4,4),(2,4)],
[(6,6), (7,6), (6.5,6.5), (7,7), (6,7), (6.2,6.5)]])
我在matplotlib中正确地将其绘制为(将外部坐标重定向为顺时针,将孔坐标重定向为逆时针):
然后,我试图使用PyVista渲染这个从页面中挤出的多边形(沿着z
)。PyVista不直接支持PolyData
类型的凹(或复杂)输入,所以我们首先创建一个简单(无孔)凹多边形的挤出,如this discussion。
def extrude_simple_polygon(xy, z0, z1):
# force counter-clockwise ordering, so PyVista interprets polygon correctly
xy = _reorient_coords(xy, clockwise=False)
# remove duplication of first & last vertex
xyz0 = [(x,y,z0) for x,y in xy]
if (xyz0[0] == xyz0[-1]):
xyz0.pop()
# explicitly set edge_source
base_vert = [len(xyz0)] + list(range(len(xyz0)))
base_data = pyvista.PolyData(xyz0, base_vert)
base_mesh = base_data.delaunay_2d(edge_source=base_data)
vol_mesh = base_mesh.extrude((0, 0, z1-z0), capping=True)
# force triangulation, so PyVista allows boolean_difference
return vol_mesh.triangulate()
依次挤出外部多边形及其每个内部多边形时,请观察此操作的效果:
extrude_simple_polygon(list(poly.exterior.coords), 0, 5).plot()
extrude_simple_polygon(list(poly.interiors[0].coords), 0, 5).plot()
extrude_simple_polygon(list(poly.interiors[1].coords), 0, 5).plot()
第一节第二节第一节第三节第一节
我推断,要创建原始 * 复杂 * 多边形的拉伸,我可以计算boolean_difference
。
outer_vol = extrude_simple_polygon(list(poly.exterior.coords), 0, 5)
for hole in poly.interiors:
hole_vol = extrude_simple_polygon(list(hole.coords), 0, 5)
outer_vol = outer_vol.boolean_difference(hole_vol)
outer_vol.plot()
是错误的:
该文档建议通过plot_normals
检查法线,发现所有挤出体积都有向内指向(或意外)的法线:
第一个第五个第一个第一个第六个第一个第七个第一个extrude
文档没有提到挤出曲面法线,也没有提到原始对象(在本例中为多边形)方向。
我们可以原谅我们的多边形必须是顺时针方向的,所以我们在extrude_simple_polygon
的第一行设置clockwise=True
,然后再试一次。调用base_mesh.plot()
会显示(* 应该 * 看起来像我们原始的蓝色外部多边形):
用挤压
- PyVista总是期望逆时针多边形吗?
- 为什么拉伸会创建具有向内指向的曲面法线的体积块?
- 如何更正挤出的曲面法线?
- 否则,我怎样才能让PyVista正确地可视化一个难以置信的简单挤压的凹复杂多边形呢?
1条答案
按热度按时间x4shl7ld1#
你已经很接近了,你需要做的是使用一个 single 调用
delaunay_2d()
,把所有三个多边形(即包围的一个和两个洞)作为边源(循环源?),同样重要的是从每个多边形得到面(而不是线);这使得可以加强孔的孔度。下面是一个完整的输入示例(我手动翻转了孔的方向;您似乎有一个
_reorient_coords()
帮助器,您应该使用它来代替):以下是多边形预挤出的顶视图: