Artifacts when drawing primitives with pygame?

What you see is most likely a problem with pygame.draw.circle implementation. Most likely pygame developer foolishly assumed that you can draw thick circle by drawing several circles in sequence, increasing radius by one for every circle. That's not going to work in practice and you'll get moire pattern like the one you see. Try increasing circle line thickness by 100 or 200 and see what happens. If it gets worse, then it is pygame.draw.circle's fault.

A solution would be to provide your own circle rendering routine. This can be certainly be done, but for optimum performance it makes sense to do it in C/C++ extension module for pygame OR using OpenGL (with or without fragment shaders).

To get a perfect circle for every scanline you'll have to calculate start and end of filled area for every scanline. It might be possible to do this in python with tolerable performance by using pygame.draw.line to draw individual scanlines.


This bug is mentioned in the comments for the circle and arc methods. There's one workaround in the comments of the draw.circle documentation. This is adapted from that workaround:

def draw_outlined_circle(surf, color, origin, radius, thickness):
    width = radius * 2 + thickness * 2
    background = (0, 0, 0, 0)
    circle = pygame.Surface((width, width)).convert_alpha()
    rect = circle.get_rect()
    circle.fill(background)
    pygame.draw.circle(circle, color, rect.center, radius)
    pygame.draw.circle(circle, background, rect.center, radius - thickness)
    surf.blit(circle, (origin[0] - (rect.w / 2), origin[1] - (rect.w / 2)))

This method uses an extra Surface and draws two circles: a smaller circle inside of a larger one to achieve the same effect. The smaller circle's fill color has an alpha of 0, so the full circle's center appears transparent.

EDIT: From the above comment, I see the behavior is mentioned in the pygame FAQ as well.


I fixed this issue, and it will be in the next release of pygame (1.9.4). How do you draw circles like that without artifacts? Use the newer version of pygame.

Tags:

Python

Pygame