Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do negative-sized rectangles intersect?

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?

like image 844
dlras2 Avatar asked Apr 30 '11 08:04

dlras2


1 Answers

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.

like image 173
Jason Moore Avatar answered Oct 28 '22 23:10

Jason Moore