raytracing
前回、レンズなどの光学系の光線追跡(レイトレーシング)ができるraytracingライブラリを紹介しました。

今回はraytracingライブラリの光学設計の基本を見ていきましょう。
もととするプログラムとして前回紹介したこちらのプログラムです。
from raytracing import *
path = ImagingPath()
path.append(Space(d=50))
path.append(Lens(f=50, diameter=25))
path.append(Space(d=120))
path.append(Lens(f=70))
path.append(Space(d=100))
path.display()
実行結果

それでは始めていきましょう。
raytracingの光学設計の基本
一番最初に必要なのは、光学系を作るという宣言で「path = ImagingPath()」を用います。
そして返り値を受けて、その変数pathに光学系を組んでいきます。
最終的に設計した光学系を表示するのには「path.display()」とします。
また「ImagingPath()」やその後に光源の設定を行えますが、そこはまた別の機会に紹介します。
とりあえずここまでをプログラムとしてみるとこんな感じです。
from raytracing import *
path = ImagingPath()
path.display()
実行結果
---------------------------------------------------------------------------
ZeroDivisionError Traceback (most recent call last)
Cell In[4], line 4
1 from raytracing import *
3 path = ImagingPath()
----> 4 path.display()
File /Library/Frameworks/Python.framework/Versions/3.10/lib/python3.10/site-packages/raytracing/imagingpath.py:996, in ImagingPath.display(self, rays, raysList, removeBlocked, comments, onlyPrincipalAndAxialRays, limitObjectToFieldOfView, interactive, filePath)
994 fanAngle = self.fanAngle
995 if fanAngle is None:
--> 996 fanAngle = np.tan(self.figure.displayRange / 2 / self.L / 5)
997 defaultObject = ObjectRays(self.objectHeight, z=self.objectPosition,
998 halfAngle=fanAngle, T=self.rayNumber, H=self.fanNumber)
999 raysList.append(defaultObject)
ZeroDivisionError: float division by zero
これだけだと全く光学系が設計されていないので、エラーとなってしまいます。
ということで光学系を組んでいきますが、光学系を足していくには「path.append()」を用います。
まずは光源からある一定の距離にレンズを置こうと思うのですが、その場合は「ある一定の距離」をまず光学系に足してあげます。
光学系に距離を足すには「Space(d=距離)」を、「path.append()」の引数に与えます。
from raytracing import *
path = ImagingPath()
path.append(Space(d=50))
path.display()
実行結果

与えた距離が「m」なのか、「cm」なのか、「mm」なのかは、プログラム中には距離の単位の概念は入っていなさそうなので、どれかの単位で固定されていると思えば良さそうです。
次にレンズを足していきます。
レンズを足すには「Lens(f=焦点距離)」を「path.append()」の引数に与えます。
from raytracing import *
path = ImagingPath()
path.append(Space(d=50))
path.append(Lens(f=50))
path.display()
実行結果

「raytracing」ライブラリのいいところはレンズの焦点距離だけで光学系を組めるところで、ちょっと試してみたいという私の様な光学系初心者に優しい作りになっているところです。
また焦点距離だけでなく、直径も設定することができます。
その場合は「Lens()」のオプション引数に「diameter=直径」を追加します。
from raytracing import *
path = ImagingPath()
path.append(Space(d=50))
path.append(Lens(f=50, diameter=5))
path.display()
実行結果

するとこの様にレンズに入る光線のみシミュレートされます。
また厚みのあるレンズやミラー、アパチャーなど他の光学系も配置できますが、また機会があったら紹介していきます。
レンズを配置したらまた距離を配置するとそこまでの光線がシミュレートされて、また光学系を配置して、距離を配置して、といった感じの繰り返しになります。
from raytracing import *
path = ImagingPath()
path.append(Space(d=50))
path.append(Lens(f=50))
path.append(Space(d=120))
path.display()
実行結果

ちなみに画像を保存するには「path.saveFigure(“ファイルパス”)」で保存することができます。
from raytracing import *
path = ImagingPath()
path.append(Space(d=50))
path.append(Lens(f=50))
path.append(Space(d=120))
path.saveFigure("python-raytracing2-7.png")
実行結果

ABCD行列表示
光学系の解析において、ABCD行列解析(光線行列解析)と呼ばれる光線追跡手法があるそうです。
これはレンズの前後のビームサイズや入射角度、出射角度を行列で表したもので以下の様になります。
\(\begin{bmatrix} X_2 \\ \theta_2 \end{bmatrix} = \begin{bmatrix} A & B \\ C & D \end{bmatrix} \begin{bmatrix} X_1 \\ \theta_1 \end{bmatrix}\)
つまり入射側のビームサイズと入射角度の行列とABCDの行列の積が出射側のビームサイズと出射角度となるわけです。
PythonのraytracingライブラリでABCD行列を表示するには、単に「print(path)」とします。
from raytracing import *
path = ImagingPath()
path.append(Space(d=50))
path.append(Lens(f=50, diameter=25))
path.append(Space(d=120))
path.display()
print(path)
実行結果
| -1.400 50.000 |
| |
| -0.020 0.000 |
f=50.000
ただしあくまでも最初から「print(path)」としたところまでのABCD行列解析がされるので、途中途中で確認したい場合は、確認したい場所で「print(path)」とする必要があります。
from raytracing import *
path = ImagingPath()
path.append(Space(d=50))
print(path)
path.append(Lens(f=50, diameter=25))
print(path)
path.append(Space(d=120))
print(path)
実行結果
| 1.000 50.000 |
| |
| 0.000 1.000 |
f = +inf (afocal)
| 1.000 50.000 |
| |
| -0.020 0.000 |
f=50.000
| -1.400 50.000 |
| |
| -0.020 0.000 |
f=50.000
次回はraytracingライブラリで光源をいじっていきます。
ではでは今回はこんな感じで。
コメント