[Author Prev][Author Next][Thread Prev][Thread Next][Author Index][Thread Index]

Re: [pygame] Re: `pygame.draw.line(...)` `width`



I'd also be in favor of this change to squared-off miter joints. I've noticed the odd endcap behavior in Pygame a long time ago, and it's one reason that I never used the line drawing function for lines with large widths.

-Al

On Sat, Apr 28, 2018 at 1:35 PM, Ian Mallett <ian@xxxxxxxxxxxxxx> wrote:
​By the way, a solution doesn't even need to use any trigonometry, because a squared-off miter joint is by-definition orthogonal to the line. Here's some proof-of-concept code:

def rndint(x): return int(round(x))
def cappedline(surface, color, p0,p1, width=1, rounded=True):
    radius = width * 0.5
    delta = ( p1[0]-p0[0], p1[1]-p0[1] )
    orthog = [ delta[1], -delta[0] ]
    scale = radius / (orthog[0]*orthog[0] + orthog[1]*orthog[1])**0.5
    orthog[0]*=scale; orthog[1]*=scale
    points = [
        ( p0[0]-orthog[0], p0[1]-orthog[1] ),
        ( p0[0]+orthog[0], p0[1]+orthog[1] ),
        ( p1[0]+orthog[0], p1[1]+orthog[1] ),
        ( p1[0]-orthog[0], p1[1]-orthog[1] )
    ]
    pygame.draw.polygon(surface, color, points)
    if rounded:
        #Could have added these to the polygon points instead, but then we'd have had to choose a subdivision accuracy.
        pygame.draw.circle(surface, color, (rndint(p0[0]),rndint(p0[1])), rndint(radius))
        pygame.draw.circle(surface, color, (rndint(p1[0]),rndint(p1[1])), rndint(radius))
pygame.draw.cappedline = cappedline


Note that this also supports rounded corners by drawing circles on the ends, although this is rather limited by the (poor) accuracy of the circle drawing routine, and doesn't look fabulous at small widths.

Ian