【raytracing】ABCD行列のそれぞれの値と焦点位置を取得し、図に追加する方法[Python]

  • URLをコピーしました!

raytracing

前回、raytracingライブラリの光線解析結果から自分で光線図を作成する方法を紹介しました。

今回はraytracingライブラリでABCD行列のそれぞれの値と焦点位置を取得し、図に追加する方法を紹介します。

まず前回行った光線解析結果の取得と、自分で光線図を作成するためのプログラムはこちらです。

from raytracing import *
import matplotlib.pyplot as plt

path = ImagingPath()
path.append(Space(d=50))
path.append(Lens(f=10))
path.append(Space(d=50))

angle_list = np.linspace(-10, 10, 7)

#----------位置、角度情報取得ここから----------
y_list = []; z_list = []; theta_list = []
for angle in angle_list:
    ray = Ray(y=0, theta=np.radians(angle))
    trace = path.trace(ray)

    y_optics = []; z_optics = []; theta_optics = []
    for data in trace:
        y_optics.append(data.y)
        z_optics.append(data.z)
        theta_optics.append(data.theta)
    y_list.append(y_optics)
    z_list.append(z_optics)
    theta_list.append(theta_optics)
#----------位置、角度情報取得ここまで----------

#----------光線プロットここから----------
fig = plt.figure()
plt.clf()

for y_optics, z_optics in zip(y_list, z_list):
    plt.plot(z_optics, y_optics, color="red", lw=0.5)

plt.xlabel("Distance")
plt.ylabel("Height")
plt.show()
#----------光線プロットここまで----------

実行結果

それでは始めていきましょう。

ABCD行列のそれぞれの値と焦点位置の取得方法

まずは各光学系のABCD行列のそれぞれの値と焦点位置を取得する方法を紹介します。

前に「path = ImagingPath()」にさまざまな光学系を配置したの「print(path)」で光路全体のABCD行列を表示できることを紹介しました。

from raytracing import *

path = ImagingPath()
path.append(Space(d=50))
path.append(Lens(f=10))
path.append(Space(d=50))

print(path)

実行結果
| -4.000   -150.000 |
|                 |
| -0.100   -4.000 |
f=10.000

それぞれの光学系のABCD行列を取得するには、for文を使ってpathの中身を一つずつ取得し、それをprint関数で表示します。

from raytracing import *

path = ImagingPath()
path.append(Space(d=50))
path.append(Lens(f=10))
path.append(Space(d=50))

for optics in path:
    print(optics)

実行結果
|  1.000   50.000 |
|                 |
|  0.000    1.000 |
f = +inf (afocal)
|  1.000    0.000 |
|                 |
| -0.100    1.000 |
f=10.000
|  1.000   50.000 |
|                 |
|  0.000    1.000 |
f = +inf (afocal)

次にABCD行列のそれぞれの値を取得するには、取得したpathの中身に対して、「.A」、「.B」、「.C」、「.D」とすると取得できます。

また焦点に関しては「.f」とすると取得できます。

from raytracing import *

path = ImagingPath()
path.append(Space(d=50))
path.append(Lens(f=10))
path.append(Space(d=50))

for i, optics in enumerate(path):
    print(f"-----Optics{i}-----")
    print(f"A: {optics.A}")
    print(f"B: {optics.B}")
    print(f"C: {optics.C}")
    print(f"D: {optics.D}")
    try:
        print(f"focus: {optics.f}")
    except:
        None

実行結果
-----Optics0-----
A: 1.0
B: 50.0
C: 0.0
D: 1.0
-----Optics1-----
A: 1.0
B: 0.0
C: -0.1
D: 1.0
focus: 10
-----Optics2-----
A: 1.0
B: 50.0
C: 0.0
D: 1.0

ちなみに「Space」は焦点位置が存在しない(afocal)ため、「.f」をするとエラーとなります。

そのため上のプログラムでは「try文」を使って、エラーが出ても止まらないようにしています。

また「.f」で取得できる焦点はレンズ後の焦点だけです。

レンズ前の焦点、レンズ後の焦点をそれぞれ別に取得したい場合は「.frontFocalLength()」、「.backFocalLength()」を用います。

from raytracing import *

path = ImagingPath()
path.append(Space(d=50))
path.append(Lens(f=10))
path.append(Space(d=50))

for optics in path:
    print(optics.frontFocalLength())
    print(optics.backFocalLength())

実行結果
None
None
10.0
10.0
None
None

光線図に焦点を追加する方法

光線図に焦点を追加するには、焦点を追加するレンズまでの距離、そして焦点距離が必要です。

焦点距離に関しては上で説明しました通り、「.frontFocalLength()」、「.backFocalLength()」でレンズ前後の焦点を取得できます。

焦点を追加するレンズまでの距離はそれぞれの光学系の配置距離を足し合わせていきます。

そのためfor文を使って一つずつ光学系の情報を取得し、その中で距離を示す「.B」を順次足し合わせていくことで焦点を追加したいレンズまでの距離を計算します。

そして取得したレンズまでの距離に焦点距離を足したり、引いたりすることで焦点の位置を取得し、「plt.scatter()」で表示します。

それをプログラムで表すとこんな感じです。

position = 0
for optics in path:
    optics_position = optics.B
    position = position+optics_position
    ffl = optics.frontFocalLength()
    bfl = optics.backFocalLength()
    if ffl != None and bfl != None:
        plt.scatter(position+ffl, 0, color="black", s=5)
        plt.scatter(position-bfl, 0, color="black", s=5)

あとはこれを最初のプログラムに合わせるだけです。

from raytracing import *
import matplotlib.pyplot as plt

path = ImagingPath()
path.append(Space(d=50))
path.append(Lens(f=10))
path.append(Space(d=50))

angle_list = np.linspace(-10, 10, 7)

#----------位置、角度情報取得ここから----------
y_list = []; z_list = []; theta_list = []
for angle in angle_list:
    ray = Ray(y=0, theta=np.radians(angle))
    trace = path.trace(ray)

    y_optics = []; z_optics = []; theta_optics = []
    for data in trace:
        y_optics.append(data.y)
        z_optics.append(data.z)
        theta_optics.append(data.theta)
    y_list.append(y_optics)
    z_list.append(z_optics)
    theta_list.append(theta_optics)
#----------位置、角度情報取得ここまで----------

#----------光線プロットここから----------
fig = plt.figure()
plt.clf()

for y_optics, z_optics in zip(y_list, z_list):
    plt.plot(z_optics, y_optics, color="red", lw=0.5)

#----------焦点距離取得&プロットここから----------
position = 0
for optics in path:
    optics_position = optics.B
    position = position+optics_position
    ffl = optics.frontFocalLength()
    bfl = optics.backFocalLength()
    if ffl != None and bfl != None:
        plt.scatter(position+ffl, 0, color="black", s=5)
        plt.scatter(position-bfl, 0, color="black", s=5)
#----------焦点距離取得&プロットここまで----------

plt.xlabel("Distance")
plt.ylabel("Height")
plt.show()
#----------光線プロットここまで----------

実行結果

次回はraytracingライブラリを使って光線が集まる位置(結像位置)を取得し、図に表示する方法を紹介します。

ではでは今回はこんな感じで。

よかったらシェアしてね!
  • URLをコピーしました!

コメント

コメントする