我有一个重叠矩形的理论网格,可能看起来像这样:
但我必须使用的是Rectangle对象的集合:
var shapes = new List<Rectangle>();
shapes.Add(new Rectangle(10, 10, 580, 380));
shapes.Add(new Rectangle(15, 20, 555, 100));
shapes.Add(new Rectangle(35, 50, 40, 75));
// ...
我想要做的是构建一个类似DOM的结构,其中每个矩形都有一个ChildRectangles属性,该属性包含网格中包含的矩形。
最终结果应该允许我将这样的结构转换为XML,类似于:
<grid>
<shape rectangle="10, 10, 580, 380">
<shape rectangle="5, 10, 555, 100">
<shape rectangle="20, 30, 40, 75"/>
</shape>
</shape>
<shape rectangle="etc..."/>
</grid>
但主要是我想要的内存中类似DOM的结构,输出XML只是我如何使用这种结构的一个例子。
我坚持的一点是如何有效地确定哪个矩形属于哪个。
注意没有矩形部分包含在另一个中,它们总是完全在另一个内部。
编辑通常会有数百个矩形,我应该遍历每个矩形以查看它是否包含在另一个矩形中?
编辑有人建议包含(不是我最好的时刻,错过了!),但我不确定如何最好地构建DOM。例如,取第一个矩形的孙子,父母确实包含孙子,但它不应该是直接的孩子,它应该是父母的第一个孩子的孩子。
答案 0 :(得分:8)
使用Contains()
的{{1}}。
Rectangle
<强>更新强>:
供将来参考...
有趣的是,如果你想检查一个矩形是否与另一个矩形部分碰撞,Rectangle rect1, rect2;
// initialize them
if(rect1.Continas(rect2))
{
// do...
}
也有Rectangle
。
答案 1 :(得分:6)
正如@BeemerGuy指出的那样,Rect.Contains
会告诉你一个矩形是否包含另一个矩形。构建层次结构有点复杂......
有一个O(N ^ 2)解决方案,其中对于每个矩形,您搜索其他矩形列表以查看它是否适合内部。每个矩形的“所有者”是包含它的最小矩形。伪代码:
foreach (rect in rectangles)
{
owner = null
foreach (possible_owner in rectangles)
{
if (possible_owner != rect)
{
if (possible_owner.contains(rect))
{
if (owner === null || owner.Contains(possible_owner))
{
owner = possible_owner;
}
}
}
}
// at this point you can record that `owner` contains `rect`
}
效率不高,但对于您的目的而言可能“足够快”。我很确定我已经看过一个O(n log n)解决方案(毕竟它只是一个排序操作),但它有点复杂。
答案 2 :(得分:4)
平均情况O(n log n)解决方案:
将您的矩形集视为树,其中父节点“包含”子节点 - 与DOM结构相同。您将一次将树构建为矩形。
创建一个虚拟节点作为树的根。然后,对于每个矩形(“current_rect”),从root的子项开始向下工作,直到找到它的位置:
parent_node = root_node
sibling_nodes = [children of parent_node]
for this_node in sibling_nodes:
if current_rect contains this_node:
move this_node: make it a child of current_rect instead of parent_node
elseif this_node contains current_rect:
parent_node = this_node
sibling_nodes = [children of parent_node]
restart the "for" loop using new set of sibling_nodes
make current_rect a child of parent_node
“包含”关系询问一个矩形是否包含另一个矩形。 “父母”,“孩子”和“兄弟姐妹”指的是树形结构。
已编辑:修复了错过将某些节点移至current_rect的错误。
答案 3 :(得分:0)
检查矩形中的每个点是否在其他矩形的边界内。 在.NET中,Rectangle类有一个.Contains(Point)方法。或者你可以在目标rect的.Left,.Right,.Top和.Bottom属性中检查角点坐标。
答案 4 :(得分:0)
伪代码:
for i = 0 to rectangles.length - 2
for j = i + 1 to rectangles.length - 1
if rectangles[i].Contains(rectangles[j])
//code here
}}}