10

我正在做这个基于浏览器的实验,给我 N 个特定的圆圈(假设它们有一张独特的图片),并且需要将它们放在一起,尽可能少地在它们之间留出空间。不一定非要排成一圈,但要“成群”在一起。

圆的大小是可定制的,用户可以通过拖动 javascript 滑块来更改大小,更改一些圆的大小(例如,在 10% 的滑块中,圆 4 的半径为 20px,圆 2 为 10px,圆5保持不变,等等......)。正如您可能已经猜到的那样,我将尝试在移动滑块时平滑地“转换”调整大小-重新定位。

到目前为止我尝试过的方法:我尝试使用物理引擎而不是手动尝试定位它们 -

我的方法示例

想法:

  1. 在屏幕中心放置某种引力
  2. 使用物理引擎来处理球碰撞
  3. 在“拖动时间”滑块事件中,我只需设置不同的球尺寸,让引擎负责其余的工作

对于这个任务,我使用了“box2Dweb”。我在屏幕中心放置了一个引力,然而,直到球被放置在中心并漂浮起来花了很长时间。然后我把一个小的静态球放在中心,这样他们就会击中它然后停下来。它看起来像这样:

box2d 试用版

结果稍微好一点,但圆圈在静止之前仍然移动了一段时间。即使在玩弄了诸如球摩擦和不同引力之类的变量之后,整个东西也只是漂浮着,感觉非常“摇摆不定”,而我希望球只有在我拖动时间滑块时才移动(当它们改变大小时)。另外,box2d 不允许更改对象的大小,我将不得不破解我的方法来解决问题。

所以,box2d 方法让我意识到,也许让物理引擎来处理这个问题并不是解决问题的最佳方案。或者也许我必须包括一些我没有想到的其他力量。我在 StackOverflow 上发现了与我类似的问题。然而,非常重要的区别是它只“一次”生成一些 n 个非特定的圆圈,并且不允许额外的特定球大小和位置操作。

我现在真的被困住了,有没有人有任何想法如何解决这个问题?

更新:现在已经快一年了,我完全忘记了这个线程。我最终所做的是坚持物理模型并在几乎空闲的条件下重置力/停止。结果可以在这里看到http://stateofwealth.net/ 你看到的三角形在这些圆圈内。其余的线通过“delaunay triangulation algorithm”连接

4

3 回答 3

5

我记得看到一个与您所描述的非常相似的d3.js演示。它是由 Mike Bostock 自己写的:http: //bl.ocks.org/mbostock/1747543

d3.js圈装截图

它使用四叉树进行快速碰撞检测并使用基于力的图,它们都是 d3.js 实用程序。

tick函数中,您应该能够添加一个在更改数据.attr("r", function(d) { return d.radius; })时更新每个刻度的半径。nodes只是对于初学者,您可以将其设置为随机返回,并且圆圈应该像疯了一样抖动。

于 2013-07-16T21:15:51.357 回答
1

(不评论,因为它不适合)

我对您引入 Box2D 来帮助进行繁重的工作印象深刻,但不幸的是,它可能不太适合您的要求,因为 Box2D 在您模拟刚性物体及其碰撞动力学。

我认为,如果您真的考虑到您需要什么,那么它根本就不是刚体动力学问题。您实际上不需要 box2d 的复杂性,因为您的所有几何图形都由球体组成(我保证您比任意凸多边形建模要简单得多,这就是 IMO Box2D 的复杂性产生的原因),并且就像您提到的那样,Box2D 无法平滑地更改几何参数并没有帮助,因为它会使浏览器陷入不必要的几何分配和解除分配,并且无法应用任何类型的平滑动画。

您可能正在寻找一种算法或方法来演变一组坐标的位置(每个坐标的半径也可能发生变化),以便它们保持半径分开,并最大限度地减少它们与中心位置的距离。如果这必须是平滑的,您不能每次都应用最小的解决方案,因为您可能会“变形”,因为最佳配置可能会在滑块移动的特定点发生显着变化。我只想说你要做很多调整,但没有什么比在 Box2D 内部必须应对的更可怕的了。

你的圈子不重叠有多重要?我认为您应该只做一个简单的迭代“求解器”,首先尝试将圆圈带向它们的目标(屏幕中心?),然后尝试根据半径将它们分开。

我相信如果你尝试为你想要的运动想出一个简化的数学模型,它会比试图让 Box2D 去做更好。Box2D 很神奇,但它只擅长它擅长的事情。

于 2013-07-16T19:33:16.797 回答
0

至少对我来说,似乎最简单的解决方案是首先在集群中设置圆圈。所以首先将最大的圆圈放在中心,将第二个圆圈放在第一个圆圈旁边。对于第三个,你可以把它放在第一个圆圈旁边,然后沿着边缘移动它,直到它碰到第二个圆圈。在此处输入图像描述

所有其他圆都可以遵循相同的方法:将它放在任意圆旁边,然后沿着边缘移动它,直到它接触到另一个圆,但不相交。请注意,这不会使其成为最有效的集群,但它可以工作。之后,当你扩大,比如说,圈 1,你会向外移动所有相邻的圈,然后将它们移动以重新聚集。

于 2013-07-16T21:43:55.900 回答