Can someone explain why negatively sized Rectangle
s intersect the way they do?
var r = new Rectangle(0, 0, 3, 3);
var r0 = new Rectangle(0, 0, -1, -1);
var r1 = new Rectangle(1, 1, -1, -1);
var r2 = new Rectangle(2, 2, -1, -1);
var r3 = new Rectangle(3, 3, -1, -1);
System.Console.WriteLine(r.IntersectsWith(r0)); // False
System.Console.WriteLine(r.IntersectsWith(r1)); // False
System.Console.WriteLine(r.IntersectsWith(r2)); // True
System.Console.WriteLine(r.IntersectsWith(r3)); // False
I would think r1
and r2
should always intersect with r
, even though they don't. r3
should intersect if you consider their negative size. If negative sizes aren't considered, r0
should intersect.
Why does this work the way it does, and what other caveats I should look for when working with Rectangle
structures?
If you create a rectangle with a negative width, then it draws a rectangle that starts at the original (x,y) point and draws to the left instead of to the right.
If you create a rectangle with a negative height, then it draws a rectangle that starts at the original (x,y) point and draws to up instead of down.
Thus if you make a rectangle of with say new Rectangle(5, 4, -1, -2);
then you get a rectangle with the following points: (5,4), (4,4), (5,2), (4,2).
Run the following code for an example:
Rectangle negWidthHeightRect = new Rectangle(5, 4, -1, -2);
Console.WriteLine(negWidthHeightRect.Left);
Console.WriteLine(negWidthHeightRect.Right);
Console.WriteLine(negWidthHeightRect.Bottom);
Console.WriteLine(negWidthHeightRect.Top);
Console.WriteLine(negWidthHeightRect.Width);
Console.WriteLine(negWidthHeightRect.Height);
Console.ReadLine();
The output is as follows:
5
4
2
4
-1
-2
The behavior is somewhat expected given Microsoft's comments on other rectangle-like controls (besides System.Drawing.Rectangle). See MSDM here.
Now, why does the rectangle's IntersectsWith
method produce such weird results. It is because it is using the following code for implementing the IntersectsWith
method:
public bool IntersectsWith(Rectangle rect)
{
return ((((rect.X < (this.X + this.Width)) && (this.X < (rect.X + rect.Width))) && (rect.Y < (this.Y + this.Height))) && (this.Y < (rect.Y + rect.Height)));
}
If you follow through the logic yourself you will see why you get the answers you get. What Microsoft should probably do is either:
1) when it sees a negative width/height make the width/height positive and readjust the Left/Top
2) Or in the IntersectsWith logic, they should do some Min(x, x+width) and Min (y, y+width) when doing the logic.
Some others smarter than me may have an even more clever way to do this.
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