-
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 ,这可能是最有效的非专业方法,你可以得到的。
-
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.
下一篇:旋转点大约另一点(2D)