Search code examples
pythonpygamelineantialiasing

Pygame draw anti-aliased thick line


I used to draw lines (given some start and end points) at pygame like this: pygame.draw.line(window, color_L1, X0, X1, 2), where 2 was defining the thickness of the line.

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

However, this does not allow me to define the thickness of the line. How could I have thickness and anti-aliasing together?


Solution

  • After many trials and errors, the optimal way to do it would be the following:

    1. First, we define the center point of the shape given the X0_{x,y} start and X1_{x,y} end points of the line:

      center_L1 = (X0+X1) / 2.
      
    2. Then find the slope (angle) of the line:

      length = 10  # Total length of line
      thickness = 2
      angle = math.atan2(X0[1] - X1[1], X0[0] - X1[0])
      
    3. Using the slope and the shape parameters you can calculate the following coordinates of the box ends:

      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 computed coordinates, we draw an unfilled anti-aliased polygon (thanks to @martineau) and then fill it as suggested in the documentation of pygame's gfxdraw module for drawing shapes.

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