I am confused as to why the XNA Rectangle struct is written like it is.
If I run this code:
var bounds = new Rectangle(0, 0, 10, 10);
var bounds2 = new Rectangle(0, 10, 10, 10);
var bounds3 = new Rectangle(0, 19, 10, 10);
Debug.Print("Bounds X: {0}, Y: {1}, Top: {2} Left: {3} Bottom: {4} Right {5}",
bounds.X, bounds.Y, bounds.Top, bounds.Left, bounds.Bottom, bounds.Right);
Debug.Print("Bounds2 X: {0}, Y: {1}, Top: {2} Left: {3} Bottom: {4} Right {5}",
bounds2.X, bounds2.Y, bounds2.Top, bounds2.Left, bounds2.Bottom, bounds2.Right);
Debug.Print("Bounds2 X: {0}, Y: {1}, Top: {2} Left: {3} Bottom: {4} Right {5}",
bounds3.X, bounds3.Y, bounds3.Top, bounds3.Left, bounds3.Bottom, bounds3.Right);
Debug.Print("bounds.Intersects(bounds2): {0}", bounds.Intersects(bounds2));
Debug.Print("bounds2.Intersects(bounds3): {0}", bounds2.Intersects(bounds3));
I get the following output:
Bounds X: 0, Y: 0, Top: 0 Left: 0 Bottom: 10 Right 10
Bounds2 X: 0, Y: 10, Top: 10 Left: 0 Bottom: 20 Right 10
Bounds2 X: 0, Y: 19, Top: 19 Left: 0 Bottom: 29 Right 10
bounds.Intersects(bounds2): False
bounds2.Intersects(bounds3): True
This shows that the Intersects method works correctly as bounds does not overlap bounds2 but bounds2 does overlap bounds3 by one row of pixels.
Yet the output for Bottom and Right just seems strange to me.
They both report values that are 1 pixel greater than I feel they should be and I always get caught out by it, causing frustration.
For instance I might use rectangle to create a bounding box for a rectangular sprite.
For convenience I like to make use of the Width, Height, Right and Bottom values but the Right and Bottom values don't give me the bottom row and right column of pixels of the texture, they give me back the row just below the bottom and the column just to the right of the texture.
Is there a good reason it works like this? Do you use Rectangle for bounding boxes in XNA, and if so do you notice the same behaviour or can you offer any suggestions to improve my approach?
Thanks
I don't really see your problem. If a rectangle starts at Left = 1 and has a Width of 3, then it reaches from pixels 1 to 4:

In the above picture I chose the pixel's center as its position. If we say, the pixel's location is its top left corner, then the figure looks as follows:

Then the rectangle reaches from the top left corner of pixel 1 to the top left corner of pixel 4. What might confuse you is that the top left corner of pixel 4 is the top right corner of pixel 3. But that's all up to your interpretation of the rectangle. If you keep interpretation consistent, then it all makes sense.
It's the same for the Windows API Rect structure, which dates back to Windows 3.x at least.
The reason for it is that it simplifies some calculations.
Here's a blog entry about it from 2004: http://blogs.msdn.com/b/oldnewthing/archive/2004/02/18/75652.aspx
Note that GDI line drawing (and probably XNA line drawing too) also uses exclusive endpoints, for similar reasons.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With