【raytracing】光線の高さや位置、角度を取得する方法[Python]

  • URLをコピーしました!
目次

raytracing

前回、raytracingライブラリで同じ点から異なる角度で射出される複数の平行光を作る方法を紹介しました。

今回はraytracingライブラリで光線の高さや位置、角度を取得する方法を紹介します。

まず基本とする光線のプログラムはこんな感じです。

from raytracing import *

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

path.display(ObjectRays(diameter=1, halfAngle=np.radians(10), H=1, T=7))

実行結果

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

trace

各位置での光線の位置(X軸方向)や高さ(Y軸方向)、角度を取得するには「.trace」という関数を用います。

ですがこの「.trace()」はなかなかクセがあるので、順を追って解説していきます。

「.trace()」は「ImagingPath」に対して用いるので「path = ImagingPath()」として光路を作成している場合、「trace = path.trace()」として光線の追跡結果を得ます。

そのためこんな感じでプログラムを書きがちで、エラーとなります。

from raytracing import *

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

path.display(ObjectRays(diameter=1, halfAngle=np.radians(10), H=1, T=7))

trace = path.trace()

print(trace)

実行結果
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
Cell In[23], line 10
      6 path.append(Space(d=50))
      8 path.display(ObjectRays(diameter=1, halfAngle=np.radians(10), H=1, T=7))
---> 10 trace = path.trace()
     12 print(trace)

TypeError: MatrixGroup.trace() missing 1 required positional argument: 'inputRay'

エラーの内容としては引数として「inputRay」がないよと言われています。

ここで「path.display(ObjectRays(diameter=1, halfAngle=np.radians(10), H=1, T=7))」で設定しているじゃないかと思われるのですが、どうやら「.display()」と「.trace()」は連動していないようです。

「.display()」での光源の設定はあくまでも「.display()」のもの、「.trace()」には「.trace」で設定してやる必要があるということです。

ということで「Ray」関数を使って一本の光線を定義してあげ、それを「.trace()」の引数に与えます。

(ここでは図の出力はコメントアウトしています)

from raytracing import *

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

# path.display(ObjectRays(diameter=1, halfAngle=np.radians(10), H=1, T=7))

ray = Ray(y=0, theta=np.radians(10))

trace = path.trace(ray)

print(trace)

実行結果
[<raytracing.ray.Ray object at 0x110b34dc0>, 
<raytracing.ray.Ray object at 0x110b34dc0>, 
<raytracing.ray.Ray object at 0x110b355d0>, 
<raytracing.ray.Ray object at 0x110e6d3c0>, 
<raytracing.ray.Ray object at 0x110e6d3c0>, 
<raytracing.ray.Ray object at 0x110e6d930>]

どうやら解析できた様ですが、オブジェクトになっています。

ということでfor文を使って一つずつ見てみます。

(ここでは図の出力はコメントアウトしています)

from raytracing import *

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

# path.display(ObjectRays(diameter=1, halfAngle=np.radians(10), H=1, T=7))

ray = Ray(y=0, theta=np.radians(10))

trace = path.trace(ray)

for data in trace:
    print(data)

実行結果
y =  0.000
theta =  0.175
z = 0.000
y =  0.000
theta =  0.175
z = 0.000
y =  8.727
theta =  0.175
z = 50.000
y =  8.727
theta = -0.698
z = 50.000
y =  8.727
theta = -0.698
z = 50.000
y = -26.180
theta = -0.698
z = 100.000

「y」が各位置での高さ、「theta」が各位置での角度、「z」が位置です。

光源-空間1-レンズ-空間2という光学系に対して、6回出力されています。

これは「光源」、「空間1の入射側」、「レンズの入射側」、「レンズの出射側」、「空間2の入射側」、「光路の最後」での出力となっているようです。

ちなみに各データを直接取得する場合は「.y」で高さ、「.z」で位置、「.theta」で角度を取得することができます。

(ここでは図の出力はコメントアウトしています)

from raytracing import *

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

# path.display(ObjectRays(diameter=1, halfAngle=np.radians(10), H=1, T=7))

ray = Ray(y=0, theta=np.radians(10))

trace = path.trace(ray)

for data in trace:
    print(data.y, data.z, data.theta)

実行結果
0 0 0.17453292519943295
0 0 0.17453292519943295
8.726646259971647 50.0 0.17453292519943295
8.726646259971647 50.0 -0.6981317007977317
8.726646259971647 50.0 -0.6981317007977317
-26.17993877991494 100.0 -0.6981317007977317

複数の入射角度での光線解析を行う場合

複数の入射角度での光線解析を行いたい場合は初期の光線の角度のリストを作成し、for文で一つずつ「.trace()」に渡すという方法が考えられます。

from raytracing import *

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

#path.display(ObjectRays(diameter=1, halfAngle=np.radians(10), H=1, T=7))

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

for angle in angle_list:
    print(f"==========angle: {angle} deg==========")
    ray = Ray(y=0, theta=np.radians(angle))
    trace = path.trace(ray)

    for data in trace:
        print(data.y, data.z, data.theta)

実行結果
==========angle: -10.0 deg==========
0 0 -0.17453292519943295
0 0 -0.17453292519943295
-8.726646259971647 50.0 -0.17453292519943295
-8.726646259971647 50.0 0.6981317007977317
-8.726646259971647 50.0 0.6981317007977317
26.17993877991494 100.0 0.6981317007977317
==========angle: -6.666666666666666 deg==========
0 0 -0.11635528346628862
0 0 -0.11635528346628862
-5.817764173314431 50.0 -0.11635528346628862
-5.817764173314431 50.0 0.4654211338651545
-5.817764173314431 50.0 0.4654211338651545
17.453292519943293 100.0 0.4654211338651545
==========angle: -3.333333333333333 deg==========
0 0 -0.05817764173314431
0 0 -0.05817764173314431
-2.9088820866572154 50.0 -0.05817764173314431
-2.9088820866572154 50.0 0.23271056693257725
-2.9088820866572154 50.0 0.23271056693257725
8.726646259971647 100.0 0.23271056693257725
==========angle: 0.0 deg==========
0 0 0.0
0 0 0.0
0.0 50.0 0.0
0.0 50.0 0.0
0.0 50.0 0.0
0.0 100.0 0.0
==========angle: 3.333333333333334 deg==========
0 0 0.058177641733144325
0 0 0.058177641733144325
2.9088820866572163 50.0 0.058177641733144325
2.9088820866572163 50.0 -0.2327105669325773
2.9088820866572163 50.0 -0.2327105669325773
-8.726646259971648 100.0 -0.2327105669325773
==========angle: 6.666666666666668 deg==========
0 0 0.11635528346628865
0 0 0.11635528346628865
5.8177641733144325 50.0 0.11635528346628865
5.8177641733144325 50.0 -0.4654211338651546
5.8177641733144325 50.0 -0.4654211338651546
-17.453292519943297 100.0 -0.4654211338651546
==========angle: 10.0 deg==========
0 0 0.17453292519943295
0 0 0.17453292519943295
8.726646259971647 50.0 0.17453292519943295
8.726646259971647 50.0 -0.6981317007977317
8.726646259971647 50.0 -0.6981317007977317
-26.17993877991494 100.0 -0.6981317007977317

次回はこの光線解析の結果を使って、自分で光線図を作成する方法を紹介します。

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

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

コメント

コメントする

目次