【问题标题】:Draw n identical circles without overlap and centre gravity画n个相同的圆,不重叠,不重心
【发布时间】:2019-07-23 08:56:54
【问题描述】:

我正在查看一组 100 张具有相同大小的红色圆圈的 PowerPoint 幻灯片,其中第一张幻灯片有 1 个圆圈,第 100 张幻灯片有 100 个圆圈。在每张幻灯片上,圆圈不重叠,虽然它们是半随机放置的,但它们往往会被中心吸引,并且彼此不会太近(我看不到极端异常值)。您可以自己查看幻灯片here)。

这些似乎是手工创建的(这肯定花了很长时间!),我开始思考以编程方式创建这样的东西的最佳方法是什么(有趣的玩具问题 - 自动化无聊的东西)?

我一直在考虑以下几点。

每张幻灯片最多 n 圈:

  1. 为画布上随机点处的圆生成坐标。
  2. 为此圆和画布上已有的所有其他圆计算更大的直径(对于更大的值),并使用计算出的更大直径检查新圆是否与任何现有圆重叠(以阻止圆太靠近一起)。如果可以,请继续,否则重新开始 2。
  3. 要阻止异常值,请进行某种检查以确保新生成的圆距 3(?) 个现有圆的中心不超过 x 距离?
  4. 如果所有签出,请保留新圈并再次从 1 开始,直到有足够的圈。
  5. 想办法为每个画布生成一个 png 或其他东西。

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

但是,虽然我喜欢思考问题,但我的编码能力需要工作,并且必须有某种出色的算法或其他东西才能正确地做到这一点?

很高兴任何指针或任何人都可以破解它 - 特别喜欢阅读一些 Python 实现来学习。

[我知道这可能不完全符合 StackOverflow 的风格,但不知道从哪里获得有关问题的想法]。

【问题讨论】:

  • 如何在光盘上“均匀”分布点(这是一个众所周知的问题)然后剪切/拉伸光盘?
  • 谢谢@norok2,我会看看。

标签: python algorithm geometry


【解决方案1】:

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

基本上,您从随机放置 n 个圆圈开始。然后,您进行多次迭代以尝试将圆圈移动到更令人愉悦的配置中。

对于每个圆 C,您测量到其他圆的距离,对于每个圆,您计算一个力 C,它将 C 推离另一个圆。力的方向将与另一个圆的方向相反,其大小通常与距离成反比。 (所以力的行为类似于重力,但方向相反。)你将 C 上的所有力相加,类似地将所有其他圆上的力相加,然后根据 C 上的总力移动每个圆一点它。 (您还需要一个力使圆圈远离边缘。)这是一次迭代,之后,圆圈的配置应该比以前好。

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

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

【讨论】:

  • 酷!有点跑题了,但是……你是强制执行周期性边界条件还是其他什么?
  • @norok2 哦,那不是我的东西。自从我对 SPH 做任何事情以来已经有好几年了。
  • 这真的很有趣。不会像物理问题一样思考这个问题。很酷。
【解决方案2】:

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

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

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

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

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

【讨论】:

  • 非常感谢 - 将对此进行更多调查。
猜你喜欢
  • 2014-09-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-06-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多