sf による光線追跡

はじめに

コンソール行列計算ソフト sf により光学系における光線追跡が可能です。 ただし sf は光線追跡専用のソフトではありません。行列数値計算ソフトです。光線追跡のためには sf 以外に、エディタと gnuplot と python を組み合わせた、コンソールから操作しながら計算していきます。

このように sf での光線追跡ではユーザーにコンピュータの使いこなしについて一定の知識を要求します。エディタ や gnuplot の名前ぐらいは聞いたことがある方、または新しいことに挑戦する方でないと使えないと思います。マウスだけで操作できる素人向けの統合環境ではありません。

逆に 行列数学/コンピュータについて理解・知識のある方ならば、短時間で強力な汎用的で応用の利く強力なツールを入手できます。sf 数値計算に、gnuplot はデータの可視化に特化したソフトであり、特化した分習得が容易で他への応用ができます。python は言語であり、この全体的な習得には手間がかかります。でも球面レンズの計算に限定すればブラック・ボックスにできます。 チャレンジ願います。

なお、sf は光線追跡のためのソフトではありません。汎用的に数値計算するソフトです。これに 光線追跡のための python script を 70 行程度書いただけで光線追跡ができてしまう所が自慢です。

御自分でも数値計算しながら以下を読んでください。そのほうが楽しめます。sf を使えば計算の手間はかかりません。(Windows が動く HDD に専用のディレクトリを掘って、こちらから sf20beta をダウンロードして解凍するだけで以下の計算ができてしまいます。インストーラなどありません。レジストリを汚すことはありません。不要になったら、ディレクトリごと消すだけです。"sf expression" が左上に書いてあるブロックは全て sf で計算可能です。sf 式をコピーし、コンソールで sf "コピーした sf 式" を実行させるだけで実行されます。コピーした sf 式は自由に修正できます。数値実験できます。是非ご自分の手でも数値実験を行いながら読んでみて下さい。

光線追跡で使う道具 sf, gnuplot, python

光線追跡で使う sf, gnuplot, python それぞれについて概要を説明します。実際に使っている機能は、それぞれの機能の一部だけです。簡単です。

sf

sf.exe は行列計算をさせるコマンドライン・プログラムです。計算結果を test.val などの拡張子が .val のテキスト・ファイルに残します。この test.val に対して変数と見なして sf "test2 = 3*test^2 + test^-2 + ~userFunction.py(test/3)" などと計算させられるのが sf の便利なところです。test.val を行列やベクタ・データにもできるので多くの強力な数値計算ができます。

新しい sf2.0 の機能を使います。また sf の機能の詳細ははこちらを参照ください。

sf は線形行列演算に特化したソフトです。非線形演算など sf.exe だけでは対応しきれない処理 userFunction を作って sf から呼び出して対処します。今回の ray trace では ray.py python script にレンズ面での ray trace の位置と方向を計算させます。

gnuplot

gnuplot は GPL で配布されている可視化ソフトです。ビジネスでのプレゼンテーションに使うには専用の何十万もするソフトより劣ります。自分で技術検討するための可視化ソフトと考えるならば、十分とも言える機能を持っています。フィルタ・スクリプトで扱いやすいのも嬉しいところです。

gnuplot をインストールするには ftp://ftp.gnuplot.info/pub/gnuplot/ から gp400win32.zip をダウンロードします。gp400win32.zip の中から bin directory にある wgnuplot.exeと wgnuplot.hlp を path の通ったディレクトリに解凍するだけです。とりあえず試すたけならば、カレント・ディレクトリでかまいません。とくにインストーラーは必要ありません。

gnuplot の操作は専用の gnuplot terminal window からコマンド操作を行うのが普通ですが、この光線追跡では、それは行いません。gnuplot は開始するときに gnuplot.ini ファイルを探し、そこに plot コマンドがあれば実行する機能があります。その gnuplot.ini には表示データも記述できます。この光線追跡ではコンソールに出力される sf の計算結果を copy and paste で gnuplot.ini に写し gnuplot が扱えるフォーマットにエディタで編集します。

その意味で光線追跡で gnuplot に行わせる具体的な操作は start wgnuplot.exe をコンソールから行わせることだけです。ray trace 表示コマンドと表示データは、あらかじめエディタでテキスト・データとして作ります。この gnuplot.ini データの作り方は、実例のところで詳細に説明します。

python

光線追跡で使うのは二十行程度のレンズ面での光線の位置と方向を計算する ray.py スクリプトだけです。球面レンズの光線追跡を行うだけならば ray.py を black box としてしておき、何もする必要ありません。自分で非球面レンズを使うなど拡張したいときに ray.py の中を一部修正することになります。そのときのために、もう少し python について説明します。

python は高機能なスクリプト言語です。これを使いこなせれば graphic 表示、web server 制御 windows アプリケーションなど殆んどのプログラムが作れます。それらを簡単に記述するためのパッケージが全世界の開発者たちが作り改良しつづけています。しかも無償で配布されています。

数学系の計算機能モジュールとしては scipy が配布されています。fft/特殊関数/Matlab 互換プロットパッケージ/統計処理パッケージ/積分/常微分方程式ソルバー/Lapack 線形演算 などが入っています。 。とりあえず行列処理をするだけならば、http://www.nasuinfo.or.jp/FreeSpace/kenji/sf/fastTour/pyLinear.htmここを見れば行列の加減乗除算や固有ベクタ/固有値を求めることはできるようになるはずです。インストールについても説明してあります。

光線追跡で使うのはベクトル演算機能と fsolve(.):Non-linear multi-variable equation solver. の二つだけです。この二つについて理解するだけで、凹面鏡/非球面レンズ光学系など多くの光学系での光線追跡もできるように python script:ray.py を拡張できます。最後に説明する ray.py スクリプトのソースも読んで見てもください。

sf による光線追跡の実際

一つの点光源と一つの球面凸レンズになる下のような光学系集光の様子を Snell の法則によって計算します。

              r= 30mm   r=-30mm
(-10mm,15mm)  (20mm,0), (25mm,0)            (80mm,0)
                  │    │
   ─────── │──│\            
    \            │    │     \      
          \      │    │          \
                \│    │               \
                  │──│───────────
                  │    │                    \
屈折率 1.5

レンズ形状データの作成

gnuplot に ray trace を描かせるとき、レンズも書いておくためのデータを作成します。直接には光線追跡の計算結果には影響しません

球面レンズ左面の位置データ

下の sf 式により (20mm,0) の位置に半径 30mm の球面の置いたとき、その表面の <x,y> 座標位置を計算させます。

N=32,<<-`π/2,N,`π/N @θ| <30`mm+20`mm,0>-30`mm  >>
sf "N=32,<<-`π/2,N,`π/N @θ| <30`mm+20`mm,0>-30`mm  >>"
    loop count:_n  0
    loop count:_n  1
        ・
    loop count:_n  31
[[ 32, 2 ]]
<        0.05,        0.03 >
<   0.0470595,   0.0298555 >
        ・
<   0.0235424,   0.0141419 >
<   0.0222836,   0.0114805 >
<   0.0212918,  0.00870854 >
<   0.0205764,  0.00585271 >
<   0.0201445,  0.00294051 >
<        0.02,           0 >
<   0.0201445, -0.00294051 >
<   0.0205764, -0.00585271 >
<   0.0212918, -0.00870854 >
<   0.0222836,  -0.0114805 >
<   0.0235424,  -0.0141419 >
        ・
<   0.0470595,  -0.0298555 >

この sf 式で行わせているのは [-π/2, π/2] の π の角度を N=32 等分し、それぞれの角度を θ にいれて <30`mm+20`mm,0>-30`mm <!cos(θ),!sin(θ)> を N 回計算させていることです。

`π==3.142 は予め sf.ini に宣言されています。θ のようにギリシャ文字を変数名に使えます。これは数式の可読性を高めてくれます。

`mm のように MKSA 物理単位を sf 式の中に書けるのが自慢です。やっているのは `mm=0.01 の値を入れてある変数を用意しておくだけなのですが。物理単位を数式中に入れるだけでドキュメント性が高まります。数式が何を意味しているのか良く分ります。

計算結果はコンソールに表示されます

球面レンズ左面の位置データ

同様に (25mm,0) の位置に半径 -30mm の球面の置いたとき、その表面の <x,y> 座標位置を計算させます。

N=32,<<-`π/2,N,`π/N @θ| <-30`mm+25`mm,0>+30`mm  >>
sf "N=32,<<-`π/2,N,`π/N @θ| <-30`mm+25`mm,0>+30`mm  >>"
    loop count:_n  0
    loop count:_n  1
        ・
    loop count:_n  31
[[ 32, 2 ]]
<      -0.005,       -0.03 >
< -0.00205949,  -0.0298555 >
        ・
<   0.0214576,  -0.0141419 >
<   0.0227164,  -0.0114805 >
<   0.0237082, -0.00870854 >
<   0.0244236, -0.00585271 >
<   0.0248555, -0.00294051 >
<       0.025,           0 >
<   0.0248555,  0.00294051 >
<   0.0244236,  0.00585271 >
<   0.0237082,  0.00870854 >
<   0.0227164,   0.0114805 >
<   0.0214576,   0.0141419 >
        ・
< -0.00205949,   0.0298555 >

球面レンズ位置の gnuplot.ini データ

コンソールに出力されている上のレンズ球面位置データより、レンズとして使える部分の数値の組だけをエディタで copy and paste して下のように gnuplot ini の名前のテキスト・ファイルをカレント・ディレクトリに作ります。

type gnuplot.ini
plot "-" using 1:2 with line
0.0222836     0.0114805 # レンズ面左側
0.0212918    0.00870854
0.0205764    0.00585271
0.0201445    0.00294051
     0.02             0
0.0201445   -0.00294051
0.0205764   -0.00585271
0.0212918   -0.00870854
0.0222836    -0.0114805
  0.0227164,  -0.0114805 > レンズ面右側
  0.0237082, -0.00870854 >
  0.0244236, -0.00585271 >
  0.0248555, -0.00294051 >
      0.025,           0 >
  0.0248555,  0.00294051 >
  0.0244236,  0.00585271 >
  0.0237082,  0.00870854 >
  0.0227164,   0.0114805 >

「plot "-" using 1:2 with line」は gnuplot を制御するコマンドです。