绘制n个没有重叠和中心重心的相同圆圈

时间:2019-03-01 10:30:06

标签: python algorithm geometry

我正在查看一组100张PowerPoint幻灯片,它们具有相同大小的红色圆圈,其中第一张幻灯片具有1个圆圈,而第100张幻灯片具有100个圆圈。在每张幻灯片上,圆圈都不重叠,并且当它们半随机放置时,它们趋向于趋向中心并且彼此之间的距离不太近(我看不到极端的异常值)。您可以自己here浏览幻灯片。

这些似乎是手工创建的(必须花很长时间!),我必须考虑最好的方式是以编程方式创建类似这样的东西(有趣的玩具问题-使无聊的东西自动化) )?

我一直在考虑以下方面。

每张幻灯片最多n圈:

  1. 在画布上的任意点生成圆的坐标。
  2. 为此圆和画布上所有其他圆计算较大的直径(对于较大的某个值),并使用计算出的较大直径检查新圆是否与任何现有圆不重叠(以防止圆过于靠近一起)。如果可以,请继续前进,否则请重新开始2。
  3. 要阻止异常值,请进行某种检查以确保新生成的圆与现有3(?)个圆的中心的距离不超过x距离?
  4. 如果所有签出位置都保留新的圆圈,然后从1开始重新进行,直到有足够的圆圈。
  5. 找到一些为每个画布生成png或其他内容的方法。

至少还需要找到一种方法使至少前几个圆圈趋向中心。

但是,尽管我想思考问题,但是我的编码工作需要工作,并且必须有某种出色的算法或正确执行此操作的东西?

对于任何指针或任何有裂缝的人都感到高兴-特别希望阅读一些python实现以从中学习。

[我知道这可能不完全适合StackOverflow风格,但是不确定是否还有其他地方可以获取有关该问题的想法]。

2 个答案:

答案 0 :(得分:0)

迭代放松将是解决此类问题的常见方法。

基本上,您首先随机放置n个圆圈。然后,您需要进行多次迭代,以尝试将圆移动到更令人满意的配置中。

对于每个圆C,您都测量到其他圆的距离,对于每个圆,您都需要计算一个将C推离另一个圆的力C。力的方向将与另一个圆的方向相反,并且大小通常与距离成反比。 (因此,力的作用与重力类似,但方向相反。)您对C上的所有力求和,类似地对所有其他圆上的力求和,然后根据上的总力将每个圆稍微移动一点。它。 (您还需要用力使圆远离边缘。)这是一次迭代,然后,圆应比以前略好更好地配置。

现在,如果您进行大量迭代,则最终可能会得到规则的六边形平铺,这看起来不会很有趣。因此,您可能要在此之前停止,或者添加另一个力以防止每个圆偏离其原始位置太远,或者忽略来自其他圆的任何力超过给定距离的力,或者如果圆的总力低于此力则不移动一个圆给定的幅度。

顺便说一句,您要做的很多事情都与smoothed-particle hydrodynamics(一种流体模拟方法)非常相似。 Here's的视频是一个基于Python的模拟,它模拟了水飞溅的球体超过100个,几乎完全基于单个球体,试图与附近的球体保持正确的距离。

答案 1 :(得分:0)

您的要求基本上意味着您想使用泊松圆盘采样来选择圆心:

https://www.jasondavies.com/poisson-disc/

...所以至少有很多关于它的文献。

除了“重心”之外,这一切都会为您提供。有几种不同的方法可以做到这一点,但是最简单的方法是在较小的区域中生成圆,然后将边缘拉伸。

例如,您可以将每个圆从幻灯片的中心移开,以使距离 d 的圆移动到距离 d ^ 1.5 左右。