给定一组可能重叠的矩形(所有矩形都是“未旋转”的,可以统一表示为(左,上,右,下)四元组等),它返回一组最小的(未旋转的)不重叠矩形,它们占据相同的区域。
乍一看似乎很简单,但实际上很棘手(至少要高效地完成)。
是否有一些已知的方法/思路/指针?
不一定是最小集合的方法,但启发式小集合的方法也很有趣,产生任何有效输出集合的方法也很有趣。
我认为基于线性扫描算法的某些方法可以解决这个问题:
x
坐标按顺序排列成一个数组,作为“开始矩形”和“结束矩形”事件。y
坐标即可)。y
坐标设置为尚未覆盖的新矩形的部分。我不完全确定这是否涵盖了所有情况,但我认为通过一些调整应该可以解决问题。或者至少给你一些想法… :)
所以,如果我试图做这件事,第一件事是想出一个统一的网格空间。找到所有独特的x和y坐标,并创建一个映射到索引空间的映射。因此,如果您有x值{-1、1.5、3.1},则将其映射到{0、1、2},y也是如此。然后每个矩形都可以用这些紧密打包的整数坐标准确地表示。
然后,我会分配一个位向量或覆盖整个网格的其他内容,并在网格中光栅化您的矩形。拥有网格的好处是它非常容易使用,并且通过将其限制为唯一的x和y坐标,它是最小和精确的。
想要快速找到解决方案的一种方法就是将网格的每个'像素'全部转储..再通过映射运行它们,然后你就完成了。如果您正在寻找更优化的矩形数量,则需要处理某种搜索问题。
让我们看一下4个相邻的像素,一个小的2x2正方形。当我编写这样的算法时,通常我会从顶点、边缘和面的角度考虑。所以,这些是围绕着一个顶点的面。如果其中3个打开了,1个关闭了,那么你就有了一个凹角。这是唯一的无效情况。例如,如果我没有任何凹角,我只需抓取范围并将整个内容作为单个矩形转储即可。对于每个凹角,您需要决定是水平分割、垂直分割还是两者都要。我认为分割是标记不要跨越的边缘,以便找到范围。您也可以将其彩色分组,以便更容易处理。
凹角及其分割方向是您的搜索空间...您可以使用任何优化算法。分支/界限可能效果很好。我敢打赌,您可以找到一个简单的启发式算法(例如,如果在您正在考虑的凹角的正对面有另一个凹角,则始终朝那个方向分割。否则,朝较短的方向分割)。您可以采用贪心策略。或者您可以在两个方向上分割每个凹角,这通常会给您比将每个“像素”输出为矩形更少的矩形,并且非常简单。
阅读这篇文章时,我意识到可能有一些不清楚的地方。如果您需要我澄清任何问题,请让我知道。