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

Re: [pygame] draw.line bounding box bug when width>1



Your example code didn't work for me, I made a little interactive example of the problem: http://python.pastebin.com/m66dfd8c1 it allows you to draw a line with your mouse and see line and rect (updated in realtime)
> This bug was already addressed in a DOC post in 2005,
> http://www.pygame.org/docs/ref/draw.html#pygame.draw.line
> I'm not really sure why no one included the patch.

I attempted 'inflate', but didn't account for the width.  I just tried
a range of constants.
So does it work with that code or are there still errors?  Perhaps that's why it hasn't been patched (because the example code doesn't work in all situations).  If you look at the source for the method and you see where the calculation error is occurring, you could submit a diff patch or maybe upload a revision to SVN or something.  Then you can say you contributed to an open-source project on your resume :)
You can uncomment a line in my example above to see that the workaround works just fine. (There is no patch, only a python workaround) The rect delivered by the workaround is sometimes bigger than necessary. (also easily visible in my example)

pygame.draw.line's C code seems to rely on the clip_and_draw_line_width(..) function which does not work as expected. Search trunk/src/draw.c for the definition. (I can't see linenumbers on seul.org)

While I know some python and learn Delphi at school I'm C/C++ illiterate but I might be able to fix the problem, this basically is supposed to be a patch not in diff, but English. I guess that those lines are responsible:
range[0] = MIN(newpts[0], range[0]);
range[1] = MIN(newpts[1], range[1]);
range[2] = MAX(newpts[2], range[2]);
range[3] = MAX(newpts[3], range[3]);
I guess the code somewhere assumes the first point is topleft of the second, draw a broken line in the opposite direction (example prog) and you can see what I mean. If I don't want to touch those lines (because I wouldn't know how) the function (clip_and_draw_line_width) should check if there is a problem and if so switch the points. These are the lines I would edit:
	if(abs(pts[0]-pts[2]) > abs(pts[1]-pts[3]))
		yinc = 1;
	else
		xinc = 1;
Because those lines already "know" in which direction the line might leave the rect.
	if(abs(pts[0]-pts[2]) > abs(pts[1]-pts[3]))
		if(pts[1]>pts[3]) /*if it doesn't work, try < */
			yinc = pts[1]; pts[1] = pts[3]; pts[3] = yinc
			/* I abuse yinc here, because I don't want to declare another var*/
		yinc = 1;
	else
		if(pts[0]>pts[2]) /*if it doesn't work, try < */
			xinc = pts[1]; pts[1] = pts[3]; pts[3] = xinc
		xinc = 1;

I hope that helps, and works - If you don't want to abuse yinc and xinc, declare a war.

Thank you for reading till this point, I'm sorry that my English isn't that good but I hope you where able to understand if not, feel free to ask/point it out.