【问题标题】:Fit rectangle around points围绕点拟合矩形
【发布时间】:2016-04-01 11:18:46
【问题描述】:

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

例子:

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

我的第一种方法是暴力破解每个可能的旋转,使矩形尽可能接近,然后计算覆盖面积。最好的拟合是面积最小的旋转。

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

有没有更好的方法来做到这一点?

【问题讨论】:

  • 那么,您的蛮力解决方案的复杂性是什么?凸包上有 O(n) 条边。即使你使用蛮力矩形收缩包装,你最终也会得到 O(n^2),实际上是 th(n^1.5)。
  • 我希望找到更好的解决方案,而不是蛮力方法
  • @MrSmith42 - 我的直觉告诉我相反;凸包的一个边缘成为最小矩形的一部分。不过还不能证明...
  • @MrSmith42 我会尝试将边界框与前两点对齐。
  • 所以...计算凸包;对于凸包方向 mod 90 度之间的每个角度范围,矩形由相同的四个点界定。求对应面积函数的最小值(其形式事先已知)。取最低的最小值。

标签: c++ algorithm


【解决方案1】:

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

【讨论】:

  • 嗯?边缘平行于主轴?那为什么拟合的矩形是倾斜的?我的显示器歪了吗?
  • 主轴不平行于显示器的边缘。它们由点决定。
  • 啊,所以你定义了边缘的方向......根本没有。 :P
  • 参见 3D 游戏编程和计算机图形学的数学,第 8.1.1 节(从 pp212 开始)
【解决方案2】:

已经表明,一组点的最小面积矩形与集合的凸包多边形的一条边共线 ["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]

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

【讨论】:

    【解决方案3】:

    我不知道您所说的“尝试所有可能的旋转”是什么意思,因为它们有无数种,但这个基本思想实际上产生了一个非常有效的解决方案:

    第一步是计算凸包。这实际上节省了多少取决于您的数据分布,但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

    • 如果点已经按它们的坐标之一排序,格雷厄姆扫描算法会在 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 是水平的。为了数值稳定性,让我们在(1,-1)..(1,1) 之外的每个u 旋转90°。如果需要,将该区域转换为笛卡尔形式作为练习留给读者。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2023-04-04
      • 2021-11-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-08-24
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多