2015-06-01 6 views
5

Ich habe Linien (mit einigen Start- und Endpunkten) bei pygame wie folgt gezeichnet: pygame.draw.line(window, color_L1, X0, X1, 2), wo 2 die Dicke der Linie definiert.Pygame zeichnen Anti-Aliased dicke Linie

Da Anti-Aliasing von .draw nicht unterstützt wird, habe ich zu .gfxdraw und pygame.gfxdraw.line(window, X0[0], X0[1], X1[0], X1[1], color_L1) verschoben.

Dies erlaubt mir jedoch nicht, die Dicke der Linie zu definieren. Wie könnte ich Dicke und Anti-Aliasing zusammen haben?

+1

Definieren Sie die korrekten Versatzlinien basierend auf den Endpunkten und der Breite Ihrer Linie und verwenden Sie diese, um ein Polygon zu definieren, das die fette Linie darstellt. Verwenden Sie dann 'pygame.gfxdraw.aapolygon()', um es zu zeichnen. – martineau

+0

Meine Linie rotiert bei jedem Schritt, so dass ich nicht sicher bin, ob die Enden als Polygon definiert werden, + -1 würde in diesem Fall nicht funktionieren. –

+1

Das Zeichnen von Fettlinien, wie ich es vorgeschlagen habe, ist ein Fall, bei dem ein degeneriertes Polygon verschoben wird. Eine Menge Mathe ist normalerweise beteiligt. Siehe [_Analgorithmus zum Auffüllen/Ablassen (Versetzen, Puffern) von Polygonen_] (http://stackoverflow.com/questions/1109536/an-algorithm-for-inflating-deflating-offsetting-buffering-polygons). – martineau

Antwort

5

Nach vielen Versuchen und Irrtümern, die optimale Art und Weise, es zu tun folgend wäre:

1) Zunächst definieren wir die Mitte der Form der X0_ gegeben { x, y} start und X1_ {x, y} Endpunkte der Linie.

center_L1 = (X0 + X1)/2. 

2) Dann finden Sie die Steigung (Winkel) der Linie.

length = 10 # Line size 
thickness = 2 
angle = math.atan2(X0[1] - X1[1], X0[0] - X1[0]) 

3) Unter Verwendung der Steigung und der Formparameter können Sie die folgenden Koordinaten der Kastenenden berechnen.

UL = (center_L1[0] + (length/2.) * cos(angle) - (thickness/2.) * sin(angle), 
     center_L1[1] + (thickness/2.) * cos(angle) + (length/2.) * sin(angle)) 
UR = (center_L1[0] - (length/2.) * cos(angle) - (thickness/2.) * sin(angle), 
     center_L1[1] + (thickness/2.) * cos(angle) - (length/2.) * sin(angle)) 
BL = (center_L1[0] + (length/2.) * cos(angle) + (thickness/2.) * sin(angle), 
     center_L1[1] - (thickness/2.) * cos(angle) + (length/2.) * sin(angle)) 
BR = (center_L1[0] - (length/2.) * cos(angle) + (thickness/2.) * sin(angle), 
     center_L1[1] - (thickness/2.) * cos(angle) - (length/2.) * sin(angle)) 

4) die berechneten Koordinaten wir ein Anti-Aliasing-Polygon (dank @martineau) ziehen und es dann auf der gfxdraw Website wie vorgeschlagen zu füllen.

pygame.gfxdraw.aapolygon(window, (UL, UR, BR, BL), color_L1) 
pygame.gfxdraw.filled_polygon(window, (UL, UR, BR, BL), color_L1) 
1

Ich würde vorschlagen, ein gefülltes Rechteck, wie hier gezeigt: https://www.pygame.org/docs/ref/gfxdraw.html#pygame.gfxdraw.rectangle.

Ihr Code würde in etwa so aussehen:

thickLine = pygame.gfxdraw.rectangle(surface, rect, color) 

und dann denken Sie daran, die Oberfläche zu füllen. Dies ist entlang der Linien von:

thickLine.fill() 
+0

Vielen Dank! Ich habe das ebenso wie die 'Box' versucht, aber ich kann nicht finden, wie ich den Anfang und das Ende definieren kann, da ich nur die Koordinaten von Anfang und Ende der Linie habe. –

+0

Das Problem liegt in der Tatsache, dass meine Linie rotiert, so dass eine einfache + -1 nicht genug ist, da Sie mit einer konstanten Seite enden können, die der Rotation des anderen Endes nicht folgt. –