1

I know of pygame.draw.polygon() but that can only handle colors with no alpha value. Is there an analogous function somewhere that can? I searched for a bit and did not find anything, so I tried writing my own. somehow it misses pixels occasionally (it's worth noting it only needs to work for convex quadrilaterals). here it is, apologies in advance for the poorly written inefficient code:

def fill_quad(A, B, C, D, color=(0, 255, 100, 100)):
    M = quad_center(A, B, C, D);

    dxA, dyA = A[0] - M[0], A[1] - M[1];
    dxB, dyB = B[0] - M[0], B[1] - M[1];
    dxC, dyC = C[0] - M[0], C[1] - M[1];
    dxD, dyD = D[0] - M[0], D[1] - M[1];

    dist = max(math.hypot(dxA, dyA), math.hypot(dxB, dyB), math.hypot(dxC, dyC), math.hypot(dxD, dyD));
    dxA, dyA, dxB, dyB, dxC, dyC, dxD, dyD = map(lambda d: d / dist, (dxA, dyA, dxB, dyB, dxC, dyC, dxD, dyD));
    for i in range(0, int(dist)+1, 1):
        connect(A, B, C, D, color=color);
        A = A[0] - dxA, A[1] - dyA;
        B = B[0] - dxB, B[1] - dyB;
        C = C[0] - dxC, C[1] - dyC;
        D = D[0] - dxD, D[1] - dyD;

quad_center returns the center of the polygon formed by four points and connect connects points like pygame.draw.lines except it can do transparency. The trouble seems to be with dxA, dxB, etc. and dyA, dyB, etc. (as in they are too big of steps) which is why it misses pixels. The issue is not with my connect function because I have the same problem when using pygame's builtins. In order to run this on your computer just replace connect(A, B, C, D, color=color) with pygame.draw.lines(screen, color, True, (A, B, C, D)) and use this for quad_center:

def midpoint(A, B):
    return (A[0] + B[0]) / 2, (A[1] + B[1]) / 2;

def quad_center(A, B, C, D):
    return midpoint(midpoint(A, B), midpoint(C, D));

Just for completeness here is an example of what I mean when I say "missing pixels": example of missing pixels Each one of those quadrilaterals is drawn with my function. You can see the little blue streaks everywhere, that's what I'm referring to.

If a function like this already exists, obviously I prefer that, but if not any help with the function that I wrote is appreciated. thanks for any help.

sam-pyt
  • 1,027
  • 15
  • 26
  • I think it's inherent in the way you're interpolating the edges of the quadrilaterals. To do this properly, you'd need to implement a "standard" polygon-fill algorithm, which typically interpolate the polygon's edges along each horizontal scanline they intersect. i.e. with a delta y of `1`. – martineau Apr 28 '19 at 17:45
  • I'm not sure what you mean. Can you provide a link? – sam-pyt Apr 28 '19 at 18:06
  • Just do a Google search for [polygon scanline conversion](https://www.google.com/search?hl=en&as_q=polygon+scanline+conversion&as_epq=&as_oq=&as_eq=&as_nlo=&as_nhi=&lr=&cr=&as_qdr=all&as_sitesearch=&as_occt=any&safe=images&as_filetype=&as_rights=). – martineau Apr 28 '19 at 19:34

1 Answers1

0

Pygame cannot draw transparent shapes or draw and blend them simultaneously. The only way is to draw single shapes on pygame.Surface with an alpha channel (pygame.SRCALPHA) and blend that surface with the target surface. Also see Draw a transparent rectangles and polygons in pygame.

Rabbid76
  • 202,892
  • 27
  • 131
  • 174