问题描述
我正在做这个基于浏览器的实验,在该实验中,我得到了N个特定的圆圈(假设它们中有唯一的图片),并且需要将它们放置在一起,并在它们之间保持尽可能小的空间.它不一定要排列成圆形,但应该将它们聚集"在一起.
I am working on this browser-based experiment where i am given N specific circles (let's say they have a unique picture in them) and need to position them together, leaving as little space between them as possible. It doesn't have to be arranged in a circle, but they should be "clustered" together.
圆的大小是可自定义的,用户将可以通过拖动javascript滑块,更改某些圆的大小来更改大小(例如,在10%的滑块中,圆4的半径为20px,圆2 10px,第5圈保持不变,依此类推...).正如您可能已经猜到的那样,在移动滑块时,我将尝试平滑地转换"调整大小-重新定位.
The circle sizes are customizable and a user will be able to change the sizes by dragging a javascript slider, changing some circles' sizes (for example, in 10% of the slider the circle 4 will have radius of 20px, circle 2 10px, circle 5 stays the same, etc...). As you may have already guessed, i will try to "transition" the resizing-repositioning smoothly when the slider is being moved.
到目前为止,我尝试过的方法是:我尝试使用物理引擎,而不是手动尝试定位它们,
The approach i have tried tried so far: instead of manually trying to position them i've tried to use a physics engine-
想法:
- 在屏幕中央放置某种重力拉力
- 使用物理引擎来照顾球的碰撞
- 在拖动时间"滑块事件期间,我将设置为不同球尺寸,让引擎负责其余的事情
- place some kind of gravitational pull in the center of the screen
- use a physics engine to take care of the balls collision
- during the "drag the time" slider event i would just set differentball sizes and let the engine take care of the rest
对于此任务,我使用了"box2Dweb".我将引力拉到屏幕的中心,但是,花了很长时间才把球放到屏幕中央,然后它们才能漂浮在屏幕上.然后我将一个小的静态球放在中间,这样他们就可以击中球然后停下来.看起来像这样:
For this task i have used "box2Dweb". i placed a gravitational pull to the center of the screen, however, it took a really long time until the balls were placed in the center and they floated around. Then i put a small static piece of ball in the center so they would hit it and then stop. It looked like this:
结果要好一些,但是圆圈在静止之前仍然移动了一段时间.即使在像球的摩擦和不同的重力拉力这样的变量玩耍之后,整个东西还是漂浮着,感觉非常颤抖",而我希望球只有在我拖动时间滑块(当它们改变大小)时才移动.另外,box2d不允许更改对象的大小,因此我必须设法解决问题.
The results were a bit better, but the circles still moved for some time before they went static. Even after playing around with variables like the ball friction and different gravitational pulls, the whole thing just floated around and felt very "wobbly", while i wanted the balls move only when i drag the time slider (when they change sizes). Plus, box2d doesn't allow to change the sizes of the objects and i would have to hack my way for a workaround.
因此,box2d方法使我意识到也许让物理引擎来处理这个问题并不是解决问题的最佳方法.或者,也许我必须包括一些我没有想到的其他力量.我发现了这个类似的问题在StackOverflow上进行挖掘.但是,非常重要的区别是,它只能一次"生成n个非特定的圆,并且不允许其他特定的球尺寸和位置操纵.
So, the box2d approach made me realize that maybe to leave a physics engine to handle this isn't the best solution for the problem. Or maybe i have to include some other force i haven't thought of. I have found this similar question to mine on StackOverflow. However, the very important difference is that it just generates some n unspecific circles "at once" and doesn't allow for additional specific ball size and position manipulation.
我现在真的很困,是否有人知道如何解决此问题?
I am really stuck now, does anyone have any ideas how to approach this problem?
更新:已经快一年了,我完全忘记了这个话题.最后,我要做的是坚持物理模型,并在几乎闲置的情况下重置力/停止力.结果可以在这里看到 http://stateofwealth.net/您看到的三角形在这些圆内.其余的线通过"delaunay三角剖分算法"连接
update: it's been almost a year now and i totally forgot about this thread. what i did in the end is to stick to the physics model and reset forces/stop in almost idle conditions. the result can be seen here http://stateofwealth.net/the triangles you see are inside those circles. the remaining lines are connected via "delaunay triangulation algorithm"
推荐答案
我记得看到一个 d3.js 演示与您所描述的非常相似.它是由Mike Bostock亲自写的: http://bl.ocks.org/mbostock/1747543
I recall seeing a d3.js demo that is very similar to what you're describing. It's written by Mike Bostock himself: http://bl.ocks.org/mbostock/1747543
它使用四叉树进行快速碰撞检测,并使用基于力的图形,它们都是d3.js实用程序.
It uses quadtrees for fast collision detection and uses a force based graph, which are both d3.js utilities.
在tick
函数中,您应该能够添加.attr("r", function(d) { return d.radius; })
,当更改nodes
数据时,该值将更新每个刻度的半径.对于初学者,您可以将其设置为随机返回,并且圆圈应该像疯了似的那样抖动.
In the tick
function, you should be able to add a .attr("r", function(d) { return d.radius; })
which will update the radius each tick for when you change the nodes
data. Just for starters you can set it to return random and the circles should jitter around like crazy.
这篇关于将可调整大小的圆圈彼此靠近放置的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!