2012-04-13 6 views
4

Ich arbeite an etwas Code mit der Verwendung der Pygame-Bibliothek, um einen Kreis auf eine Oberfläche zu zeichnen. Der Code, den Kreis zu ziehen sieht etwa wie folgt aus:Artefakte beim Zeichnen von Primitiven mit Pygame?

surf = pygame.Surface((2000,2000)) 
    pygame.draw.circle(surf, 
        pygame.Color("white"), 
        (1000,1000), 
        508, 
        50) 

Das Problem ist, dass die resultierende Kreis Artefakte hat Circle with artifacts

Gibt es trotzdem einen Kreis so zu zeichnen, ohne diese Artefakte zu bekommen?

+0

Höchstwahrscheinlich, weil der Kreis nicht Anti-Aliased ist. – hjpotter92

+0

Haben Sie ein komplettes Beispiel, das dies zeigt? –

+0

@ChasingDeath: Die Punkte, die Sie auf dem Kreis sehen, sind entweder das Ergebnis von Dithering oder die Rendering-Bibliothek weiß nicht, wie man einen Kreis richtig zeichnet (und versucht, ihn durch Drehen eines Linienprimitivs oder ähnlichem zu zeichnen). Beide Szenarien haben nichts mit Antialiasing zu tun. – SigTerm

Antwort

7

Was Sie sehen, ist höchstwahrscheinlich ein Problem mit der Implementierung von pygame.draw.circle. Höchstwahrscheinlich nahm pygame developer törichterweise an, dass Sie einen dicken Kreis zeichnen können, indem Sie mehrere Kreise nacheinander zeichnen und den Radius für jeden Kreis um eins erhöhen. Das wird in der Praxis nicht funktionieren und Sie werden ein Moiremuster wie das, das Sie sehen, bekommen. Versuchen Sie, die Kreislinienstärke um 100 oder 200 zu erhöhen, und sehen Sie, was passiert. Wenn es schlimmer wird, dann ist es pygame.draw.circle 's Fehler.

Eine Lösung wäre, Ihre eigene Kreis-Rendering-Routine bereitzustellen. Dies kann sicherlich getan werden, aber für eine optimale Leistung ist es sinnvoll, es im C/C++ - Erweiterungsmodul für Pygame ODER OpenGL (mit oder ohne Fragment-Shader) zu tun.

Um für jeden Scanline einen perfekten Kreis zu erhalten, müssen Sie Anfang und Ende des gefüllten Bereichs für jeden Scanline berechnen. Es könnte möglich sein, dies in Python mit tolerierbarer Leistung zu tun, indem Sie pygame.draw.line verwenden, um einzelne Scanlinien zu zeichnen.

+0

Ich glaube, das ist die richtige Antwort. Sobald du die Kreisbreite in meinem Code unten auf 2 änderst, erscheint der erste Riss, wenn du genau hinsiehst.pygame.draw.circle (Bildschirm, pygame.Color ("white"), (1000, 1000), 508, 2) ' – jgritty

+0

Das ist richtig, und ist [in pygame Häufig gestellten Fragen dokumentiert] (http://www.pygame.org/wiki/FrequentlyAskedQuestions#Why%20does%20drawing%20thick%20circles%20or% 20arcs% 20give). Entsprechend der Antwort auf die FAQ können Sie das Paket SDL_gfx verwenden, das in pygame enthalten ist (ab 1.9.0), die eine ausgefüllte Ellipse-Zeichenfunktion enthält, mit der Sie zwei konzentrische Kreise zeichnen können. – Darthfett

2

Dieser Fehler wird in den Kommentaren für die Methoden circle und arc erwähnt. Es gibt einen Workaround in den Kommentaren der draw.circle documentation. Dies wird aus dieser Behelfslösung angepasst:

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))) 

Dieses Verfahren verwendet eine zusätzliche Surface und zieht zwei Kreise: einen kleineren Kreis innerhalb eines größeren man die gleiche Wirkung zu erzielen. Die Füllfarbe des kleineren Kreises hat einen Alpha-Wert von 0, sodass der Mittelpunkt des gesamten Kreises transparent erscheint.

EDIT: Aus dem obigen Kommentar, ich sehe das Verhalten ist auch in der pygame FAQ erwähnt.

0

Ich habe dieses Problem behoben, und es wird in der nächsten Version von Pygame (1.9.4) sein. Wie zeichnest du solche Kreise ohne Artefakte? Verwenden Sie die neuere Version von Pygame.

Verwandte Themen