什么是一个有效的算法找出重叠的矩形的面积是一个、矩形、算法、面积

2023-09-10 22:31:31 作者:说戏人

我的情况

输入:一组矩形 在每个矩形由4双打是这样的:(X0,Y0,X1,Y1) 它们不是旋转在任何角度,所有的他们是正常的矩形那去上/下和左/右相对于该屏幕 在他们被随机放置 - 他们可能接触的边缘,重叠,或没有任何联系 在我将有几百个矩形 这是在C#中实现

我需要找到

是受它们的重叠所形成的区域 - 的所有区域中的帆布中,不止一个矩形封面(例如使用两个矩形,这将是交点) 我不需要重叠的几何形状 - 刚刚的区域(例如:4平方英寸) 重叠不应被多次计算 - 所以例如想象3 rects具有相同的大小和位置 - 他们是正确的对彼此的顶部 - 此区域应计算一次(未三次)

示例

在下面的图片中包含THRE矩形:A,B,C 在A和B重叠(用虚线表示) B和C重叠(用虚线表示) 在我所寻找的是那里的虚线所示的区域

-

  AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAA -------------- BBB
AAAAAAAAAAAAAAAA -------------- BBB
AAAAAAAAAAAAAAAA -------------- BBB
AAAAAAAAAAAAAAAA -------------- BBB
                BBBBBBBBBBBBBBBBB
                BBBBBBBBBBBBBBBBB
                BBBBBBBBBBBBBBBBB
                BBBBBB ----------- CCCCCCCC
                BBBBBB ----------- CCCCCCCC
                BBBBBB ----------- CCCCCCCC
                      CCCCCCCCCCCCCCCCCCC
                      CCCCCCCCCCCCCCCCCCC
                      CCCCCCCCCCCCCCCCCCC
                      CCCCCCCCCCCCCCCCCCC
 

解决方案

计算这个领域的一个有效的方法是使用扫描算法。让我们假设,我们通过矩形U型工会扫一条垂直线L(X):

首先,就需要建立一个事件队列Q,其中,在这种情况下,所有的x坐标的矩形(左和右)的有序列表。 在扫描过程中,你应该保持一维数据结构,这应该给你的L交集的总长度(x)和美国最重要的是,这个长度为两个连续的事件q和q的恒问:那么,如果L(Q)表示L(Q +)的总长度(即我只是对q的rightside)相交U,用L事件Q和Q'之间扫过的面积恰好是L(Q)* (Q - Q)。 您只需要总结这些扫领域获得的总之一。

我们还是要解决的一维问题。你想一维结构,动态计算(垂直)段工会。通过动态,我的意思是你有时会添加一个新的细分市场,有时删除一个。

我在回答这个collapsing范围问题如何做一个静态的方式(这实际上是一维扫描)。所以,如果你想要的东西简单,你可以直接申请的(通过重新计算工会为每个事件)。如果你想要的东西更有效,你只需要适应它一下:

假设你知道段S中的工会 1 内容S N 由脱节段的D- 1 .... D K 。加入S N + 1 是很容易的,你只需要找到为S 两端N + 1 amongsð 1 的两端.. .D K 。 假设你知道段S中的工会 1 内容S N 由脱节段的D- 1 .... D K ,删除段S 我(假设使得S 我被列入D中Ĵ)指重新计算部分的结合使D Ĵ组成的,除了S 我(使用静态算法)。 非最大抑制算法是如何工作的

这是您的动态算法。假设您将使用的有序集合与记录时间位置查询重新presentð 1 .... D K ,这可能是最有效的非专业方法,你可以得到的。

My situation

Input: a set of rectangles each rect is comprised of 4 doubles like this: (x0,y0,x1,y1) they are not "rotated" at any angle, all they are "normal" rectangles that go "up/down" and "left/right" with respect to the screen they are randomly placed - they may be touching at the edges, overlapping , or not have any contact I will have several hundred rectangles this is implemented in C#

I need to find

The area that is formed by their overlap - all the area in the canvas that more than one rectangle "covers" (for example with two rectangles, it would be the intersection) I don't need the geometry of the overlap - just the area (example: 4 sq inches) Overlaps shouldn't be counted multiple times - so for example imagine 3 rects that have the same size and position - they are right on top of each other - this area should be counted once (not three times)

Example

The image below contains thre rectangles: A,B,C A and B overlap (as indicated by dashes) B and C overlap (as indicated by dashes) What I am looking for is the area where the dashes are shown

-

AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAA--------------BBB
AAAAAAAAAAAAAAAA--------------BBB
AAAAAAAAAAAAAAAA--------------BBB
AAAAAAAAAAAAAAAA--------------BBB
                BBBBBBBBBBBBBBBBB
                BBBBBBBBBBBBBBBBB
                BBBBBBBBBBBBBBBBB
                BBBBBB-----------CCCCCCCC
                BBBBBB-----------CCCCCCCC
                BBBBBB-----------CCCCCCCC
                      CCCCCCCCCCCCCCCCCCC
                      CCCCCCCCCCCCCCCCCCC
                      CCCCCCCCCCCCCCCCCCC
                      CCCCCCCCCCCCCCCCCCC

解决方案

An efficient way of computing this area is to use a sweep algorithm. Let us assume that we sweep a vertical line L(x) through the union of rectangles U:

first of all, you need to build an event queue Q, which is, in this case, the ordered list of all x-coordinates (left and right) of the rectangles. during the sweep, you should maintain a 1D datastructure, which should give you the total length of the intersection of L(x) and U. The important thing is that this length is constant between two consecutive events q and q' of Q. So, if l(q) denotes the total length of L(q+) (i.e. L just on the rightside of q) intersected with U, the area swept by L between events q and q' is exactly l(q)*(q' - q). you just have to sum up all these swept areas to get the total one.

We still have to solve the 1D problem. You want a 1D structure, which computes dynamically a union of (vertical) segments. By dynamically, I mean that you sometimes add a new segment, and sometimes remove one.

I already detailed in my answer to this collapsing ranges question how to do it in a static way (which is in fact a 1D sweep). So if you want something simple, you can directly apply that (by recomputing the union for each event). If you want something more efficient, you just need to adapt it a bit:

assuming that you know the union of segments S1...Sn consists of disjoints segments D1...Dk. Adding Sn+1 is very easy, you just have to locate both ends of Sn+1 amongs the ends of D1...Dk. assuming that you know the union of segments S1...Sn consists of disjoints segments D1...Dk, removing segment Si (assuming that Si was included in Dj) means recomputing the union of segments that Dj consisted of, except Si (using the static algorithm).

This is your dynamic algorithm. Assuming that you will use sorted sets with log-time location queries to represent D1...Dk, this is probably the most efficient non-specialized method you can get.