Pygame draws a smooth thick line

I used line drawing (considering some starting and ending points) in pygame as follows: pygame.draw.line(window, color_L1, X0, X1, 2) , where 2 determined the thickness of the line.

Since anti-aliasing is not supported .draw , so I switched to .gfxdraw and pygame.gfxdraw.line(window, X0[0], X0[1], X1[0], X1[1], color_L1) .

However, this does not allow me to determine the thickness of the line. How can thickness and smoothing be combined?

+7
source share
3 answers

After many trials and errors, the best way to do this would be:

1) First we define the center of the shape defined by the starting points X0_ {x, y} and X1_ {x, y} of the line.

 center_L1 = (X0 + X1) / 2. 

2) Then find the slope (angle) of the line.

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

3) Using the parameters of the slope and shape, you can calculate the following coordinates of the end of the box.

 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) Using the calculated coordinates, we draw a smooth polygon (thanks to @martineau) and then fill it as suggested on the gfxdraw website.

 pygame.gfxdraw.aapolygon(window, (UL, UR, BR, BL), color_L1) pygame.gfxdraw.filled_polygon(window, (UL, UR, BR, BL), color_L1) 
+6
source

I would suggest a filled rectangle as shown below: https://www.pygame.org/docs/ref/gfxdraw.html#pygame.gfxdraw.rectangle .

Your code will look something like this:

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

and then remember to fill the surface. This corresponds to the following:

 thickLine.fill() 
+1
source

You can also hack the pygame.draw.aalines function a bit by drawing copies of the +/- 1-N line of pixels around the original line (yes, this is not very efficient, but it works as a last resort.). For example, suppose we have a list of line segments for drawing:

 for segment in self._segments: if len(segment) > 2: for i in xrange(self._LINE_WIDTH): pygame.draw.aalines(self._display, self._LINE_COLOR, False ((x,y+i) for x,y in segment)) pygame.draw.aalines(self._display, self._LINE_COLOR, False, ((x,yi) for x,y in segment)) pygame.draw.aalines(self._display, self._LINE_COLOR, False ((x+i,y) for x,y in segment)) pygame.draw.aalines(self._display, self._LINE_COLOR, False, ((xi,y) for x,y in segment)) 
0
source

All Articles