距離,角度,二面角の測定と変更

このページでは,Builcule で原子の成す距離,角度,二面角を測定したり変更したりする方法を紹介します.
変更する方法には,マウス操作で変更する方法と,値を指定して変更する方法があります.
距離,角度,二面角について,以下の順で解説しています.

  1. 原子の指定法
  2. 測定
  3. マウスで変更
  4. 値を指定して変更
  5. アルゴリズム

なお,Builcule では二面角の値を,反時計回りに 0°〜 180°,時計回りに 0°〜 -180°としています.


距離の測定と変更

2 原子の指定法

2 原子のピック

まず,操作の対象とする 2 原子をピックします.
画像は,ジクロロエタンで 2 個の炭素原子をピックしていくところ( 1 → 2 → 3 )と解釈してください.

原子間距離を測定する場合は,2 原子は共有結合している必要はありません

結合距離を変更するためのピックには,条件が付きます.

原子間距離の測定

距離の測定結果

2 原子をピックして水平ツールバーの [距離を測定] ボタン距離を測定をクリックすると,2 原子間の距離(Å)がポップアップウィンドウに表示されます.
この例では,距離は 1.54 Å と測定されました.

マウスで結合距離を変更

  1. 2 原子をピック
  2. 水平ツールバーの [距離を変更]距離を変更 ボタンをクリック
  3. マウスの左ボタンを押したままドラッグ

この際,後でピックした側の領域が平行移動します.
「距離を変更」の状態は,マウスのボタンを離すと解除されます(ピックは維持されます).

値を指定して結合距離を変更

長さを指定

2 原子をピックしてメニューの [値を指定して結合距離を変更] を実行すると,数値の入力を求めるウィンドウが表れます.
設定できる数値は,1.0 〜 10.0 です.
画像は,1.0 と入力したところです.
この状態で [実行] ボタンを押すと,後でピックした側の領域が平行移動して結合距離が変更されます.

距離を測定するプログラムの例

ピックされた 2 原子の位置ベクトルの差を求め,そのノルムを求めれば OK です.
Eigen を使う例をコードで書いてみると,


#include <Eigen/Dense>

double measure_distance(const Eigen::Vector3d *v0, const Eigen::Vector3d *v1) {
 return (*v1 - *v0).norm();
}

結合距離を変更するアルゴリズムの例

Builcule 内部では次の処理をおこなっています.

  1. 後からピックされた側の領域を選択します
  2. ピックされた 2 原子の位置ベクトルの差ベクトルを求め,必要なノルムに変更します
  3. 1. で選択した領域の原子の座標に,2. で作成したベクトルを加えます

角度の測定と変更

3 原子の指定法

3 原子のピック

まず,操作の対象とする 3 原子をピックします.
画像は,ジクロロエタンで 3 個の炭素原子をピックしていくところ( 1 → 2 → 3 → 4 )と解釈してください.

角度を測定する場合は,原子どうしが共有結合している必要はありません.

結合角を変更するためのピックには,条件が付きます.

3 原子が成す角度の測定

角度の測定結果

3 原子をピックして水平ツールバーの [角度を測定]角度を測定 ボタンをクリックすると,3 原子の成す角度(°)がポップアップウィンドウに表示されます.
この例では,角度は 109.471 °と測定されました.

マウスで結合角を変更

  1. 3 原子をピック
  2. 水平ツールバーの [角度を変更]角度を変更 ボタンをクリック
  3. マウスの左ボタンを押したままドラッグ

この際,後でピックした側の領域が回転します.
「角度を変更」の状態は,マウスのボタンを離すと解除されます(ピックは維持されます).

値を指定して結合角を変更

角度を指定

3 原子をピックしてメニューの [値を指定して結合角を変更] を実行すると,数値の入力を求めるウィンドウが表れます.
設定できる数値は 0°〜 180°です.
画像は,90.0 と入力したところです.
この状態で [実行] ボタンを押すと結合角が変更されます(後でピックした側の領域が回転します).

角度を測定するプログラムの例

C++ と Eigen を使った,角度を返却するコードです.
原子の座標(3 個の位置ベクトル)を v0, v1, v2 とします.


#include <Eigen/Dense>

double measure_angle(const Eigen::Vector3d *v0, const Eigen::Vector3d *v1, const Eigen::Vector3d *v2) {
 Eigen::Vector3d vect0(*v0 - *v1);  //v1 → v0 ベクトル
 Eigen::Vector3d vect1(*v2 - *v1);  //v1 → v2 ベクトル
 vect0.normalize();  //正規化
 vect1.normalize();  //正規化
 double cos = vect0.dot(vect1);  //内積.ベクトルが正規化されているので,そのままコサイン値
 double angle = acos(cos);  //逆三角関数でラジアンに変更
 if(isnan(angle) || isinf(angle))
  return 0.0;
 return angle;
}

結合角を変更するアルゴリズムの例

角度の変更法

画像は角の変更法を概念的に表したものです.
これを使い,Builcule での,原子 A,B,C の成す結合角を変更するための考え方を下に記します.

  1. 回転すべき対象を定めます.ここでは原子 C です.一般的には C に結合した B 以外の原子も含みます
  2. 回転の中心を B とします
  3. 回転軸を定めます.ここでは,ベクトル BA を正規化したものとベクトル BC を正規化したものとの外積を正規化したものとします.図では赤い矢印で示しました
  4. 回転させたい角度に応じた回転行列を作成します
  5. 回転の中心原点に来るように,回転すべき対象を平行移動します
  6. 回転行列と回転すべき対象の座標を掛け算します
  7. 回転すべき対象を,元の位置に平行移動します

二面角の測定と変更

4 原子の指定法

4 原子のピック

まず,操作の対象とする 4 原子をピック(原子をクリックして赤紫に表示)します.
画像は異時同図法で,ジクロロエタンの 4 個の原子を,2 → 3 → 4 → 5 の順にピックしていくところと解釈してください.

二面角を測定する場合は,原子どうしが共有結合している必要はありません.

二面角を変更するためのピックには,条件が付きます.

4 原子が成す二面角の測定

二面角の測定結果

4 原子をピックして水平ツールバーの [二面角を測定]二面角を測定 ボタンをクリックすると,4 原子の成す二面角(°)がポップアップウィンドウに表示されます.

マウスで二面角を変更

  1. 4 原子をピック
  2. 水平ツールバーの [二面角を変更]二面角を変更 ボタンをクリック
  3. マウスの左ボタンを押したままドラッグ

この際,後でピックした側の領域が回転します.
「二面角を変更」の状態は,マウスのボタンを離すと解除されます(ピックは維持されます).

値を指定して二面角を変更

二面角を指定

4 原子をピックしてメニューの [値を指定して二面角を変更] を実行すると,数値の入力を求めるウィンドウが表れます.
画像は,90.0 と入力したところです.
設定できる数値は,0°〜 360°です.

この状態で [実行] ボタンを押すと二面角が入力した数値に変更されます.
変更後,ピックは維持されます.

二面角を測定するアルゴリズム

二面角の測定法

画像は二面角の測定法を概念的に表したものです.
点 A,B,C,および D が成す二面角というのは,点を A → B → C → D の順で考えたとき,
点 A,B,C が成す平面と,点 B,C,D が成す平面をイメージしたときに,これらの 2 面が成す角度のことです.
Builcule では,それぞれの面に垂直なベクトル(法線ベクトル)を求め,それらが成す角を求めています.

画像は二面角の測定法を概念的に表したものです.
4 点 A,B,C,および D を A → B → C → D の順でピックされたとします.
このとき,

をイメージしてください.
二面角というのは,これらの 2 面が成す角度のことです.

Builcule では,それぞれの面に垂直なベクトル(法線ベクトル)を求め,それらが成す角を求めています.

手順1:それぞれの面ごとに,法線ベクトル求めます

図では,2 本の法線ベクトルを赤い矢印で示しました.
左側の法線ベクトルは,ベクトル BA と ベクトル BC の外積です.
右側の法線ベクトルはベクトル CB と ベクトル CD の外積です.

Builcule では,線形代数ライブラリ Eigen の cross() という外積を返す関数を使い,
Eigen::Vector3d (外積ベクトル B) = (ベクトル BA).cross(ベクトル BC);
Eigen::Vector3d (外積ベクトル C) = (ベクトル CB).cross(ベクトル CD);
といった感じでコーディングしています.

手順2:得られた 2 本の法線ベクトルの成す角度を求めます

これは内積で求まります.Eigen での内積を求める関数は dot() です.
標準化しておけば,内積がそのままコサインの値になります.
(外積ベクトル B).normalize();
(外積ベクトル C).normalize();
(二面角のコサイン) = (外積ベクトル B).dot(外積ベクトル C);

二面角を変更するアルゴリズム

二面角の変更法

図は,二面角変更の概念図です.
これを使い,Builcule での,原子 A,B,C,D の成す二面角を変更するための考え方を下に記します.

  1. 回転すべき対象を定めます.図では原子 D です.一般的には,D と結合した C 以外の原子も含まれます
  2. 回転の中心を C とします
  3. 回転軸を定めます.ここでは,ベクトル BC を正規化したものとします.図では赤い矢印で示しました
  4. 回転させたい角度に応じた回転行列を作成します
  5. 回転の中心が原点に来るように,回転すべき対象を平行移動します
  6. 回転行列と回転すべき対象の座標を掛け算します
  7. 回転すべき対象を,元の位置に平行移動します