【问题标题】:How to optimally displace two polygons?如何以最佳方式置换两个多边形?
【发布时间】:2014-11-02 04:39:52
【问题描述】:

给定两个凸多边形(可能重叠也可能不重叠),它们应该以“最紧密的方式”布局(使它们不重叠 - 参见 cmets)。 (即它们应该占用尽可能少的屏幕空间。)正式地,让我们将“最紧密的可能方式”定义为边界框具有最小面积的方式(但我也对其他合理的定义持开放态度:) )。 (注意:这里的一切都是 2D 的。)一个好处是甚至考虑边界框的边的比例(例如,它应该是 16:9),但我怀疑问得太多了:)。

是否有比蛮力更好的算法来做到这一点? (蛮力就像将它们布置在“所有可能的”方向并计算边界框的面积。)我一直在寻找解决方案,但我还没有找到;虽然这对我来说不是一个非常独特的问题......


这就是我现在所做的(接近上述要求):我将一个多边形固定 (p1) 并计算其中心点 (c1)。然后我在p1 的抑扬符上找到最接近c1 的点(我们称之为x)。 (注意:(c1, x) 向量将定义p2 的移动方向。)然后我们将分离轴定义为与(c1,x)x 处垂直的线。 (这两个多边形最后会在x 接触。)然后我计算 y,它是p2(!) 在(x,c1) 方向上离分离轴最远的点(矢量反转!);让我们称它的距离为d。然后我将p2(c1,x) 的方向移动d

它确保p2 尽可能靠近p1 的中心 - 不幸的是,仅限于p1。但它没有考虑p2 的形状,因此可能通过选择不同的位移方向将它们放置得“更紧”。

【问题讨论】:

  • “layed out”意味着它们不会在新位置重叠,对吧?
  • 你在使用任何框架吗?有一些算法和索引可能能够为您处理其中的一些,或者至少大大提高速度。
  • @japreiss:是的,我就是这个意思
  • 边界框可能无法给出正确的图片。紧密对齐的多边形集可能有更大的 AxisAligned BB.... 凸面外壳可能更适合该法案
  • @radpin:不,但如果有帮助的话我可能会(目前是准系统 Javascript)——你认为什么样的框架?

标签: math graphics geometry polygon computational-geometry


【解决方案1】:

由于您没有指定收容条件,

如果一个小于另一个,则将其放入较大的多边形内。那是最紧身的:)

否则对齐中心,并旋转其中一个直到凸包/ BB 最小。

编辑

好的,我稍后会阅读有关非重叠的 cmets .. :)

因此,取一个多边形,并将其所有边与所有其他多边形边重叠,面积最小的方向获胜。这绝对是 O( 2 * N1 * N2 ) // 2 张幻灯片来匹配每个重叠的顶点。

边的重叠使得多边形的中心仅朝向共享边的相对边。由于它们都是凸多边形,因此如果其中一个边重叠,它们不会相交,因此不会重叠。

【讨论】:

  • 区域是否重叠?而且我也不知道他是否可以轮换
  • 本来我不会轮换的;如果这有很大帮助,我可能会考虑轮换其中一个。 (看这是一个“软”问题:最终用户的期望是整个事情应该“看起来不错”:)。)
  • 我猜测旋转它们并将其中一个边缘本身作为分离轴会给你带来更紧密的结果。但是然后看看什么对你最有帮助.. :)
【解决方案2】:

有趣的问题我会这样处理:

  1. 将多边形转换为安全距离

    • 计算边界框
    • 平移一个多边形,使边界框almost 接触且不重叠
    • ax0,ax1,ay0,ay1 成为一个多边形(顶部)的边界框
    • bx0,bx1,by0,by1 是另一个(底部)的边界框
    • ay0<=ay1 , by0<=by1 , up 表示 y 轴 + 方向
    • 所以dy = by1 - ay0 + d
    • 其中dy 是第一个(红色)多边形的平移(只需将其添加到所有 y 坐标)
    • d是你想要的他们之间的安全间隙
  2. 找出多边形的下半部分和上半部分

    • 喜欢这张图片:
    • 按 CW 对顶点进行排序
    • 然后计算每个顶点的dx=x(i)-x(i-1)
    • 如果dx > 0是上半部分,否则是下半部分
  3. 现在尝试将红色多边形向下移动

    • 您必须只检查顶部多边形的底部
    • 底部多边形的顶部
    • 这应该会加快速度
    • 移动步长应该是min(d,ay1-ay0,by1-by0)的一小部分
    • 现在只需将顶部多边形逐步向下移动
    • 如果相邻两半之间没有相交,则重复上一步
    • 否则将顶部多边形向上移动安全间隙 > 步骤,这就是解决方案

[备注]

  • 您应该处理边界框不重叠(并排)等边缘情况
  • 将线的接触处理为交点
  • 您可以尝试两种变体(第一个是哪个多边形,第二个是哪个多边形)并选择更好的解决方案
  • 在展位上下半部分设置顶点dx==0 可能更安全

【讨论】:

  • 谢谢。如果我理解正确,您的不会尝试在“b”周围“移动”“a”多边形 - 这样如果“a”最初是“b”的“左上角”,它就会卡在那里。 (我知道它在技术上没有正确描述,但我希望你明白这一点。)我将使用我当前的 - 绝对不是最佳的 - 解决方案编辑原始帖子。
  • @fastcatch 是的,它只是在 y 轴上向上/向下移动,因为您的原始问题文本倾斜......对于一般的 2D 移位,这将是一般的装箱问题......应该有很多关于这里的问题......如果多边形并排,你可以随时停止如果新的ay1 <= by1 ...
  • 你确定它是否是 bin-packing-hard 吗?因为那是 NP 难的,因此尝试所有可能的方向是最好的方法。
  • 如果你可以在任何方向移动和/或旋转(没有一些特定的约束)那么是的,你唯一能做的就是使用一些启发式或质量/复杂性妥协,比如凸包......有时是场方法得到了很好的简单和快速的结果,但它不稳定......
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2014-09-11
  • 2011-08-16
  • 1970-01-01
  • 1970-01-01
  • 2012-02-06
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多