11

Can someone explain why negatively sized Rectangles 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?

dlras2
  • 8,416
  • 7
  • 51
  • 90
  • I have no idea... I guess the behaviour of IntersectsWith is undefined for negatively-sized rectangles, allthough it's not documented as such in the [API](http://msdn.microsoft.com/en-us/library/y10fyck0.aspx)... I suggest you post this question to MSDN as "community content"? It's a REALLY good question. One suspects that the behaviour of negatively-sized Rectangle's is not defined for all there spatial operations... Are they even rendered as you'd expect? – corlettk Apr 30 '11 at 08:30
  • 1
    @corlettk: "Community Content" is **not** intended for posting questions. That's what the MSDN forums are for. – Cody Gray - on strike Apr 30 '11 at 08:59
  • Thanx Cody. I've never used MSDN's forums ;-) – corlettk Apr 30 '11 at 09:49

2 Answers2

8

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.

Jason Moore
  • 3,294
  • 15
  • 18
0

Check out the first comment to the answer to this question. It appears to be saying that the negative height and width represent a rectangle drawn in the quadrant that's above and to the left of the current coordinate.

Community
  • 1
  • 1
jonsca
  • 10,218
  • 26
  • 54
  • 62
  • which would mean that `Rectangle(0, 0, -x, -x)` is the same as `Rectangle(-x, -x, x, x)`. – Dan D. Apr 30 '11 at 08:34
  • @Dan D. Seems to me that's true. It came as a total surprise to me that it was even valid input. They talk about `ScreenToClient` and `ClientToScreen` in that answer (which I personally don't have a lot of experience with), which leads me to believe its a part of their internal machinations. – jonsca Apr 30 '11 at 08:37
  • @Dan D. Does this imply `Rectangle(1, 1, -1, -1)` is the same as `Rectangle(0, 0, 1, 1)`? If so, it should still intersect with `r`. – dlras2 Apr 30 '11 at 08:41
  • @Daniel Rasmussen `Rectangle(-1,-1,-1,-1)` is the same as `Rectangle(0,0,1,1)` – jonsca Apr 30 '11 at 08:54