You can try organize your rectangles in a structure called k-d-tree.
It gives you up to O(log N) complexity in a large rectangle array (> 100).
F.e. make binary tree with fixed length, say, 2. Divide your space into left and right halves, then each half divide into top and bottom quarters (and so on).
Inside leaf node create a list on rectangles. If a rectangles falls into left half and top quarter, locate it in the list of this quarter.
A rectangle may be locates in a few list at the same time (f.e. in case if it falls in left and right halves).
To check intersection you should test rectangle in responding halves and quarters.
Or, you removes too many rectangles, it's faster to copy remaining rectangles into the new list in your own code.
Small example.
public enum CheckBy
{
Horizontal,
Vertical
}
public class Node
{
public Node First { get; set; }
public Node Second { get; set; }
public int Coordinate { get; set; }
public CheckBy CheckBy { get; set; }
public List<Rectangle> Rectangles { get; set; }
}
public bool IsRectangleInFist(Node node, Rectangle rectangle)
{
if (node.CheckBy == CheckBy.Horizontal)
return rectangle.Left <= node.Coordinate;
return rectangle.Top <= node.Coordinate;
}
public bool IsRectangelInSecond(Node node, Rectangle rectangle)
{
if (node.CheckBy == CheckBy.Horizontal)
return rectangle.Right >= node.Coordinate;
return rectangle.Bottom >= node.Coordinate;
}
public void AddRectangleInSuitableNode(Node node, Rectangle rectangle)
{
if (InRectangleInFirst(node, rectangle))
AddRectangleInSuitableNode(node.First, rectangle);
if (InRectangleInSecond(node, rectangle))
AddRectangleInSuitableNode(node.Second, rectangle);
}
public void SearchIntersectedRectangles(Node node, Rectangle rectangle, List<Rectangles> result)
{
// If not-leaf node
if (node.Rectangles == null && node.First != null && node.Second != null)
{
if (IsRectangleInFirst(node, rectangle))
SearchIntersecatedRectangles(node.First, rectangle, result);
if (IsRectangleInSecond(node, rectangle))
SearchIntersecatedRectangles(node.Second, rectangle, result);
return;
}
result.AddRangle(Rectangles.Where(r => r.IsIntersect(rectangle)));
}
These all lines makes simple 2D-tree. First, make the tree:
// Say, all rectangles would be inside this "space"
const int leftest = -1000;
const int rightest = 1000;
const int bottomest = -1000;
const int toppest = 1000;
// Tree with depth == 2
var tree = new Node
{
CheckBy = CheckBy.Hozirontal,
Coordinate = (leftest + rightest)/2,
First = new Node
{
CheckBy = CheckBy.Vertical,
Coordintate = (toppest + bottomest)/2,
Rectangles = new List<Rectangle>(),
},
Second = new Node
{
CheckBy = CheckBy.Vertical,
Coordintate = (toppest + bottomest)/2,
Rectangles = new List<Rectangle>(),
},
}
Then, sort all rectangles in this tree:
foreach (var rectangle in rectangles)
AddRectangleInSuitableNode(tree, rectangle);
Now you can fast get intersecting rectangles:
var intersecting = new List<Rectangles>();
SearchIntersecatedRectangles(tree, targetRectangle, intersecting);
// Here you can remove intersecting rectangles...