長方形を回転する直線が横切る長さ

X線結晶回折法でのデータ収集では、固定されたビームに対して結晶を回転させてデータを収集していく。結晶は球形ではないので、回転につれてビームが結晶を貫通する長さが変化し、それに比例して回折強度が変化する。スケーリングでは、この強度変化をなめらかな曲線でフィッティングした上で補正する。

実際にどんな曲線になるのか計算してみた。もっとも簡単な場合として、結晶を原点を中心とする直方体と考える。具体的には、x=±a, y=±b, z=±c で区切られる領域だ。結晶は z 軸を中心として回転し、ビームはこの回転軸に直交しているとする。

これは、結晶を固定した座標系で考えると、原点を中心とした長方形 x=[-a, a], y=[-b, b] があって、原点を通る直線  y = x \tan\theta が横断するモデルになる。角で場合分けして計算すると、以下のコードになる。

a <- 5
b <- 3

func <- function(x) {
   boundary <- atan(b/a)
   if ((x >= 0 & x < boundary) | (x >= -boundary + pi & x < boundary + pi) | (x >= -boundary + 2 * pi)) {
      return(2 * a / abs(cos(x)))
   } else if ((x >= boundary & x < -boundary + pi) | (x >= boundary + pi & x < -boundary + 2 * pi)) {
      return(2 * b / abs(sin(x)))
   }
   return(0.0)
}

x <- seq(0, 2*pi, 0.01)
ret <- rep(0, length(x))
for (i in 1:length(x)) {
   ret[i] <- func(x[i])
}
plot(x, ret, type="l", ylim=c(0, max(ret)))

func は、とりあえず [0, 2π]の範囲しか考えていない。そのうえ、ベクトル化していないので curve 関数が使えず不恰好になってしまった。

見ての通りなめらかに変化しており、その変化は二次曲線とみなしても良さそうであるが、角の部分でかなり鋭い変化をしている。二次曲線とみなしても良さそうな理由は、Taylor 展開してみれば分かる。

(%i4) taylor(1/cos(x), x, 0, 6);
                              2      4       6
                             x    5 x    61 x
(%o4)/T/                 1 + -- + ---- + ----- + . . .
                             2     24     720
(%i10) plot2d([1+x^2/2, 1/cos(x)], [x, -%pi/3, %pi/3]);

SCALA での実装を確認する。
#結晶断面が任意の多角形の場合を確認する
#ヘリカルスキャンの場合を考察する