为啥 Pyglet 不能正确绘制多边形?
Posted
技术标签:
【中文标题】为啥 Pyglet 不能正确绘制多边形?【英文标题】:Why can't Pyglet draw a polygon correctly?为什么 Pyglet 不能正确绘制多边形? 【发布时间】:2019-07-28 09:40:57 【问题描述】:我正在随机创建用于使用 Pyglet 绘制多边形的点。但是 Pyglet 大部分时间都做不好。
好吧,我尝试用另一个图形模块绘制一个多边形,实际上它可以工作,但如果 Pyglet 工作正常,它会让我的工作更轻松。
我用它来绘制多边形和点(方便你看)。
point_list = [18, 61, 59, 149, 328, 204, 305, 284, 3, 197, 25, 107]
ec = int(len(point_list)/2)
batch.add(ec, pyglet.gl.GL_POLYGON, None, ("v2i", point_list), ("c3B", [random.randrange(255)]*(3*ec)))
for i in range(int(len(point_list)/2)):
p1 = point_list[i*2:2+i*2]
p2 = point_list[2+i*2:4+i*2]
if not len(p2):
p2 = point_list[:2]
batch.add(ec, pyglet.gl.GL_POINTS, None, ("v2i", point_list), ("c3B", [255]*(3*ec)))
@window.event
def on_draw():
window.clear()
batch.draw()
pyglet.app.run()
这是结果,但它应该像我在下面绘制的绿色多边形。
【问题讨论】:
【参考方案1】:PyGlet 是一个 OpenGL 包装器。使用Legacy OpenGLPrimitive 类型GL_POLYGON
绘制的多边形必须是Convex。 Concave 多边形可能无法正确绘制。
使用基本类型 GL_TRIANGLE_FAN
并从点 (59, 149) 开始。这将解决您的特殊情况下的问题:
point_list = [59, 149, 328, 204, 305, 284, 3, 197, 25, 107, 18, 61]
ec = int(len(point_list)/2)
batch.add(ec, pyglet.gl.GL_TRIANGLE_FAN, None,
("v2i", point_list),
("c3B", [random.randrange(255)]*(3*ec)))
这会导致Polygon triangulation:
对于您想要绘制的任何多边形,您必须找到合适的Polygon triangulation。三角测量可能会有所不同,必须使用 Triangle primitive 类型 GL_TRIANGLES
、GL_TRIANGLE_STRIP
或 GL_TRIANGLE_FAN
之一。
在某些情况下,更改多边形的起点并使用基本类型GL_TRIANGLE_FAN
就足够了。
例如点列表(来自commnet)[488, 485, 375, 73, 61, 48, 70, 257, 119, 260, 418, 327]
可以更改为[375, 73, 61, 48, 70, 257, 119, 260, 418, 327, 488, 485]
:
对于更通用的方法,您必须实现 Polygon triangulation 算法,例如 Two ears theorem,但 OpenGL 不适合您。
【讨论】:
它确实适用于这个确切的point_list,但对于另一个它却没有,这是为什么呢?例如:[488、485、375、73、61、48、70、257、119、260、418、327] @Adenzu 这取决于多边形和Polygon triangulation。三角测量取决于Triangle primitive 类型。即使您使用GL_POLYGON
,也会对多边形进行三角剖分,但未指定确切的三角剖分,具体取决于图形硬件和驱动程序。
最后一件事。您是否碰巧知道 Python 的图形库或模块,即使数字是随机的,也可以根据我的需要使用此类列表绘制多边形?就像能够正确绘制第一个和第二个列表一样。以上是关于为啥 Pyglet 不能正确绘制多边形?的主要内容,如果未能解决你的问题,请参考以下文章