我正在使用Javascript构建配置工具,以不同的方式计算电缆截断的测量值。基本上,您可以输入电缆数量和电缆直径。现在我想将这些电缆可视化为具有给定直径的圆形,并自动将它们打包在一起以占据尽可能小的空间。以下是两个例子:
7根电缆包装在一起:
48根电缆:
正如您所看到的,我已经尝试通过使用物理引擎(physics.js)来实现这一点,并让重力自动优化元素。这在某种程度上适用于小数字但是需要很长时间来完成大量元素(> 20)并且它并不总能产生最佳结果。除此之外,我认为这种方式有点过头了。
在给定直径为 d 的圆圈时,是否有一种计算 x 位置的简洁方法?是否有一个框架或类似的东西来处理这些任务?我很好奇你的想法,提前谢谢。哦,顺便说一句,这不是作业 - 我是35岁以上:-D
答案 0 :(得分:2)
此算法并不总能找到经过验证的最佳解决方案(这很难,因为for most numbers over 13 the best known configuration has not yet been proven to be ideal),但在大多数情况下,它至少应该提供一个“非常好”的解决方案:
- 从一个中心圆开始并将其放置
- 每增加一个圈子
- 找到最接近中心圆的角度 重叠已放置的圆圈
- 把它放在那里
此算法的时间复杂度取决于您为新圆圈找到最近位置的效率。通过一些优化,您应该能够使其与圆圈数成线性关系。这意味着算法的整体复杂性为n²
。
答案 1 :(得分:2)
如果“最小可能空间”是指“包含在最小区域”(或“由最紧密的凸包围”),您可能会发现检查article in Wikipedia about circle packing:
是有用的在二维欧几里德空间中,约瑟夫路易斯拉格朗日证明了 1773年,密度最高的圆的格子排列 是六边形的包装排列,其中心是 圆圈排列成六角形格子(交错排,像一个 蜂窝),每个圆圈被其他6个圆圈包围。
你能根据这个发现做出算法吗?我在想的是:从至少覆盖电缆数量的“平凡”六边形排列开始,然后开始在外圆上迭代并移除距离中心圆最远的那个。继续,直到剩下您需要的确切圈数。
如果你这样做,你可以节省计算“你已经知道的东西”的时间。也就是说,如果你有七个圆圈,你知道它是一个六边形,中间有一个圆圈。如果您有八个圆圈,则从12个圆圈的六边形开始,其中包含六个圆圈的六边形,其中包含一个圆圈:总共19个圆圈(12 + 6 + 1)。您开始从外六边形(带有12个圆圈的圆圈)中移除圆圈,直到您移除了11,然后以最佳排列留下8个圆圈(1 + 6 + 1)。