Why does Rect.Intersect return a non-empty Rect for two rectangles that do not intersect?

I have a small project in WPF in which I need to exchange UIElements. Something similar to iGoogle functionality.

Due to the fact that I can not publish photos (not enough reputation), I will explain in the text. I have a 3x3 grid defined as follows:

0 1 2 0 C e C 1 eee 2 L e C 

Where C = canvas, L = label, e = empty cell (column + row).

In the MouseMove event, I track my currently selected canvas, and I look at a list of all the other canvases available in the grid to see if they overlap. And here a problem arises; although I move the canvas from (0,0) to the right by 1 pixel, it detects that it intersects with the canvas from (2,2).

I use Rect.Intersect (r1, r2) to determine the intersected area and it should return an empty Rect because r1 does not overlap r2, but instead it always returns a non-empty Rect.

  // Create the rectangle with the moving element width and height Size draggedElementSize = new Size(this.DraggedElement.ActualWidth, this.DraggedElement.ActualHeight); Rect draggedElementRect = new Rect(draggedElementSize); foreach (Canvas c in canvases) { // Create a rectangle for each canvas Size s = new Size(c.ActualWidth, c.ActualHeight); Rect r = new Rect(s); // Get the intersected area Rect currentIntersection = Rect.Intersect(r, draggedElementRect); if (currentIntersection == Rect.Empty) // this is never true return; } // end-foreach 

I do different things inside the loop, but they do not interact with it in any way, since it does not work properly.

I would appreciate any help.

Thanks.

+4
source share
2 answers

Nowhere in your sample code do you compensate for location errors. You set the size of the rectangles.

So, of course, all of your rectangles start at the point (0,0), and so everyone intersects.

You will need to convert the rectangles from the element you are checking to their parents.

The fastest way to execute this is VisualTreeHelper.GetOffset

  // Create the rectangle with the moving element width and height Size draggedElementSize = new Size(this.DraggedElement.ActualWidth, this.DraggedElement.ActualHeight); Rect draggedElementRect = new Rect(draggedElementSize); draggedElementRect.offset(VisualTreeHelper.GetOffset(this.DraggedElement)); foreach (Canvas c in canvases) { if (this.DraggedElement == c) continue; // skip dragged element. // Create a rectangle for each canvas Size s = new Size(c.ActualWidth, c.ActualHeight); Rect r = new Rect(s); r.offset(VisualTreeHelper.GetOffset(c)); // Get the intersected area Rect currentIntersection = Rect.Intersect(r, draggedElementRect); if (currentIntersection == Rect.Empty) // this is never true return; } // end-foreach 

You might want you to skip the current moved item as indicated.

+1
source

I do not see references to positions in your code, only width and height. Do you really want to start all your rectangles with 0/0? Most likely, they will all overlap. You need to include the x / y coordinates.

+1
source

All Articles