![]() |
1
51
计算该区域的一种有效方法是使用扫描算法。假设我们将垂直线l(x)扫过矩形u的并集:
我们仍然需要解决一维问题。您需要一个1d结构,它动态计算(垂直)段的并集。动态地说,我的意思是有时添加一个新的段,有时删除一个。 我已经在回答中详细说明了 collapsing ranges question 如何以静态方式进行(实际上是一维扫描)。因此,如果您想要一些简单的东西,您可以直接应用它(通过为每个事件重新计算联合)。如果你想要更有效率的东西,你只需要稍微调整一下:
这是您的动态算法。假设您将使用带有日志时间位置查询的排序集来表示数据。 一 …D K ,这可能是最有效的非专门化方法。 |
![]() |
2
13
一种方法是将其绘制到画布上!使用半透明颜色绘制每个矩形。NET运行时将使用优化的本机代码进行绘图,甚至使用硬件加速器。 然后,你必须读回像素。每个像素是背景色、矩形色还是其他颜色?唯一能变成另一种颜色的方法是两个或多个矩形重叠… 如果这是一个太多的欺骗,我会推荐四叉树作为另一个答案,或 r-tree . |
![]() |
3
9
这是我在Topcoder SRM 160第2部分中使用的一些快速而肮脏的代码。
T =顶部
|
![]() |
4
8
最简单的解决方案
在这个例子中,我们创建了两个零矩阵,它们是画布的大小。对于每个矩形,用其中一个矩阵填充矩形占用空间的矩阵。然后对矩阵求和。现在
|
![]() |
5
6
下面是一些我觉得可行的方法:
示例:5个矩形,相互顶部绘制,从A到E:
这是X坐标列表:
列表将是(其中每个v的坐标从0开始向上):
因此,每个条带都是(从上到下排序的矩形):
对于每个条带,重叠部分为:
我可以想象,用于顶部底部检查的sort+enter/leave算法的变体也是可行的:
对于上面的1-2条,您可以这样迭代:
实际上也不需要在这里维护一个实际的集合,只需要计算你所在的矩形的数量,每当它从1到2,存储y,每当它从2到1,计算当前的y存储y,并求和这个差。 希望这是可以理解的,正如我所说,这是我的头上,没有任何测试。 |
![]() |
6
3
使用示例: 1 2 3 4 5 6 1 +---+---+ | | 2 + A +---+---+ | | B | 3 + + +---+---+ | | | | | 4 +---+---+---+---+ + | | 5 + C + | | 6 +---+---+ 1)将所有X坐标(左、右)收集到一个列表中,然后对其进行排序并删除重复项 1 3 4 5 6 2)将所有Y坐标(顶部和底部)收集到一个列表中,然后对其进行排序并删除重复项 1 2 3 4 6 3)通过唯一X坐标之间的间隙数*唯一Y坐标之间的间隙数创建二维阵列。 4 * 4 4)将所有矩形绘制到此网格中,增加每个单元格的计数: 1 3 4 5 6 1 +---+ | 1 | 0 0 0 2 +---+---+---+ | 1 | 1 | 1 | 0 3 +---+---+---+---+ | 1 | 1 | 2 | 1 | 4 +---+---+---+---+ 0 0 | 1 | 1 | 6 +---+---+ 5)网格中计数大于1的单元格区域的总和是重叠区域。为了在稀疏用例中提高效率,每次将单元格从1移动到2时,实际上可以在绘制矩形时保持该区域的总运行时间。 在这个问题中,矩形被描述为四个双精度。双精度通常包含舍入误差,误差可能会蔓延到计算的重叠区域。如果合法坐标位于有限点,请考虑使用整数表示。 PS使用硬件加速器和我的另一个答案一样,如果分辨率可以接受的话,这不是一个糟糕的想法。它也很容易实现,代码比我上面概述的方法要少得多。马为课程。 |
![]() |
7
3
这是我为面积扫描算法编写的代码:
|
![]() |
8
2
如果将每个矩形拆分为较小的矩形,可以将此问题简化很多。收集所有矩形的所有X和Y坐标,这些坐标就成为分割点——如果一个矩形横过这条线,将其分割为两个。完成后,会有一个重叠0%或100%的矩形列表,如果对它们进行排序,就很容易找到相同的矩形。 |
![]() |
9
2
链接上列出了一个解决方案 http://codercareer.blogspot.com/2011/12/no-27-area-of-rectangles.html 求多个矩形的总面积,使重叠区域只计算一次。 上面的解决方案可以扩展到只计算重叠区域(即使重叠区域被多个矩形覆盖,也只能计算一次),每对连续的垂直扫描线都有水平扫描线。 如果目的仅仅是找出所有矩形所覆盖的总面积,那么不需要水平扫描线,只要将两条垂直扫描线之间的所有矩形合并就可以得到该面积。 另一方面,如果只计算重叠区域,则需要水平扫描线来确定垂直(y1,y2)扫描线之间重叠的矩形数。 下面是我在Java中实现的解决方案的工作代码。
|
![]() |
10
0
|
![]() |
11
0
这种类型的碰撞检测通常称为AABB(轴对齐的边界框),这是 google search . |
![]() |
12
0
你可以在x轴和y轴上找到重叠,然后将它们相乘。
|
![]() |
13
0
我找到了一个与扫描算法不同的解决方案。 由于矩形都是矩形放置的,因此矩形的水平线和垂直线将形成矩形不规则网格。您可以在网格上“绘制”矩形;这意味着,您可以确定将填充网格的哪些字段。由于网格线是由给定矩形的边界形成的,因此网格中的字段将始终完全为空或完全由矩形填充。 我必须用Java解决这个问题,所以这里是我的解决方案: http://pastebin.com/03mss8yf 此函数计算矩形所占的完整面积。如果您只对“重叠”部分感兴趣,则必须在第70行和第72行之间扩展代码块。也许您可以使用第二个集合来存储哪些网格字段被多次使用。第70行和第72行之间的代码应替换为如下块:
这里的变量usedlocations2与usedlocations的类型相同;它将被构造 在同一点上。 我不太熟悉复杂度计算;所以我不知道这两个解决方案(扫描或网格解决方案)中哪一个能更好地执行/扩展。 |
![]() |
14
0
考虑到我们有两个矩形(A和B),我们有它们的左下(x1,y1)和右上(x2,y2)坐标。使用下面的代码可以计算C++中的重叠区域。
|
![]() |
15
0
下面的答案应该只给出一次总面积。 它有以前的答案,但现在在C中实现。 它也适用于浮点数(如果需要,也可以是double,如果不超过值的话)。 信用: http://codercareer.blogspot.co.il/2011/12/no-27-area-of-rectangles.html 编辑: OP要求重叠区域-这显然非常简单:
答案是:
代码如下:
|
![]() |
Sweepy Dodo · JSON lite的格式化 7 月前 |
![]() |
giantjenga · 优化整数向量到二进制向量的转换 9 月前 |
![]() |
Zegarek · Postgresql递归查询未提供预期结果 9 月前 |
![]() |
Joe · 为什么这两个查询之间的性能存在如此大的差异? 1 年前 |
![]() |
tic-toc-choc · 在`dplyr中高效使用列表进行过滤` 1 年前 |