物理シミュレーションに影響を与えた3冊 — 203個の実装を支えた知識の源泉
このトピックを深掘りする
Web Audio・サウンドプログラミング
Web Audio APIによる音響合成・楽器実装・物理シミュレーション参考文献
全3本中 3 本目。
次に読む記事
シリーズ全体の流れを見ながら、次に読む記事へ進めます。 初めての方はホームへ →
はじめに
sakimytocomには現在211個のインタラクティブデモがある。そのうち物理法則や数学的アルゴリズムを使っているものは100個を超える。パーティクルシステム、流体シミュレーション、群れの知能、衝突判定、振り子、波動方程式——これらを独学で実装するにあたり、特に影響を受けた3冊の本がある。
この記事では「どの本のどの章を読んで、どのコンポーネントを作ったか」を具体的に書く。書評ではなく、実装者の視点からの読書記録だ。抽象的な「おすすめ本リスト」ではなく、「この章のこの概念が、このコンポーネントのこの部分に直接使われている」というレベルで紹介したい。
プログラミングで物理シミュレーションを書きたい人にとって、最初に手に取るべき本の参考になれば嬉しい。
1冊目: The Nature of Code(Daniel Shiffman)
この本がなければ、sakimytocomの物理シミュレーションの半分は存在しない。それくらい決定的な一冊だった。
Daniel ShiffmanはProcessingの教育者として知られていて、この本はProcessing(Java)で自然現象をシミュレーションする方法を体系的に教えてくれる。ベクトル、力、パーティクルシステム、自律エージェント、セルオートマトン、フラクタル、遺伝的アルゴリズムと、物理シミュレーションの基礎がほぼ網羅されている。
Vectorクラスの設計 → physics.ts の Vec2 型
The Nature of Codeの第1章は「ベクトル」だ。PVector(ProcessingのVectorクラス)の設計思想——位置・速度・加速度をすべてベクトルとして扱い、add, sub, mult, normalize といった操作を定義する——は、そのまま physics.ts の Vec2 型の原型になった。
type Vec2 = { x: number; y: number }Processingではクラスベースで PVector.add() と書くところを、TypeScriptでは純粋関数 addVec(a, b) として実装した。状態を持たないほうがReactのレンダリングモデルと相性がいい。この「クラスベース → 関数 + useRef」への変換パターンは、Processingのコードを移植するときに何度も使うことになる。
Boids(群れの知能) → Boids.tsx
第6章「Autonomous Agents」のBoidsアルゴリズムは、最も感動した章の一つだ。たった3つのルール——separation(分離)、alignment(整列)、cohesion(結合)——で、鳥の群れのような複雑な動きが生まれる。
Boids.tsxでは、separationの影響範囲を25px、alignmentとcohesionを50pxに設定している。この数値は本の推奨値をベースに、ブラウザの画面サイズに合わせて調整したものだ。本を読まなければ、これらのパラメータが何を意味するのか理解できなかっただろう。
Shiffmanの説明で特に良かったのは、各ルールの力を「ステアリングフォース」として計算する方法だ。目標速度と現在の速度の差分が操舵力になる。この考え方は直感的で、コードに落としやすい。
パーティクルシステム → ParticleField.tsx
第4章「Particle Systems」は、ParticleField.tsxの直接的な設計図だ。パーティクルの生成、速度の減衰、寿命管理、エミッターの概念。本で学んだ構造をそのまま使っている。
ParticleField.tsxでは、マウスカーソルからの斥力をパーティクルに与えている。カーソルに近いパーティクルほど強い力で弾かれる。これは本の「引力と斥力」の章(第2章)で学んだ逆二乗の法則を応用したものだ。距離の二乗に反比例する力を、斥力として符号を反転させるだけ。シンプルだが、インタラクションとしては非常に気持ちいい動きになる。
Reaction-Diffusion → ReactionDiffusion.tsx
第7章で紹介されるReaction-Diffusionは、Gray-Scottモデルの実装手順がほぼそのまま使えた。2つの化学物質の拡散と反応をラプラシアンで計算する。本ではProcessingのピクセル操作で実装しているが、Canvas APIの getImageData / putImageData に置き換えるだけでほぼ同じコードが動く。
feed rateとkill rateの2つのパラメータで、斑点、縞模様、迷路状のパターンが生まれる。パラメータ空間の探索は本に載っている表を参考にした。
Processing → TypeScript変換のコツ
The Nature of Codeのコードを移植する際に身につけたパターンをまとめると:
setup()→useEffectの初期化処理draw()→requestAnimationFrameループ- グローバル変数 →
useRef - PVectorクラス → 純粋関数(
addVec,subVec,scaleVec) mouseX, mouseY→ PointerEvent の座標をuseRefで保持
このパターンさえ覚えれば、Processing系のサンプルコードは機械的にTypeScript + Canvasに変換できる。
2冊目: ゲーム開発のための数学・物理学入門
The Nature of Codeが「何を作るか」を教えてくれるなら、この本は「なぜそう動くか」を教えてくれる。数式の導出過程を丁寧に説明してくれるのが最大の特徴だ。
衝突判定の数学 → physics.ts
physics.ts の detectCollision と resolveCollision は、この本の衝突判定の章をほぼそのまま実装したものだ。円同士の衝突判定(中心間距離と半径の和の比較)、衝突法線の計算、インパルスベースの衝突応答。
特に衝突応答のインパルス計算は、この本の導出を追わなければ理解できなかった。「なぜ反発係数がこの位置に入るのか」「なぜ質量の逆数で按分するのか」が、運動量保存則とエネルギー保存則から丁寧に導かれている。式を暗記するのではなく、導出を理解できたから、パラメータを変えたときに何が起こるか予測できるようになった。
反射ベクトル → Breakout, Pinball
Breakout.tsxでボールが壁やブロックに当たって跳ね返る計算、Pinball.tsxでボールがバンパーに当たる計算。どちらも反射ベクトルの公式を使っている:
v' = v - 2(v · n)n入射ベクトル v を法線ベクトル n で反射する。この公式自体は短いが、「なぜ内積が出てくるのか」「なぜ2倍するのか」を幾何学的に理解するにはこの本の図解が不可欠だった。入射ベクトルを法線方向成分と接線方向成分に分解し、法線方向成分だけを反転させる——という直感的な理解は、この本から得たものだ。
運動方程式の離散化 → Symplectic Euler
physics.ts の積分関数はSymplectic Euler法を使っている。通常のEuler法(位置を先に更新)ではなく、速度を先に更新してから位置を更新する。
// Symplectic Euler
vel.x += acc.x * dt
vel.y += acc.y * dt
pos.x += vel.x * dt
pos.y += vel.y * dtたった2行の順序の違いだが、エネルギー保存性が劇的に改善する。この本は「なぜ通常のEuler法だとエネルギーが発散するのか」を、1次元のバネの例で視覚的に説明してくれる。この説明を読んで、sakimytocomのすべてのシミュレーションをSymplectic Eulerに統一した。
回転と角速度 → DoublePendulum
DoublePendulum.tsxではラグランジュ力学を使っているが、その前提知識として「角速度とは何か」「トルクとは何か」を理解する必要がある。この本の回転運動の章が、まさにその基礎を与えてくれた。
角速度ω、角加速度α、慣性モーメントI、トルクτ。これらの概念と、線形運動(v, a, m, F)との対応関係が表でまとめられていて、回転を「線形運動のアナロジー」として理解できた。
「なぜそうなるか」を教えてくれる本
この本の最大の価値は、数式を「結果」ではなく「過程」として示してくれることだ。教科書的に「この公式を使え」ではなく、「こういう前提条件から、こう式変形すると、この結果になる」と導いてくれる。
結果として、公式を覚えるのではなく、公式を導出する能力が身についた。これは既存の公式がない状況——たとえば独自のゲームメカニクスを考えるとき——に非常に役立つ。
3冊目: プログラミングのための線形代数
この本は物理シミュレーションの本ではない。線形代数の本だ。しかし、物理シミュレーションを書く上で最も根底的な理解を与えてくれた。
座標変換 → Canvas の translate / rotate / scale
Canvas APIでは ctx.translate()、ctx.rotate()、ctx.scale() を組み合わせて描画座標系を変換する。これらの操作が「行列の積」であることを、この本で初めて理解した。
たとえば「原点を中心に回転してから平行移動する」と「平行移動してから回転する」では結果が違う。これは行列の積が非可換(AB ≠ BA)だからだ。この理解があるかないかで、Canvas上での複雑な座標変換のデバッグ効率が圧倒的に変わる。
SolarSystem.tsxでは、太陽を中心に惑星が公転し、惑星を中心に衛星が公転する。この入れ子の回転は、座標変換の合成として実装している。ctx.save() / ctx.restore() で変換行列をスタックに積む操作が、行列のスタックそのものだと分かったとき、CanvasのAPIが完全に腑に落ちた。
固有値・固有ベクトル → 振動系の理解
固有値と固有ベクトルは、線形代数の中でも特に抽象的な概念だ。この本では「変換しても方向が変わらないベクトル」という直感的な説明から入る。
物理シミュレーションでは、固有値は振動系の固有振動数に対応する。二重振り子のような結合振動系では、固有モードが2つあり、それぞれ固有の振動数を持つ。この概念を理解していると、シミュレーション結果が「合っているか」の定性的な判断ができる。
主成分分析(PCA)のためではなく、物理現象の固有モードを理解するために固有値を学んだ——というのは、やや珍しいルートかもしれない。
行列の意味 → 「行列は変換」
この本を読む前と後で、最も大きく変わったのは「行列」に対する直感だ。
読む前: 行列は数字の表。計算方法は知っているが、何のためにあるか分からない。 読んだ後: 行列は空間の変換。回転、拡大縮小、せん断、射影——すべてが行列で表現できる。
この直感を得たことで、Canvas上の座標操作が「行列を掛けている」という意識で書けるようになった。バグが出たときも「どの変換行列が間違っているか」で切り分けられる。デバッグの速度が体感で3倍以上になった。
物理シミュレーションの本質
この本を通じて到達した結論は、「物理シミュレーションは結局、行列の掛け算と微分方程式の離散化に帰着する」ということだ。
座標変換は行列の積。運動方程式は微分方程式のEuler積分。衝突応答は法線方向と接線方向への射影(内積)。すべてが線形代数の基本操作に還元される。この見通しが得られたことで、新しいシミュレーションを実装するときの「何から手をつけるか」が明確になった。
補足: 数学ガール(結城浩)
直接的に実装に使った本ではない。しかし、この本がなければ上の3冊を読み通せなかっただろう。
数学ガールは、高校生の主人公たちが数学の問題を対話形式で解いていく小説だ。フィボナッチ数列、素数、テイラー展開、フーリエ級数——ストーリーの中で数学的概念が自然に導入される。
FourierSeries.tsxを作ったとき、フーリエ級数の直感的な理解——「任意の周期関数はsin波の重ね合わせで表現できる」——は、この本のフーリエの章から得たものだ。数式の細部は後から教科書で確認したが、「何をやっているか」の大枠はこの本で掴んだ。
数学ガールの最大の価値は、数学を「解くもの」から「楽しむもの」に変えてくれたことだ。数式を見て「面白そう」と思えるようになった。この姿勢の変化は、技術的なスキルよりもはるかに重要だったと思う。数学に対する恐怖心がなくなれば、どんな教科書でも開ける。
書籍の使い方: 「必要な章だけ読む」
ここで紹介した3冊を、1ページ目から最後まで通読したわけではない。実装で詰まったときに、該当する章を引く——辞書的な使い方をしている。
たとえばNavier-Stokes方程式を実装するとき。The Nature of Codeの流体の章で全体の構造を掴み、ゲーム物理本の微分方程式の章で離散化の方法を確認する。2冊を行き来しながら、必要な知識だけをピックアップする。
この使い方が可能なのは、3冊それぞれの守備範囲が異なるからだ:
- The Nature of Code: 「何を作るか」のレシピ集。実装の全体像を掴むのに最適
- ゲーム開発のための数学・物理学入門: 「なぜそうなるか」の導出集。数式の意味を理解するのに最適
- プログラミングのための線形代数: 「すべての基礎」。座標変換と行列の関係を理解するのに最適
「教科書は辞書。1ページ目から読む必要はない」——これは物理シミュレーションを独学する上で、最も重要な心構えかもしれない。分からない章は飛ばす。今の実装に必要な章だけ読む。そして実装してみる。動いたら次へ進む。動かなかったらもう一度読む。このサイクルが最も効率的だった。
まとめ:物理シミュレーション書籍
211個のインタラクティブデモを支えた知識の源泉は、突き詰めると3冊に集約される。
- The Nature of Code — 自然現象のシミュレーションレシピ。パーティクル、Boids、Reaction-Diffusionなど、「何を作るか」を教えてくれる
- ゲーム開発のための数学・物理学入門 — 衝突判定、反射、積分法の数学的基礎。「なぜそう動くか」を教えてくれる
- プログラミングのための線形代数 — 座標変換、行列、固有値。すべてのシミュレーションの根底にある数学を教えてくれる
この3冊で、物理シミュレーションの90%はカバーできる。残りの10%——ラグランジュ力学、Gray-Scottモデルの詳細なパラメータ、Navier-Stokes方程式の安定化手法など——は、Wikipediaと論文で補える。
物理シミュレーションを書きたいが数学に自信がない人には、まず数学ガールを勧める。数学を楽しめるようになったら、The Nature of Codeで実装の全体像を掴む。数式の意味を深く知りたくなったら、残りの2冊を辞書的に引く。この順番が、最も挫折しにくいルートだと思う。