技術ドキュメント: draw_unit_cell.py
プログラムの動作
draw_unit_cell.py は、結晶学における単位格子(Unit Cell)を3次元で可視化し、その画像をPNGファイルとして保存するPythonプログラムです。
プログラムは、指定された格子定数 \(a, b, c\) と格子角 \(\alpha, \beta, \gamma\) を基に、単位格子を直交座標系で構築します。
具体的には、3つの基本格子ベクトル \(\vec{a}, \vec{b}, \vec{c}\) を矢印で表示し、単位格子の辺と頂点を描画します。
最終的に、生成された3Dプロットは unit_cell.png というファイル名で保存され、同時にmatplotlibのウィンドウにも表示されます。
このプログラムの主な機能は以下の通りです。
格子定数と格子角から単位格子の基本ベクトルを計算。
計算された基本ベクトルに基づいて単位格子の8つの頂点と12の辺を定義。
matplotlibの3Dプロット機能を使用して、これらの要素を可視化。
カスタム矢印クラス
Arrow3Dを使用して、3D空間に適切な向きとスケールで基本ベクトルを描画。プロットの視点、アスペクト比を調整し、不要な軸やグリッドを非表示にすることで、見やすい図を生成。
透過背景の高品質なPNG画像をファイルとして保存。
原理
このプログラムは、結晶学における単位格子の記述と、それを直交座標系に変換して3D描画を行うことを基本原理としています。
1. 格子ベクトルの計算
単位格子の定義において、3つの格子ベクトル \(\vec{a}, \vec{b}, \vec{c}\) は、その長さ \(a, b, c\) と、それらの間の角度 \(\alpha, \beta, \gamma\) によって特徴付けられます。 プログラムでは、これらのパラメータから直交座標系 \((x, y, z)\) におけるベクトルの成分を計算します。 標準的な結晶学の慣例に従い、\(\vec{a}\) を \(x\) 軸に沿って配置し、\(\vec{b}\) を \(xy\) 平面に配置します。\(\vec{c}\) は \(xyz\) 空間に配置されます。
各ベクトルの成分は以下のように計算されます。 ここで、\(\alpha_r, \beta_r, \gamma_r\) はそれぞれ \(\alpha, \beta, \gamma\) をラジアンに変換した値です。
ベクトル \(\vec{a}\): \(a_x = a\) \(a_y = 0\) \(a_z = 0\) したがって、 $\(\vec{a} = (a, 0, 0)\)$
ベクトル \(\vec{b}\): \(b_x = b \cos\gamma_r\) \(b_y = b \sin\gamma_r\) \(b_z = 0\) したがって、 $\(\vec{b} = (b \cos\gamma_r, b \sin\gamma_r, 0)\)$
ベクトル \(\vec{c}\): \(c_x = c \cos\beta_r\) \(c_y = c \frac{\cos\alpha_r - \cos\beta_r \cos\gamma_r}{\sin\gamma_r}\) \(c_z = \sqrt{c^2 - c_x^2 - c_y^2}\) したがって、 $\(\vec{c} = (c \cos\beta_r, c \frac{\cos\alpha_r - \cos\beta_r \cos\gamma_r}{\sin\gamma_r}, \sqrt{c^2 - c_x^2 - c_y^2})\)$
これらの計算は、関数 lattice_vectors で実行されます。
2. 3D描画技術
カスタム矢印
Arrow3D: 標準のmatplotlibのFancyArrowPatchは2D描画に特化しています。3D空間で矢印を正しく表示するためには、3D座標を2Dスクリーン座標に変換し、深度に基づいて描画順序を決定する必要があります。Arrow3DクラスはFancyArrowPatchを継承し、mpl_toolkits.mplot3d.proj3d.proj_transformを使用してこの変換を実行します。これにより、矢印は3D空間での相対的な位置と向きを保ちつつ、適切な透視投影で描画されます。アスペクト比の均一化:
set_equal_aspect関数は、3Dプロットの \(x, y, z\) 軸のスケールを均一に設定します。これにより、物体が歪んで見えず、物理的な形状を正確に反映した表示になります。具体的には、各軸のデータ範囲を計算し、その最大値に合わせて全ての軸の範囲を調整します。描画の最適化:
draw_unit_cell関数内では、単位格子の辺(細い黒線)、頂点(小さな黒い点)、および基本格子ベクトル(太い青い矢印とラベル)を描画します。 プロットの視認性を高めるため、軸の目盛り、ラベル、グリッド、背景の軸面はすべて非表示に設定されます。背景色も透過に設定され、よりクリーンな画像出力が可能になります。
必要な非標準ライブラリとインストール方法
このプログラムの実行には、以下の非標準ライブラリが必要です。
NumPy: 数値計算(特に配列操作や三角関数)に使用されます。
Matplotlib: グラフ描画(特に3Dプロット機能)に使用されます。
これらのライブラリは、Pythonのパッケージマネージャ pip を使用してインストールできます。
コマンドラインで以下のコマンドを実行してください。
pip install numpy matplotlib
必要な入力ファイル
draw_unit_cell.py は、外部の入力ファイルを必要としません。
単位格子の格子定数 (\(a, b, c\)) と格子角 (\(\alpha, \beta, \gamma\)) は、プログラム内の draw_unit_cell 関数の呼び出しで直接ハードコードされています。
現在の設定は a=5.0, b=5.5, c=4.5, alpha=80, beta=70, gamma=100 です。
生成される出力ファイル
プログラムを実行すると、以下のファイルが生成されます。
unit_cell.png: 生成された3D単位格子の図が、透過背景を持つPNG形式の画像ファイルとして保存されます。 解像度は300 dpiで、図の余白が最小限に抑えられた状態で出力されます。 この画像には、原点から伸びる青い矢印で示された3つの基本格子ベクトルa,b,c、黒い線で描かれた単位格子の辺、および黒い点で示された単位格子の頂点が含まれます。
さらに、プログラムはmatplotlibのGUIウィンドウを起動し、描画された単位格子をリアルタイムで表示します。
このウィンドウで視点を変更すると、その現在の視点角度 (elev, azim) が標準出力(コンソール)に表示されます。
コマンドラインでの使用例 (Usage)
draw_unit_cell.py は、コマンドライン引数を受け取らないため、Pythonインタープリタで直接実行します。
python draw_unit_cell.py
コマンドラインでの具体的な使用例
以下のコマンドを実行すると、プログラムが起動し、単位格子の図が生成されます。
python draw_unit_cell.py
実行結果:
現在のディレクトリに
unit_cell.pngという画像ファイルが保存されます。このファイルには、格子定数 \(a=5.0, b=5.5, c=4.5\) および格子角 \(\alpha=80^\circ, \beta=70^\circ, \gamma=100^\circ\) で定義された単位格子の3D図が含まれます。matplotlibのGUIウィンドウが開き、同じ単位格子の図が表示されます。
このGUIウィンドウでマウスを使って図を回転させると、現在の視点角度(
elevとazim)が以下のような形式でコンソールに表示されます。elev: 5.90, azim: -67.55 elev: 10.00, azim: -60.00 elev: 15.25, azim: -55.70 ...
これはインタラクティブなデバッグや視点調整に役立つ情報ですが、プログラムの主要な出力ではありません。