如何确定一个矩形是否完全包含在另一个矩形内?
我有一个重叠矩形的理论网格,可能看起来像这样:
但我所要做的就是一个矩形对象的集合:
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 只是我如何使用此类结构的示例。
我所困惑的是如何有效地确定哪些矩形属于哪个矩形。
注意 没有矩形部分包含在另一个矩形内,它们总是完全包含在另一个矩形内。
编辑通常会有数百个矩形,我是否应该迭代每个矩形以查看它是否被另一个矩形包含?
编辑 有人建议使用 Contains (这不是我最好的时刻,错过了!),但我不确定如何最好地构建 DOM。例如,取第一个矩形的孙子,父级确实包含孙子,但它不应该是直接子级,它应该是父级第一个子级的子级。
I have a theoretical grid of overlapping rectangles that might look something like this:
But all I have to work with is a collection of Rectangle objects:
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));
// ...
What I'd like to do is build a DOM-like structure where each rectangle has a ChildRectangles property, which contains the rectangles that are contained within it on the grid.
The end result should allow me to convert such a structure into XML, something along the lines of:
<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>
But it's mainly that DOM-like structure in memory that I want, the output XML is just an example of how I might use such a structure.
The bit I'm stuck on is how to efficiently determine which rectangles belong in which.
NOTE No rectangles are partially contained within another, they're always completely inside another.
EDIT There will typically be hundreds of rectangles, should I just iterate through every rectangle to see if it's contained by another?
EDIT Someone has suggested Contains (not my finest moment, missing that!), but I'm not sure how best to build the DOM. For example, take the grandchild of the first rectangle, the parent does indeed contain the grandchild, but it shouldn't be a direct child, it should be the child of the parent's first child.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
使用
Rectangle
的Contains()
。更新:
备查...
有趣的是,如果您想检查一个矩形是否与另一个矩形部分碰撞,
Rectangle
还具有IntersectsWith(Rectangle rect)
功能。Use the
Contains()
of aRectangle
.UPDATE:
For future reference...
It's interesting to add that
Rectangle
also hasIntersectsWith(Rectangle rect)
in case you want to check if a rectangle partially collides with another rectangle.正如 @BeemerGuy 指出的,
Rect.Contains
会告诉您一个矩形是否包含另一个矩形。构建层次结构有点复杂...有一个 O(N^2) 解决方案,其中对于每个矩形,您都搜索其他矩形的列表以查看它是否适合内部。每个矩形的“所有者”是包含它的最小矩形。伪代码:
它的效率不是很高,但对于您的目的来说可能“足够快”。我很确定我见过 O(n log n) 解决方案(毕竟它只是一个排序操作),但它有点复杂。
As @BeemerGuy points out,
Rect.Contains
will tell you whether one rectangle contains another. Building the hierarchy is a bit more involved...There's an O(N^2) solution in which for each rectangle you search the list of other rectangles to see if it fits inside. The "owner" of each rectangle is the smallest rectangle that contains it. Pseudocode:
It's not terribly efficient, but it might be "fast enough" for your purposes. I'm pretty sure I've seen an O(n log n) solution (it is just a sorting operation, after all), but it was somewhat more complex.
平均情况 O(n log n) 解决方案:
将矩形集视为一棵树,其中父节点“包含”子节点——与 DOM 结构相同。您将一次构建一个矩形树。
创建一个虚拟节点作为树的根。然后,对于每个矩形(“current_rect”),从根的子级开始并向下工作,直到找到它的位置:
“包含”关系询问一个矩形是否包含另一个矩形。 “父”、“子”和“兄弟”指的是树结构。
已编辑:修复了一个错误,该错误可能会错过将某些节点移动到 current_rect 的情况。
An average-case O(n log n) solution:
Think of your set of rectangles as a tree, where parent nodes "contain" the child nodes -- the same kind of thing as a DOM structure. You'll be building the tree a rectangle at a time.
Make a dummy node to serve as the root of your tree. Then, for each of your rectangles ("current_rect"), start with the root's children and work downwards until you find where it goes:
The "contains" relation asks whether one rectangle contains the other. "Parent", "child", and "sibling" are referring to the tree structure.
EDITED: Fixed a bug that would miss moving some nodes into current_rect.
检查矩形中的每个点是否位于其他矩形的边界内。
在 .NET 中,矩形类有一个 .Contains(Point) 方法。或者,您可以根据目标矩形的 .Left、.Right、.Top 和 .Bottom 属性检查角点坐标。
Check that each point in the rectangle is within the bounds of the other rectangles.
In .NET the Rectangle class has a .Contains(Point) method. Or you can check the corner point coordinates againt the target rect's .Left, .Right, .Top, and .Bottom properties.
伪代码:
pseudo code: