4
« on: October 17, 2009, 03:27:14 am »
What I'm about to say is based off of SFML 1.5, so if things have changed since that version please forgive me, but there seems to be some confusion about how rectangles should be represented by the sf::Rect object. Browsing through the code for the Rect class, I see conflicting uses. Here are the two options:
1) Inclusive Coordinates
The "right" and "bottom" members specify the bottom-right-most pixel that is included in the rectangle. So a Rect(0,0,1,1) would have a width of 2, and a height of 2, including four pixels, with the pixel at (1,1) being the bottom-right.
2) Exclusive Coordinates
The "right" and "bottom" members specify the bottom-right-most pixel that is outside the rectangle. So a Rect(0,0,1,1) would have a width of 1, a height of 1, and include only one pixel, (0,0).
Method 2 is commonly accepted as the standard way of representing a rectangle. Using this method simplifies things such as iterating over the points in a rectangle, or calculating its width or height. For this, all that needs to be done is to subtract the right from the left. If using inclusive coordinates, the width of the rect is (right-left+1), which is considered counter-intuitive. Using exclusive coordinates also makes SFML's intersect code work correctly. For your example, the rect (0,0,1,1) would encompass only one pixel at (0,0). The second rect (1,1,2,2) would also encompass only one pixel, at (1,1). These do not intersect, even though they at first appear to share a pixel. In reality, they do not share any pixels, because the bottom-right pixel of the first rect is not actually inside that rectangle. If the rectangles do not overlap, returning a Rect(0,0,0,0) would be correct with exlusive coordinates, since this rectangle would have a width and height of zero, and thus contain no pixels and be invalid.
In the sf::Rect class, GetWidth(), GetHeight(), and Intersects() all operate as if the rectangle is expressed in exclusive coordinates. However, Contains() appears to operate as if the rectangle is using inclusive coordinates. Instead of this:
return (X >= Left) && (X <= Right) && (Y >= Top) && (Y <= Bottom);
I believe it should be this:
return (X >= Left) && (X < Right) && (Y >= Top) && (Y < Bottom);
I strongly recommend that SFML continue to use exclusive coordinates, they make life easy. Either way, the class needs to be consistent in the method it uses to do calculations. I am also in favor of having a global Intersects() function, but I would also like to see the class continue to have its own Intersects() method as well.