Christopher Night wrote:
If I have a 100x100 pixel window, and I want to put a dot at a position (x,x), it seems to me like the dot should appear in the window if 0 <= x < 100. You're saying it should appear in the window if -0.5 <= x < 99.5.
You need to be more precise about what you mean by "a dot". On a display surface made of pixels, to make anything appear at all, you need to paint at least one pixel. So I'll take it that you want to paint a 1x1 rectangle. There are also a couple of other things we need to be clear about. One is the precise relationship between coordinates and pixels. Two obvious choices come to mind: we could take the coordinates as labelling the centres of pixels, or the boundaries between pixels. I prefer to take the boundary approach, because it avoids a lot of potential confusion. To draw a 1x1 rect centred at (x, y), we need to paint the area between (x-0.5, y-0.5) and (x+0.5, y+0.5). In order to cover exactly one pixel, the centre coordinates need to be an integer plus 0.5, so that the boundaries are integers. So if x = 0.5, the rect covers the range 0.0 to 1.0. Now, suppose our arithmetic is a little inaccurate, and we actually get x = 0.499. The boundaries then come out as -0.001 and 0.999. If we round these, we get 0.0 and 1.0 as before. But if we floor, we get -1.0 and -0.0, and the pixel goes off the screen. Note that I'm rounding the *boundaries* of the rect, not its centre. That's what I meant when I said that you need to work out where all the sides of the rect are first, and then round them. Also, in general, what I mean by "rounding" is finding the *nearest pixel boundary*. If the coordinate system is chosen so that the pixel boundaries are on integer coordinates, then this will correspond to what the round() function does. If you choose some other convention, it won't. In particular, if you decide that the *centres* of pixels lie on integer coordinates, it will correspond to something involving floor(), because everything is offset by 0.5 and round(x) == floor(x+0.5). This may be the reason we're misunderstanding each other -- you're thinking of (0, 0) as being the *centre* of the top left pixel in the window, whereas I'm thinking of it as the *top left corner* of that pixel.
I realize that it's a matter of preference, and either way would be logically consistent, so it's just a matter of which is more intuitive and comfortable.
The PyGame docs don't specify one way or the other. They don't really need to, because for integer coordinates you get the same result either way. But when floats are involved, things need to be pinned down more precisely. -- Greg
