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

2018-04-28 Thread Al Sweigart
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  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
>


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

2018-04-28 Thread Ian Mallett
​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