10

私はこのブラウザベースの実験に取り組んでおり、N個の特定の円が与えられ(それらに一意の画像があるとしましょう)、それらを一緒に配置する必要があり、それらの間に可能な限り小さなスペースを残す必要があります. 円状に配置する必要はありませんが、一緒に「クラスター化」する必要があります。

円のサイズはカスタマイズ可能で、ユーザーは JavaScript スライダーをドラッグしてサイズを変更し、いくつかの円のサイズを変更できます (たとえば、スライダーの 10% では、円 4 の半径は 20px、円 2 は 10px、円は円になります)。 5 は同じままなど...)。すでにご想像のとおり、スライダーが移動しているときに、サイズ変更と再配置をスムーズに「移行」しようとします。

私がこれまでに試したアプローチ: 手動で配置しようとする代わりに、物理エンジンを使用しようとしました-

私のアプローチ例

アイデア:

  1. 画面の中央にある種の引力を配置する
  2. 物理エンジンを使用してボールの衝突を処理する
  3. 「ドラッグ ザ タイム」スライダー イベントでは、さまざまなボール サイズを設定し、残りはエンジンに任せます。

このタスクでは、「box2Dweb」を使用しました。画面の中央に引力を置いたのですが、ボールが中央に配置されて浮き上がるまでに非常に時間がかかりました。次に、小さな静的なボールを中央に配置して、ボールにぶつかって停止するようにしました。次のように見えました。

box2dトライアル

結果は少し良くなりましたが、円は静止する前にしばらく動いていました。ボールの摩擦やさまざまな引力などの変数をいじった後でも、全体が浮いていて、非常に「グラグラ」しているように感じましたが、タイム スライダーをドラッグしたとき (サイズが変わったとき) にのみボールを動かしたかったのです。さらに、box2d ではオブジェクトのサイズを変更できないため、回避策としてハックする必要があります。

そのため、box2d のアプローチにより、これを処理するために物理エンジンをそのままにしておくことは、問題の最善の解決策ではないことに気付きました。あるいは、私が思いもよらなかった他の力を含めなければならないかもしれません。StackOverflow で、この同様の質問を見つけました。ただし、非常に重要な違いは、n 個の不特定の円を「一度に」生成するだけで、特定のボールのサイズと位置をさらに操作できないことです。

私は今本当に立ち往生しています。誰もこの問題に取り組む方法を知っていますか?

更新: ほぼ 1 年が経ちましたが、このスレッドのことを完全に忘れていました。私が最後にしたことは、物理モデルに固執し、ほとんどアイドル状態で力をリセット/停止することです。結果はここで見ることができますhttp://stateofwealth.net/ あなたが見る三角形はそれらの円の中にあります. 残りの線は「ドロネー三角形分割アルゴリズム」を介して接続されます

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

少なくとも私にとっては、最初にクラスター内に円を設定するのが最も簡単な解決策のようです。最初に最大の円を中央に置き、2 番目の円を最初の円の隣に置きます。3 つ目は、最初の円の隣に置いて、2 つ目の円に当たるまで端に沿って移動します。ここに画像の説明を入力

他のすべての円は、同じ方法に従うことができます: 任意の円の隣に配置し、別の円に接触するが交差しないまでエッジに沿って移動します。これは最も効率的なクラスタリングにはなりませんが、機能することに注意してください。その後、たとえば円 1 を拡大すると、隣接するすべての円を外側に移動し、それらを移動して再クラスター化します。

于 2013-07-16T21:43:55.900 に答える