見出し画像

⚛️d3.forceSimulationリファレンス


https://editor.p5js.org/setapolo/sketches/WleE17Ltm

d3-force


このモジュールは、粒子上の物理的な力をシミュレートするための速度Verlet数値積分器を実装しています。シミュレーションは単純化されており、各ステップに一定の単位時間ステップΔt = 1、すべての粒子に一定の単位質量m = 1を仮定しています。その結果、粒子に作用する力Fは、時間間隔Δtにわたって一定の加速度aに相当し、粒子の速度に加算し、それを粒子の位置に加算するだけでシミュレーションが可能となります。

ここでいうフォースとは,ノードの位置や速度を変更する関数のことで,電荷や重力などの古典的な物理的力を適用することもできるし,ノードをバウンディングボックス内に収める,あるいはリンクしたノードを一定の距離だけ離すなど,幾何学的な制約を解消することもできる

指定されたノードの配列を持ち、力を持たない新しいシミュレーションを作成します。nodes が指定されない場合は、空の配列がデフォルトとなります。シミュレーションは自動的に開始されます。simulation.onを使用して、シミュレーションの実行中にtickイベントを待ちます。シミュレーションを手動で実行したい場合は、simulation.stopを呼び出し、必要に応じてsimulation.tickを呼び出してください。


simulation.tick([iterations])

指定された反復回数だけシミュレーションを手動でステップし、そのシミュレーションを返します。iterationsが指定されていない場合は、デフォルトで1(シングルステップ)となります。

各イテレーションでは,現在のアルファ値を(alphaTarget - alpha)×alphaDecayでインクリメントし,登録されている各フォースを新しいアルファ値を渡して起動し,各ノードの速度をvelocity×velocityDecayでデクリメントし,最後に各ノードの位置をvelocityでインクリメントする,という処理が行われます.

このメソッドはイベントをディスパッチしません.イベントをディスパッチするのは,シミュレーションが作成時に自動的に開始されたとき,あるいはsimulation.restartを呼び出したときに内部タイマーによって行われます.シミュレーション開始時の自然な秒数は⌈log(alphaMin) / log(1 - alphaDecay)⌋で、デフォルトでは300秒です。

このメソッドは、simulation.stopと併用して、静的なフォースレイアウトを計算することができます。大きなグラフの場合は、ユーザーインターフェースをフリーズさせないために、静的レイアウトをウェブワーカーで計算する必要があります。

# simulation.nodes

nodesが指定された場合,シミュレーションのノードを指定されたオブジェクトの配列に設定し,必要に応じて位置と速度を初期化し,束縛された力を再初期化して,シミュレーションを返します.nodesが指定されていない場合は,コンストラクタで指定されたシミュレーションのノードの配列を返します.

各ノードはオブジェクトでなければなりません.以下のプロパティは,シミュレーションによって割り当てられます.

index - ノードに対するゼロベースのインデックス
x - ノードの現在のx位置
y - ノードの現在のy位置
vx - ノードの現在のx-速度
vy - ノードの現在のy-速度

ノードを所定の位置に固定するには、さらに2つのプロパティを指定することができます。

fx - ノードの固定Xポジション
fy - ノードの固定されたYポジション

固定されていたノードの固定を解除するには、node.fx および node.fy を null に設定するか、これらのプロパティを削除します。

フォースは通常、ノードの現在の位置⟨x,y⟩を読み取り、ノードの速度⟨vx,vy⟩に加算(または減算)します。しかし、力はノードの予想される次の位置、⟨x + vx,y + vy⟩を「先読み」することもできます。これは、反復的な緩和によって幾何学的制約を解決するために必要です。

フォースのセンタリング

センタリングフォースは,すべてのノードの平均位置(すべてのノードの重量が等しい場合は質量中心)が所定の位置⟨x,y⟩になるように,ノードを一様に移動させます.この力は,各アプリケーション上のノードの位置を修正するもので,速度は修正しません.そうすると,ノードがオーバーシュートしたり,目的の中心の周りで振動したりするからです.この力は、ノードをビューポートの中心に保つのに役立ち、ポジショニング力とは異なり、ノードの相対的な位置を歪めません。

リンク力は,希望するリンク距離に応じて,リンクされたノードを押したり離したりする。力の強さは、リンクされたノードの距離と目標とする距離の差に比例し、バネの力のようになります。

The many-body (or n-body) force

多体(またはn体)力は、すべてのノード間で相互に適用されます。正の力であれば重力(引力)を,負の力であれば静電(斥力)をシミュレートするのに利用できます.この実装では、四分木とバーンズハット近似を使用してパフォーマンスを大幅に向上させていますが、精度はthetaパラメータでカスタマイズできます。

リンクはリンクされた2つのノードにしか影響を与えませんが、電荷力はグローバルなものです。つまり、すべてのノードが他のすべてのノードに影響を与え、たとえそれらが切断されたサブグラフ上にあっても影響を与えます。

四分木(しぶんぎ、英: Quadtree)は、各内部ノードが4個までの子ノードを持つ木構造のデータ構造である。四分木は主に、2次元空間を再帰的に4つの象限または領域に分割するのに使われる。

Barnes-Hutシミュレーション(Josh BarnesとPiet Hutにちなんで命名)は,n体シミュレーションを行うための近似アルゴリズムである.直接和をとるアルゴリズムがO(n2)であるのに対し、O(n log n)のオーダーを持つことが特徴である

シミュレーションボリュームは、通常、オクトリー(3次元空間)を介して立方体のセルに分割され、近くのセルの粒子のみを個別に処理する必要があり、遠くのセルの粒子は、セルの重心を中心とした1つの大きな粒子として処理することができます(または、低次多極展開として処理することができます)。これにより、計算しなければならない粒子ペアの相互作用の数を劇的に減らすことができます。

3次元のn体シミュレーションでは、Barnes-Hutアルゴリズムが再帰的にn体を8分木(2次元シミュレーションでは4分木)に格納してグループに分割します。このツリーの各ノードは、3次元空間の領域を表しています。

一番上のノードは空間全体を表し、その8つの子ノードは空間のオクタンを表します。

空間は再帰的にオクタンに細分化され、各細分化された部分に0または1のボディが含まれるようになります(すべてのオクタンにボディが存在しない領域もあります)。オクツリーには内部ノードと外部ノードの2種類のノードがあります。外部ノードは子を持たず、空であるか1つのボディを表す。内部ノードは、その下にあるボディのグループを表し、質量中心とその子ボディの合計質量を格納します。


お願い致します