如何将由小正方形组成的区域划分为更大的矩形?

Posted

技术标签:

【中文标题】如何将由小正方形组成的区域划分为更大的矩形?【英文标题】:How to divide an area composed of small squares into bigger rectangles? 【发布时间】:2010-09-20 09:35:48 【问题描述】:

我会去哪里寻找将 0 或 1 的二维网格值作为输入的算法,然后识别其中所有可能的非重叠矩形?

在更实际的解释中:我正在绘制一个由许多正方形表示的网格,并且我希望找到一种方法将尽可能多的相邻正方形组合成矩形,以减少花费的时间循环穿过每个方块并绘制它。

不需要最高效率,速度更重要。

附录:显然我正在寻找的似乎是一种称为 Tesselation 的技术。现在我只需要为这个具体案例找到一个好的描述。

附录2:“1”方格的边界将是不规则的,在某些情况下甚至没有连接,因为“1”方格的分布将是完全随机的。我需要识别这些不规则的形状并将其分割成规则的矩形。

正确答案:为了在速度和效率之间取得最佳平衡,最好使用网格数据填充四叉树,每个节点的状态值为空/部分填充/填满。

【问题讨论】:

"不需要最高效率,速度更重要。" - 嗯?我假设您的意思是“我不想要绝对最小数量的矩形,只想要快速近似的东西”......? 哦,你有没有证明循环通过每个方格是你的性能瓶颈? 关于近似值,是的。就效率与速度而言,我基本上是在寻找最平衡的解决方案。另外,是的,我 100% 确定循环是瓶颈,因为 Perl 比 OpenGL 本身慢很多。 您的数据是静态的吗? IE。值得缓存吗? 根据使用情况,它大约每 3-30 分钟变化一次。实际上,该算法将在创建另一个缓存期间应用。最终目标是在 3D 渲染期间获得一个用于遮挡检查的边界框。 【参考方案1】:

我不得不解决一个类似的问题,我的算法支持锯齿状数组,我已经对其进行了大量测试和评论,但它比 joel-in-gö 的建议慢: https://***.com/a/13802336

【讨论】:

【参考方案2】:

查看this article from Dr Dobb's Portal,了解在您的情况下找到最大矩形。这是对一种极其有效的算法的非常详细的讨论,我认为迭代地重复它可能会解决您的问题。

【讨论】:

【参考方案3】:

我已经为使用 OpenGL 的 3d 框的快速和肮脏的体素可视化做了类似的事情。

我从左上角的框开始存储空/填充标志。然后我尝试将矩形向右扩展,直到我碰到一个带有不同标志的框。我在向下方向做了同样的事情。

绘制矩形,如果它是填充的。

如果还有boxes,则递归地对最后一个矩形引出的所有三个remaing矩形重复该过程,分别是右下角和右下角:

xxxx   1111
xxxx   1111
xxxx   1111

2222   3333
2222   3333
2222   3333

【讨论】:

是的,除非其他人提出更好的解决方案,否则我将这样做。 :)【参考方案4】:

由于您不是在寻找最小平方数,因此我建议您使用一种仍然保持算法简单的折衷方案。

最佳解决方案取决于您的数据,但一种简单的替代方法是仅沿一行收集框。即:

0 0 1 1 1 0 0 0 1 1 1 1 0

将导致:

skip 2
draw 3
skip 3
draw 4
skip 1

这将减少对绘制框的调用次数,无需任何缓存(即您可以即时构建您的框)。

如果您想创建更大的框,我建议您使用回溯算法在那里找到第一个 1 并尝试向各个方向扩展框。建立一个框列表,并在使用它们时清除 1:s。

【讨论】:

是的,这正是我想要的。我已经考虑过在 1 维中进行,但希望其他人已经花时间思考如何在 2 维中进行。【参考方案5】:

所以您正在寻找“ON”正方形的矩形边界? 你想要内界还是外界? IE。边界是否必须只有“ON”方格,还是希望矩形包含一组中的所有“ON”方格?

【讨论】:

添加解释作为附录 3。感谢您帮助我澄清它。 :)

以上是关于如何将由小正方形组成的区域划分为更大的矩形?的主要内容,如果未能解决你的问题,请参考以下文章

将长坐标和纬度坐标划分为子坐标(较小的正方形)?

[Offer收割]编程练习赛12 题目3 : 矩形分割

[部分内容摘自网络]性质定理小结

在这个二维数组中找到最大的区域

hihoCoder 第253周 hiho一下 矩形分割

巧解“求取矩形面积划分”