适合点周围的矩形

时间:2015-12-27 10:12:38

标签: c++ algorithm

我正在尝试在一组8个2D点周围放置一个矩形,同时尝试最小化覆盖区域

示例:

enter image description here

可以缩放和旋转矩形。但是它需要保持矩形。

我的第一种方法是对每个可能的旋转进行强力逼近,使矩形尽可能接近,并计算覆盖区域。最合适的是那个最低面积的旋转。

然而,这听起来并不是最好的解决方案。

有没有更好的方法呢?

3 个答案:

答案 0 :(得分:36)

我不知道“尝试每一个可能的轮换”是什么意思,因为它们中有很多,但这个基本思想实际上产生了一个非常有效的解决方案:

第一步是计算凸包。实际保存的数量取决于数据的分布,但for points picked uniformly from a unit disk, the number of points on the hull is expected to be O(n^1/3)。有一个number of ways to do that

  • 如果点已经按其坐标之一进行排序,则Graham扫描算法在O(n)中进行。对于给定顺序中的每个点,将其连接到船体中的前两个点,然后移除新船体上的每个凹点(唯一的候选者是与新点相邻的那些点)。
  • 如果点没有排序,礼品包装算法是一个在O(n * h)运行的简单算法。对于从输入的最左侧点开始的船体上的每个点,检查每个点以查看它是否是船体上的下一个点。 h是船体上的点数。
  • Chen's algorithm承诺O(n log h)表现,但我还没有完全探究它是如何运作的。
  • 另一个类似的想法是按方位角对点进行排序,然后删除凹点。但是,这一开始似乎只是O(n + sort),但我恐怕实际上并非如此。

此时,检查到目前为止收集的每个角度都应该足够了(由我和Oliver Charlesworth以及Evgeny Kluev offered a gist of a proof)联合起来。最后,让我参考Lior Kogan's answer中的相关参考资料。

对于每个方向,边界框由该间隔中的每个角度的相同四个(不一定是不同的)点定义。对于候选方向,您将至少有一个任意选择。找到这些点可能看起来像是一个O(h ^ 2)任务,直到您意识到轴对齐边界框的极值与开始合并的极值相同,并且连续间隔的极值点相同或连续。让我们按顺时针顺序调用极值点A,B,C,D,并将限定边界框的相应线条设为a,b,c,d

那么,让我们做数学。边界框区域由|a,c| * |b,d|给出。但|a,c|只是投影到矩形方向上的向量(AC)。设u为与ac平行的向量,让v为垂直向量。让它们在整个范围内平滑变化。在矢量用语中,该区域变为((AC).v) / |v| * ((BD).u) / |u| = {((AC).v) ((BD).u)} / {|u| |v|}。我们也选择u = (1,y)。然后是v = (y, -1)。如果u是垂直的,这会引起一个涉及限制和无穷大的轻微问题,所以在这种情况下我们只需选择u为水平。对于数值稳定性,我们只需在u之外的(1,-1)..(1,1)处旋转90°。如果需要,将该区域翻译成笛卡尔形式,留给读者练习。

答案 1 :(得分:27)

已经证明,一组点的最小面积矩形与集合的凸壳多边形 ["Determining the Minimum-Area Encasing Rectangle for an Arbitrary Closed Curve"的一条边线共线[Freeman,Shapira 1975]

这个问题的O(nlogn)解决方案发表于"On the computation of minimum encasing rectangles and set diameters" [Allison,Noga,1981]

一个简单而优雅的O(n)解决方案发表于"A Linear time algorithm for the minimum area rectangle enclosing a convex polygon" [Arnon,Gieselmann 1983],当输入是凸包时(constructing a convex hull的复杂性等于排序的复杂性输入点)。该解决方案基于Rotating calipers中描述的Shamos, 1978方法。可以在线演示here

答案 2 :(得分:0)

当我看到这个问题时,首先想到的是使用主成分分析。我猜想最小的矩形是满足两个条件的矩形:边缘与主轴平行,边缘至少有四个点(有界点)。应该有n维的扩展。