オービタルシミュレータ
実装方法の技術解説
量子化学の理論、3DCGによる曲面生成、Webアプリとしての実装を話題別に分け、現在の実装が生成している曲面を各層から記述する。 本文中の数値は概念例ではなく、実装で実際に用いている定数である。
水素原子軌道の理論的基礎
非相対論的な水素様1電子原子では、核と電子の相対運動に対する時間に依存しないSchrödinger方程式を解く。 電子と核の換算質量を とすると、Hamiltonianと固有値方程式は、
である。Coulombポテンシャルが球対称なので、固有関数は球座標で動径関数と球面調和関数へ変数分離できる。
エネルギー固有値と縮退
換算質量に対応するBohr半径を とすると、束縛状態のエネルギーは主量子数だけに依存する。
スピン、微細構造、Lamb shiftを無視すれば、固定した に対する空間軌道の縮退度は である。多電子原子では電子間反発と遮蔽により、この に関する縮退は一般に解ける。
球面調和関数
複素球面調和関数は角運動量演算子の同時固有関数である。
化学で用いる や5つのd軌道、7つのf軌道は、通常 と の複素関数から作る実線形結合である。本シミュレータの角度多項式も、この実軌道と同じ対称性と節集合を持つ。
動径関数と陪ラゲール多項式
と置くと、規格化された動径関数は次式で表される。
ここで はラゲールの陪多項式であり、Rodrigues型の定義は、
である。指数減衰、原点近傍の 、陪ラゲール多項式の零点が、それぞれ動径方向の外形と節を決める。
節の数
| 節の種類 | 個数 | 由来 |
|---|---|---|
| 動径節 | ||
| 角度節 | ||
| 全節数 |
複素 の絶対値は に依存せず、振幅の節は が与える 個である。実線形結合では または に由来する 枚の方位角方向の節面が加わり、角度節の総数は となる。
可視化モデルの位置づけ
本シミュレータは、水素様原子軌道の厳密な波動関数 を 直接等値面化したものではない。p・d・f軌道については実球面調和関数と同じ節構造を持つ斉次多項式を単位球面上で評価し、 その絶対値を方向依存半径へ写像する「振幅極座標曲面」を生成する。s軌道の動径節は同心球、3p・4p・4dの動径節は相似な角度曲面の入れ子で表す。
| 選択群 | 表示数 | 曲面種別 | 動径節数 |
|---|---|---|---|
| 1 | s | 0 | |
| 1 | s | 1 | |
| 3 | p | 0 | |
| 1 | s | 2 | |
| 3 | p | 1 | |
| 5 | d | 0 | |
| 1 | s | 3 | |
| 3 | p | 2 | |
| 5 | d | 1 | |
| 7 | f | 0 | |
| 4 | hybrid | — | |
| 3 | hybrid | — | |
| 2 | hybrid | — | |
| 4 | hybrid | — | |
| 6 | hybrid | — |
技術構成
UIと状態管理はReact 19.2.6とTypeScript、ページ構造はNext.js 16.2.6互換環境、バンドルはVinext 0.0.50とVite 8.0.13で構成する。 3D描画はThree.js 0.185.1、数式組版はKaTeX 0.18.1、レイアウト・テーマ・ブレークポイントはCSSで実装する。
- State軌道群、テーマ、曲面の透過モード、ローブ形状、メッシュ精細度をReact stateとして保持する。
- Geometry選択状態から軌道定義を取得し、CPU側でThree.js BufferGeometryを生成する。
- Scene正位相・負位相メッシュ、xyz軸、照明、透視投影カメラをカードごとに構築する。
- InteractionOrbitControlsがカメラ姿勢と距離を更新し、WebGLRendererが既存メッシュを再描画する。
TypeScriptデータモデル
「軌道群」と「構成軌道」を分離する。p軌道群は3構成、3d・4dは5構成、4fは7構成、混成軌道は方向ごとに2〜6構成を持つ。
type OrbitalComponent = {
id: string;
latex: string;
kind: "s" | "angular" | "hybrid";
angular?: AngularKey;
radialNodes?: number;
direction?: [number, number, number];
};
type OrbitalSet = {
key: OrbitalKey;
button: string;
title: string;
quantum: string;
description: string;
components: OrbitalComponent[];
};angular は後述する多項式 のキー、radialNodes は表示する入れ子曲面数を決める整数、direction は混成軌道の主軸方向である。数式ラベルはLaTeX文字列として保持し、KaTeXでHTMLへ変換する。
実装されている全角度関数
角度評価点は単位球面上にあり、 を満たす。実装は規格化係数を含まない実多項式を使うが、 軌道ごとに最大絶対値で再規格化するため、非零の全体定数倍は生成曲面に影響しない。
| 族 | 実軌道 | 評価多項式 | 角度節 |
|---|---|---|---|
| p | |||
| p | |||
| p | |||
| d | |||
| d | |||
| d | |||
| d | |||
| d | |||
| f | |||
| f | |||
| f | |||
| f | |||
| f | |||
| f | |||
| f |
p軌道
はそれぞれ原点を通る1枚の節平面を持つ。符号は対応軸の正負に一致するため、2つのローブは必ず逆位相となる。 2p、3p、4pは同じ角度関数を共有し、違いは後述する動径方向の入れ子数だけである。
d軌道
は2枚の直交節平面、 は の2平面を持つ。 の節は の二重円錐であり、その内外が逆位相になるため、極方向の2ローブと赤道面付近の環状領域が現れる。
f軌道
7関数はいずれも3次斉次多項式であり、因数分解された各因子が節平面または節円錐を与える。、、 は平面と二重円錐の組合せ、 残る4関数は3枚の節平面を持つ。表示順序は上段3、中央1、下段3となるようデータ配列を並べ替えている。
描画曲面の厳密な媒介変数表示
球面格子の分割数はメッシュ精細度 から次式で決定する。
初期値 では となる。端点を含む標本角は次式である。
と は幾何学的に同じ子午線だが、UV状の格子を閉じるため頂点を重複させる。各方向単位ベクトルは、
であり、選択軌道の多項式値と離散標本上の最大値を、
と定義する。球殻縮尺 における実装上の半径は、
であり、BufferGeometryへ格納する頂点は、
である。したがって描画曲面は、連続表現では次の2枚の符号別媒介曲面とみなせる。
「ローブの太さ」スライダー
と置けば、節と極大方向を除く領域では であり、 指数に対する感度は次式になる。
ここで は自然対数を表す。
したがって を大きくすると中間振幅方向の半径だけが縮み、ローブは細く鋭くなる。小さくすると同じ領域が膨らみ、太く丸くなる。 一方、主軸上の極大では なので 、最大ローブ長は変わらない。節上も のままなので、節集合そのものも変わらない。UIは を0.01刻みで更新し、 p・d・f軌道のBufferGeometryを入力イベントごとに再生成する。s軌道と楕円体モデルの混成軌道にはこの指数を適用しない。 スライダーは左を「細い」、右を「太い」に統一するため表示方向を反転し、左端を 、右端を に対応させる。
規格化を軌道ごとに行うため、異なる軌道間の絶対振幅は比較できない。表示されるのは各軌道内部の角度分布と節構造である。
「メッシュ精細度」スライダー
スライダーは を2刻みで変更し、左端の から右端の まで球面格子を再生成する。値を上げるほど輪郭と鏡面反射は滑らかになるが、頂点数と三角形数、および再生成時間は増加する。 特に大きな で細くしたローブは角度方向の変化が急になるため、高精細設定の効果が大きい。 同じ をs軌道と混成軌道のSphereGeometryにも適用するため、全軌道で精細度が揃う。
符号分離と三角形インデックス
1球殻・1位相につき頂点数は 。格子セル数は、符号制約がなければ最大三角形数は である。 初期値ではそれぞれ5133頂点、4988セル、9976三角形となる。
セル左上を とすると、他の頂点番号は、
となる。各セルの候補三角形は と 。正位相メッシュでは3頂点すべてが
を満たす三角形だけを採用する。負位相メッシュでは不等号を に置き換える。
節をまたぐ三角形を生成しないため、正負曲面は幾何学的に接続されない。頂点配列自体は両位相で同一サイズを持つが、index bufferだけが異なる。 法線は最終index設定後に computeVertexNormals() で面積加重平均から生成する。
for each cell (a, b, c, d):
if samePhase(a, b, d): indices += [a, b, d]
if samePhase(b, c, d): indices += [b, c, d]
positive phase: F >= 0
negative phase: F < 0s軌道・動径節・球殻パラメータ
s軌道
s軌道は角度関数を用いず、同心SphereGeometryで表す。球殻数を 、内側からの番号を とすると半径は、
位相は内側を正として で交互に切り替える。実際の値は次表のとおり。
| 軌道 | 内→外の半径 | 内→外の位相 | 半透明時のα | |
|---|---|---|---|---|
| 1 | + | |||
| 2 | +,- | |||
| 3 | +,-,+ | |||
| 4 | +,-,+,- |
半透明時、単一球殻の1sは 。複数球殻ではコード上の式 により内側ほど濃くする。実際の水素様s軌道の動径節位置とは一致しない。
p・d軌道の動径節
角度曲面の球殻数は 、すなわち動径節数 に1を加えた値である。 内側からの縮尺は、
| 軌道群 | 内→外の | 内→外の位相 | 半透明時のα | |
|---|---|---|---|---|
| 1 | + | |||
| 2 | +,- | |||
| 1 | + | |||
| 1 | + | |||
| 2 | +,- | |||
| 3 | +,-,+ |
位相色は球殻ごとに交換する。外側球殻を含む奇数番目の位相反転により動径方向の符号変化を表すが、球殻間の連続な関数値や真の零点半径は計算しない。 不透明モードではすべて 、depthWrite=true とし、外側曲面が内側曲面を完全に隠す。
混成軌道の楕円体モデル
混成軌道は角度多項式を標本化せず、主軸が方向単位ベクトル に一致する2楕円体で構成する。 このため、角度振幅 のべき指数である は混成軌道には定義されず、そのままでは太さを変更できない。 代わりに楕円体の軸方向半径を保ったまま、2本の垂直方向半径へ共通係数 を掛ける。 任意点 、中心 に対する変位ベクトル、軸方向のスカラー座標、垂直成分ベクトルを、それぞれ
と置くと、大ローブは次の楕円体である。
これは半径0.62の球へ局所スケール を適用した値 に対応する。逆位相の小ローブは、
であり、半径0.42、局所スケール に由来する。Three.jsのQuaternionは を へ写す最短回転として生成する。
混成軌道の太さスライダー
混成軌道を選ぶとUIは形状指数 のスライダーを、横幅係数 のスライダーへ差し替える。 定義域は 、初期値は である。 値を増やすと大小両ローブが軸と垂直な方向だけに太くなり、減らすと細くなる。長軸半径、中心位置、方向ベクトル、相互角は変化しない。 も物理定数ではなく、模式的な楕円体の視覚パラメータである。
方向ベクトルの全定義
| 混成 | 方向単位ベクトル | 相互角 |
|---|---|---|
位相色、材質、不透明度
正負位相は電荷ではなく波動関数の符号である。テーマごとの正位相色A・負位相色Bは次のとおり。
| テーマ | 正位相 A | 負位相 B |
|---|---|---|
| MIDNIGHT | #32E6FF | #8B5CF6 |
| ATLAS | #2257A6 | #DF654F |
| GALLERY | #55F3D5 | #F85BB6 |
全曲面にMeshPhysicalMaterialを用い、材質定数は以下で固定する。
emissive色は位相色をRGB空間で0.13倍したもの。不透明モードでは transparent=false、、depthWrite=true。半透明モードでは表のαを採用し、 の曲面だけdepthWrite=false として内側球殻を見せる。両面描画のため side=DoubleSide とする。
単一角度球殻のαは0.94、混成軌道の大・小ローブは0.94と0.92であり、半透明モードでも深度を書き込む。 動径節の観察対象となる複数球殻だけが低αかつ深度非書込みになる。
座標軸、照明、カメラ
xyz軸
各正軸は原点から長さ1.82のArrowHelperとして生成する。矢尻長0.14、矢尻幅0.065。軸ラベルspriteは に置き、scaleは0.34である。 軸色はx #EF6461、y #57BD85、z #5D9CEC。
カメラ
PerspectiveCameraの垂直視野角は34°、nearは0.1、farは100。共通視線方向は、
であり、カメラ位置は 。upベクトルを に固定してz軸を画面上向きに投影する。
| 軌道群 | 初期距離 |
|---|---|
| 1s, 2s, 2p, 3s, 3p, 4s | 7.05 |
| 4p | 7.30 |
| sp^3, sp^2, sp, dsp^2, d^2sp^3 | 7.35 |
| 3d, 4d | 7.80 |
| 4f | 8.30 |
OrbitControlsの最小距離は 、最大距離は 、回転速度0.72、ズーム速度0.82、 dampingFactorは0.075。パンは無効である。軌道群内では全カードが同一の視線方向・距離を使う。
照明と出力
- HemisphereLight:sky
#FFFFFF、ground#172036、強度1.5。 - 主DirectionalLight:白、強度3.6、位置 。
- rim DirectionalLight:正位相色A、強度2.2、位置 。
- 出力色空間:sRGB。tone mapping:ACES Filmic。露出1.22。
- device pixel ratio:。
実行時計算、再生成条件、資源解放
角度関数とメッシュは毎フレーム計算しない。React effectの依存値は構成軌道、位相色A・B、透過モード、ローブ形状指数、混成軌道の横幅係数、メッシュ精細度、初期距離であり、 これらが変わったときだけシーンを破棄して再生成する。回転中のフレームループは次の2処理だけである。
function render() {
controls.update();
renderer.render(scene, camera);
frame = requestAnimationFrame(render);
}各角度球殻は正負2メッシュを持つ。初期設定では1メッシュ当たり5133頂点を確保し、全角度軌道群の生成量は次表のとおり。
| 軌道群 | カード数 | 球殻数/カード | 総メッシュ数 | 初期設定の総頂点スロット数 |
|---|---|---|---|---|
| 3 | 1 | 6 | 30,798 | |
| 3 | 2 | 12 | 61,596 | |
| 5 | 1 | 10 | 51,330 | |
| 3 | 3 | 18 | 92,394 | |
| 5 | 2 | 20 | 102,660 | |
| 7 | 1 | 14 | 71,862 |
index bufferに採用される三角形数は各角度関数の符号領域によって異なり、1位相・1球殻当たりの上限 未満となる。
cleanupではrequestAnimationFrameを停止し、ResizeObserverとOrbitControlsを解除する。scene graphを走査してGeometry、Material、 軸ラベルのCanvasTextureをdisposeし、最後にWebGLRendererをdisposeしてcanvasをDOMから除去する。
レスポンシブ配置アルゴリズム
通常軌道群はCSS Gridの列数を構成軌道数へ設定する。d軌道では6仮想列を使い、上段2カードを各3列幅、下段3カードを各2列幅にする。 f軌道も6列を使い、上段と下段は各カード2列幅、中央カードは中央2列だけを占有する。6構成の は広い画面で3列×2段とする。
760px以下では特殊なgrid-column/grid-row指定を解除し、自動配置へ戻す。560px以下では1列へ落とすため、軌道カードを見るための横スクロールは発生しない。 各カードのcanvasはResizeObserverで実寸を取得し、カメラaspectとrenderer寸法を同期する。
物理的制約と、厳密化する場合の変更点
現実装が計算していない量を明示する。
- 水素様動径関数 と陪ラゲール多項式。
- Bohr半径、実効核電荷、遮蔽、軌道収縮に基づく長さ尺度。
- 確率密度 、電子密度、積分確率。
- 複素球面調和関数の位相、磁気量子数基底、スピン軌道相互作用。
- 混成軌道 の係数規格化と重なり積分。
- 多電子波動関数、SCF、Hartree–Fock、Kohn–Sham DFT、基底関数展開。
厳密な水素様軌道へ拡張する場合は、3次元格子上で を評価し、 位相付き等値面 と をMarching Cubesで抽出する方法が自然である。 動径節は から自動的に現れ、現行の相似球殻近似と置き換えられる。