p5.jsで動きに生命を吹き込む:物理シミュレーションと相互作用の詩
静的なグリッドや計算されたノイズパターンが織りなす秩序の美しさ。それもまた、クリエイティブコーディングの確かな魅力の一つです。しかし、私たちの内なる視線は、しばしばその先にあるもの、すなわち「動き」の中に宿る生命の気配へと向けられます。時間と共に変化し、予測不能な軌跡を描き、まるで自らの意志で呼吸しているかのようなダイナミズムを、p5.jsのキャンバス上でいかにして描き出せるのでしょうか。本稿では、物理シミュレーションというレンズを通して、コードに生命の躍動を吹き込むための方法論と、その根底にある詩的な思考を探求します。静止した点を、相互作用する宇宙へと変えるための、最初のステップへご案内します。
動きの中に宿る生命:アルゴリズムが描く躍動
ジェネラティブアートの世界では、一つのアルゴリズムが、時に驚くほど複雑で有機的な構造を生み出します。しかし、その多くが時間軸から切り離された、一枚の絵画として完結しています。私たちが「生命らしさ」と感じるものの本質は、静的な形ではなく、その動的な振る舞いの中にあります。環境に応答し、他の存在と関わり合い、予期せぬ揺らぎを見せる。その絶え間ない変化のプロセスこそが、私たちの心を捉えるのです。
この「生命らしさ」をデジタルなキャンバス上で模倣するための最も強力なアプローチが、物理シミュレーション です。これは、現実世界の物理法則を単純化し、コードの中に再構築する試みです。重力、摩擦、風、引力、斥力といった「力」を定義し、それらがオブジェクトにどう作用するかを計算し続けることで、自律的に動く世界を創り出します。重要なのは、オブジェクトの軌道を一つ一つ手で描くのではない、ということです。私たちはただ法則を与えるだけ。あとは、その法則に従って、オブジェクトたちが自らの物語を紡ぎ始めるのです。
p5.jsにおける「力」の言語:p5.Vectorの哲学
物理シミュレーションの根幹をなす概念は「力 (force)」です。そして、p5.jsにおいて力、速度、加速度、位置といった、大きさと向きを持つ量を扱うための基本言語となるのが p5.Vector オブジェクトです。これを単なる座標 (x, y) を格納する便利なデータ構造だと考えるのは、あまりにもったいない。p5.Vector は、空間における意志の矢印であり、運動を記述するための詩的で強力な語彙なのです。
p5.Vector は、ベクトル演算のための豊富なメソッドを提供します。例えば、add() は力の合成を、mult() は力の増幅や減衰を、normalize() は力の方向だけを純粋に抽出し、limit() は力が際限なく大きくならないよう抑制します。これらは単なる数学的な操作ではありません。force.add(wind) という一行は、「オブジェクトが受ける力に、風の力が加わる」という世界の法則を記述する一行なのです。
物理シミュレーションを始めるにあたり、私たちは通常、すべての動くオブジェクトに対して、位置、速度、加速度を p5.Vector オブジェクトとして定義します。
class Mover {
constructor(x, y) {
this.position = createVector(x, y);
this.velocity = createVector(0, 0);
this.acceleration = createVector(0, 0);
}
// ...
}
位置は現在の場所を、速度はその場所が次の瞬間にどう変わるかを示し、加速度は速度が次の瞬間にどう変わるかを示します。そして、私たちが外部から加える「力」こそが、この加速度を生み出す源泉となるのです。
基本を構築する:重力と風、そして「生命」の呼吸
世界に動きを与える最初のステップは、基本的な「力」を導入することです。最もシンプルで普遍的な力は、おそらく重力でしょう。重力は、常に一定の方向(例えば、キャンバスの下方向)へと働きかける力として定義できます。
// すべてのMoverに下向きの力を加える
let gravity = createVector(0, 0.1);
mover.applyForce(gravity);
この applyForce() メソッドは、Moverクラスの内部で、受け取った力を加速度に変換する役割を担います。ニュートンの運動法則 F = ma (力 = 質量 × 加速度) を思い出してください。これを変形すると a = F / m となります。つまり、加速度は力に比例し、質量に反比例します。これをコードにすると、以下のようになります。
// Moverクラス内のメソッド
applyForce(force) {
// 質量(mass)で力を割ることで加速度に変換
// ここでは簡単のため質量を1と仮定
let f = p5.Vector.div(force, this.mass);
this.acceleration.add(f);
}
update() {
this.velocity.add(this.acceleration);
this.position.add(this.velocity);
// 次のフレームのために加速度をリセット
this.acceleration.mult(0);
}
update() メソッド内で、加速度が速度に、速度が位置に、フレームごとに次々と加算されていきます。そして最後に加速度を 0 にリセットすることで、次のフレームで計算される新しい力だけが運動に影響するようにします。これが、p5.jsにおける物理シミュレーションの基本的な心臓部です。
重力のような一定の力だけでなく、パーリンノイズ (noise()) を使って時間や場所によって揺らぐ「風」の力を生み出したり、sin() 関数を使ってオブジェクト自身が周期的に震える「呼吸」のような内的な力を与えたりすることもできます。これらの単純な力の組み合わせが、すでに複雑で予測不能な動きの萌芽となるのです。
相互作用が生み出す複雑性:群れ、流れ、そして生命群
一つのオブジェクトが自律的に動くだけでも魅力的ですが、ジェネラティブアート の真髄は、複数の要素が相互作用することで、個々の振る舞いの総和を超えた創発的なパターンが生まれる点にあります。物理シミュレーションは、この相互作用を記述するための完璧な舞台装置です。
他のオブジェクトとの距離を測り、その距離に応じて引力や斥力を働かせる。これは基本でありながら、非常に強力なテクニックです。例えば、すべてのオブジェクトがマウスカーソルから反発する力を受ければ、それだけで鑑賞者の動きに呼応する インタラクティブアート が生まれます。
さらにこの概念を発展させたものに、Craig Reynoldsが提唱した「Boids」として知られる群れのアルゴリズムがあります。これは、鳥の群れや魚の群れのような、集合的で知的な振る舞いをシミュレートするものです。個々のエージェント(Boid)は、ごく単純な3つのルールに従って行動します。
- 分離 (Separation): 近くにいる仲間とぶつからないように、少し離れる。
- 整列 (Alignment): 近くにいる仲間の平均的な進行方向に、自分の向きを合わせる。
- 結合 (Cohesion): 近くにいる仲間の重心に向かって、近づいていく。
驚くべきことに、個々のエージェントはこの3つのローカルなルールしか知らないにもかかわらず、全体として、まるで一つの巨大な生命体であるかのように、滑らかで統率の取れた群れの動きが生まれます。p5.jsでこの3つのルールをそれぞれ「力」として計算し、合成して適用することで、あなたのキャンバス上にも生命の群れを泳がせることが可能になります。
視覚化の詩学:物理法則を超えた美の探求
物理シミュレーションは、あくまでオブジェクトの「動き」を計算するためのエンジンです。その計算結果を、最終的にどのようにピクセルとして画面に定着させるか、という「視覚化」のプロセスには、無限の創造性が介在します。計算された物理量は、そのままアート表現のパラメータとなり得ます。
例えば、オブジェクトの速度 (velocity.mag()) の大きさに応じて、その色相や透明度を変化させるのはどうでしょう。速く動くものほど鮮やかな赤に、ゆっくりと漂うものは静かな青に。あるいは、オブジェクトが通過した軌跡を、時間と共に消えゆく淡い線として描き続けることで、動きそのものがドローイングの筆致となります。速度ベクトルを線の太さや向きに反映させれば、まるで風の流れを描いたような表現も生まれるでしょう。
私たちは、物理法則を厳密に再現する必要は全くありません。むしろ、アーティストとしての特権は、その法則を意図的に「破る」ことにあります。摩擦を負の値にしてオブジェクトを無限に加速させたり、画面の中心から外側に向かって常に反発する奇妙な力を加えたり。そうした非現実的な設定が、現実を超えた幻想的な美を生み出すきっかけとなります。物理シミュレーションは、現実を模倣するための道具であると同時に、未知の美を発見するためのコンパスでもあるのです。
あなたのキャンバスで世界を動かす:創作への誘い
ここまで、p5.jsで物理シミュレーションを用いて生命的な動きを創り出すための基本的な考え方とテクニックを見てきました。重力、風、反発、引力、そして群れのルール。これらは、あなたが自分自身の動的な世界を構築するための、ほんの数個の語彙に過ぎません。
ぜひ、あなたのキャンバスで、小さな実験を始めてみてください。一つの円を、重力に従って落下させてみる。マウスの位置から斥力を発生させ、円が逃げ惑う様子を観察する。そして、円の数を増やし、それらが互いに微かな引力で引き合うようにしてみる。すると、あなたの目の前で、小さな宇宙が生まれ、星雲が形成され、やがては独自の秩序を見つけ出すかもしれません。
完璧なシミュレーションを目指す必要はありません。大切なのは、コードを通して「力」という概念と対話し、アルゴリズムが生み出す予期せぬ動きの中に、あなただけの美しさや「生命らしさ」を見出すプロセスそのものです。その探求の先に、まだ誰も見たことのない、動きの詩学が待っています。


