Почему 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()

фактический результат

Это результат, но он должен быть похож на многоугольник зеленого цвета, который я нарисовал ниже. неправильно и правильно


person Adenzu    schedule 28.07.2019    source источник


Ответы (1)


PyGlet — это оболочка OpenGL. Многоугольники, нарисованные с помощью устаревшего OpenGL Примитивный тип GL_POLYGON должен быть Выпуклый. Вогнутые многоугольники могут отображаться неправильно.


Используйте тип примитива 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)))

Это приводит к следующей полигональной триангуляции:


Для любого многоугольника, который вы хотите нарисовать, вы должны найти правильную триангуляцию многоугольника. Триангуляция может быть разной, и один из типов треугольника имеет тип GL_TRIANGLES, GL_TRIANGLE_STRIP или GL_TRIANGLE_FAN. должен быть использован.

В некоторых случаях достаточно изменить начальную точку многоугольника и использовать тип примитива GL_TRIANGLE_FAN.

например список точек (из сообщества) [488, 485, 375, 73, 61, 48, 70, 257, 119, 260, 418, 327] можно изменить на [375, 73, 61, 48, 70, 257, 119, 260, 418, 327, 488, 485]:

введите здесь описание изображения


Для более общего подхода вам необходимо реализовать алгоритм полигональной триангуляции, подобный Теорема о двух ушах, но OpenGL не сделает эту работу за вас.

person Rabbid76    schedule 28.07.2019
comment
Он работает именно для этого point_list, но не для другого, почему? Например: [488, 485, 375, 73, 61, 48, 70, 257, 119, 260, 418, 327] - person Adenzu; 28.07.2019
comment
@Adenzu Это зависит от многоугольника и триангуляции многоугольника. Триангуляция зависит от типа треугольного примитива. Даже если использовать GL_POLYGON, то полигон триангулируется, но точная триангуляция не указывается и зависит от графического железа и драйвера. - person Rabbid76; 28.07.2019
comment
Последняя вещь. Вы случайно не знаете графическую библиотеку или модуль для Python, который может рисовать полигоны с такими списками, как я хочу, даже если числа случайны? Например, уметь правильно рисовать и первый, и второй список. - person Adenzu; 28.07.2019