I have a list of boxes, and wish to group them into unconnected sets of overlapping boxes. (Note that two boxes A and B may not overlap each other, but if they are both overlapped by a box C, they will still be grouped together).
The following works ok, but I feel like it could be made a lot more concise with LINQ, or possibly made faster.
private List<List<Box>> FindUnconnectedSets(List<Box> boxes)
{
List<List<Box>> unconnectedSets = new List<List<Box>>();
while (boxes.Count() != 0)
{
List<Box> set = new List<Box>();
bool found = true;
while (found)
{
found = false;
foreach (Box newBox in boxes)
{
if (set.Count != 0)
{
foreach (Box setBox in set)
{
if (newBox.Overlaps(setBox))
{
set.Add(newBox);
boxes.Remove(newBox);
found = true;
break;
}
}
}
else
{
set.Add(newBox);
boxes.Remove(newBox);
found = true;
}
if (found)
break;
}
}
unconnectedSets.Add(set);
}
return unconnectedSets;
}
Edit: added the Box class. It's not all that interesting really.
private class Box
{
public Box(int xOrigin, int yOrigin, int size)
{
XOrigin = xOrigin;
YOrigin = yOrigin;
Size = size;
}
public int XOrigin;
public int YOrigin;
public int Size;
public override string ToString()
{
string s = "Box: "
+ "(" + XOrigin.ToString() + ", " + YOrigin.ToString() + ")"
+ " " + Size.ToString();
return s;
}
public bool Overlaps(Box b2)
{
if (XOrigin >= b2.XOrigin + b2.Size)
return false;
if (b2.XOrigin >= XOrigin + Size)
return false;
if (YOrigin >= b2.YOrigin + b2.Size)
return false;
if (b2.YOrigin >= YOrigin + Size)
return false;
return true;
}
}
Comments welcome, both on the LINQifying side, and algorithm suggestions if you think I'm going about this the wrong way, as well as any other feedback. :)
Box
implementation, and maybe a few examples of input and expected output? This could be quite helpful. \$\endgroup\$HashSet<T>
instead. Your function should accept a HashSet. Then write another function that acceptsIEnumerable<T>
and converts it toHashSet<T>
and then calls the implementing function. \$\endgroup\$