格子の変換(昨日の続き)

id:mercure:20060302:1141301010 の行列だと determinant (実は体積に等しい)があわない。なので自力で考えてみた。興味のある人だけどうぞ。
長さ1の直交基底{\bf e}_x, {\bf e}_y, {\bf e}_zは、元の平行六面体に対して任意にとれるので、次の様にとることに決める。

  1. {\bf e}_x{\bf a} に平行
  2. {\bf e}_y{\bf a}{\bf b} でできる面内にとる

こうすると、{\bf e}_x, {\bf e}_y, {\bf e}_zはこう書ける。

\begin{eqnarray*} {\bf_a} &=& ({\bf a} \cdot {\bf e}_x){\bf e}_x \\ {\bf_b} &=& ({\bf b} \cdot {\bf e}_x){\bf e}_x + ({\bf b} \cdot {\bf e}_y){\bf e}_y \\ {\bf_c} &=& ({\bf c} \cdot {\bf e}_x){\bf e}_x + ({\bf c} \cdot {\bf e}_y){\bf e}_y + ({\bf c} \cdot {\bf e}_z){\bf e}_z \end{eqnarray*}

以下で \alpha, \beta, \gamma はそれぞれ、{\bf b}{\bf c}, {\bf c}{\bf a}, {\bf a}{\bf b} のなす角のこと。

1 から明らかに

{\bf a} \cdot {\bf e}_x = |{\bf a}|

2 から {\bf b} \cdot {\bf e}_x{\bf b}{\bf a} への射影、{\bf b} \cdot {\bf e}_y{\bf b}{\bf a} を 90度回転したベクトルへの射影なので、

\begin{eqnarray*} {\bf b} \cdot {\bf e}_x &=& |{\bf b}|\cos\gamma \\ {\bf b} \cdot {\bf e}_y &=& |{\bf b}|\sin\gamma \end{eqnarray*}

となる。

{\bf e}_x{\bf e}_y{\bf a}{\bf b} で表せるようになった。この関係から {\bf c} \cdot {\bf e}_x{\bf c} \cdot {\bf e}_y が求まる。

\begin{eqnarray*} {\bf c} \cdot {\bf e}_x &=& {\bf c} \cdot \frac{{\bf a}}{|{\bf a}|} \\ &=& \frac{{\bf c} \cdot {\bf a}}{|{\bf a}|} \\ &=& \frac{|{\bf c}||{\bf a}|\cos\beta}{|{\bf a}|} \\ &=& |{\bf c}|\cos\beta \end{eqnarray*}

\begin{eqnarray*} {\bf c} \cdot {\bf e}_y &=& {\bf c} \cdot (\frac{{\bf b} - |{\bf b}|\cos\gamma{\bf e}_x}{|{\bf b}|\sin\gamma}) \\ &=& \frac{{\bf c} \cdot {\bf b} - |{\bf b}|\cos\gamma {\bf c} \cdot {\bf e}_x}{|{\bf b}|\sin\gamma} \\ &=& \frac{|{\bf c}||{\bf b}|\cos\alpha - |{\bf b}|\cos\gamma |{\bf c}|\cos\beta}{|{\bf b}|\sin\gamma} \\ &=& \frac{|{\bf c}|(\cos\alpha - \cos\gamma\cos\beta)}{\sin\gamma} \end{eqnarray*}

残りは {\bf c} \cdot {\bf e}_z だけになった。これはちょっと面倒臭いかも。ベクトルの外積を使わないといけないかなぁ。

ということで {\bf a}{\bf b}外積 {\bf a} \times {\bf b}から攻めてみる。外積 {\bf a} \times {\bf b}{\bf a}{\bf b} に垂直で |{\bf a}||{\bf b}|\sin\gamma の大きさ(ベクトル {\bf a}{\bf b} でできる平行四辺形の面積)を持つベクトルです。なのでこのベクトルに {\bf c} の射影を掛ける(つまり内積をとる)と平行六面体の体積となります。この体積をとりあえず V としておくと、

\begin{eqnarray*} {\bf c} \cdot ({\bf a} \times {\bf b}) &=& V \end{eqnarray*}

ところで {\bf a}{\bf b} はもう {\bf e}_x{\bf e}_y で書けているので、

\begin{eqnarray*} {\bf c} \cdot ({\bf a} \times {\bf b}) &=& {\bf c} \cdot \left{ |{\bf a}|{\bf e}_x \times(|{\bf b}|\cos\gamma {\bf e}_x + |{\bf b}|\sin\gamma {\bf e}_y)\right} \\ &=& |{\bf a}||{\bf b}|\sin\gamma {\bf c} \cdot {\bf e}_z \end{eqnarray*} \\ ({\bf e}_x \times {\bf e}_x = 0, {\bf e}_x \times {\bf e}_y = {\bf e}_z)

ちょっとズルをして公式集を眺めると体積 VV=|{\bf a}||{\bf b}||{\bf c}|sqrt{1-\cos^2\alpha-\cos^2\beta-\cos^2\gamma+2\cos\alpha\cos\beta\cos\gamma} だそうなので、

\begin{eqnarray*} {\bf c} \cdot {\bf e}_z &=& \frac{V}{|{\bf a}||{\bf b}|\sin\gamma} \\ &=& \frac{|{\bf c}|sqrt{1-\cos^2\alpha-\cos^2\beta-\cos^2\gamma+2\cos\alpha\cos\beta\cos\gamma}}{\sin\gamma} \end{eqnarray*}

となります。なので変換行列は

\left( \begin{array}{ccc} |{\bf a}| & 0 & 0 \\ |{\bf b}|\cos\gamma & |{\bf b}|\sin\gamma & 0 \\ |{\bf c}|\cos\beta & \frac{|{\bf c}|(\cos\alpha - \cos\gamma\cos\beta)}{\sin\gamma} & \frac{|{\bf c}|sqrt{1-\cos^2\alpha-\cos^2\beta-\cos^2\gamma+2\cos\alpha\cos\beta\cos\gamma}}{\sin\gamma} \end{array}\right)

となりました。む、やはり昨日のとちょっと違うな。ともあれ、めでたしめでたし、ということで。

ちなみに昨日の行列は openbabel 1.1 のソースをみて書いたもので、 最新の openbabel 2.0 ではちゃんと上の行列になってます。