ランベルト反射(Lambertian reflection)

ランベルト反射(Lambertian reflection)

乱反射に関する方程式の例として、ランベルト反射(Lambertian reflection)があります。

この反射モデルでは、光が表面に当たった後、ランダムな方向に均等に散乱されると仮定されます。

このモデルでは、反射率は入射角に依存せず、すべての方向に対して均一です。

ランベルト反射の方程式は以下のように表されます:

$$
L_o(\omega_o) = \frac{c}{\pi} L_i(\omega_i) \max(0, \omega_i \cdot n)
$$

ここで、$ ( L_o(\omega_o) ) $は出射光の放射束密度、$ ( L_i(\omega_i) ) $は入射光の放射束密度、$ ( \omega_o ) $は視線の方向、$ ( \omega_i ) $は入射光の方向、$ ( n ) $は法線ベクトル、$ ( c ) $は反射率です。

Pythonでこの式を解き、グラフ化するためのサンプルコードを以下に示します。

このコードでは、ランダムな入射光の方向を仮定し、その方向に応じてランベルト反射による出射光の放射束密度を計算し、その結果をグラフ化します。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
import numpy as np
import matplotlib.pyplot as plt

def lambertian_reflection(cos_theta_i):
return np.maximum(0, cos_theta_i) / np.pi

# 入射光の角度を生成
num_samples = 1000
cos_theta_i = np.random.uniform(low=-1, high=1, size=num_samples)
theta_i = np.arccos(cos_theta_i)

# ランベルト反射による放射束密度を計算
lo = lambertian_reflection(cos_theta_i)

# 結果をグラフ化
plt.figure(figsize=(8, 6))
plt.scatter(np.degrees(theta_i), lo, s=5)
plt.title('Lambertian Reflection')
plt.xlabel('Incident Angle (degrees)')
plt.ylabel('Radiant Intensity')
plt.grid(True)
plt.show()

このコードでは、入射光の角度を一様にランダムに生成し、それに対応する出射光の放射束密度を計算しています。

最後に、入射角度に対する出射光の放射束密度をグラフ化しています。

[実行結果]

ソースコード解説

このソースコードは、Pythonを使用してランベルト反射に関する放射束密度を計算し、グラフ化するものです。

以下は、それぞれの部分の詳細な説明です。

インポート:

1
2
import numpy as np
import matplotlib.pyplot as plt
  • numpy ライブラリを np としてインポートし、数値計算を行うために使用します。
  • matplotlib.pyplot モジュールを plt としてインポートし、グラフを描画するために使用します。

関数定義:

1
2
def lambertian_reflection(cos_theta_i):
return np.maximum(0, cos_theta_i) / np.pi
  • lambertian_reflection 関数は、ランベルト反射による放射束密度を計算する関数です。
  • 入射角の余弦を受け取り、ランベルト反射による放射束密度を計算して返します。

入射光の角度生成:

1
2
3
num_samples = 1000
cos_theta_i = np.random.uniform(low=-1, high=1, size=num_samples)
theta_i = np.arccos(cos_theta_i)
  • num_samples 個のサンプルを生成します。
  • np.random.uniform 関数を使用して、$-1$から$1$までの一様分布から num_samples 個の乱数を生成し、入射光の角度の余弦を生成します。
  • np.arccos 関数を使用して、余弦から入射角を計算します。

ランベルト反射による放射束密度の計算:

1
lo = lambertian_reflection(cos_theta_i)
  • 先ほど定義した lambertian_reflection 関数を使用して、ランベルト反射による放射束密度を計算します。

結果のグラフ化:

1
2
3
4
5
6
7
plt.figure(figsize=(8, 6))
plt.scatter(np.degrees(theta_i), lo, s=5)
plt.title('Lambertian Reflection')
plt.xlabel('Incident Angle (degrees)')
plt.ylabel('Radiant Intensity')
plt.grid(True)
plt.show()
  • グラフの大きさを指定し、plt.figure(figsize=(8, 6)) を使用して新しいグラフを作成します。
  • plt.scatter を使用して、散布図をプロットします。
    $x軸$に入射角、$y軸$に放射束密度をプロットします。
  • plt.titleplt.xlabelplt.ylabel を使用して、グラフのタイトルと軸ラベルを設定します。
  • plt.grid(True) を使用して、グリッド線を表示します。
  • plt.show() を使用して、グラフを表示します。

これらの手順により、ランベルト反射に関する放射束密度の計算結果がグラフ化されます。

結果解説

[実行結果]

上記のPythonコードによって生成されるグラフは、ランベルト反射による放射束密度の振る舞いを示しています。
以下は、グラフの内容の詳細な説明です。

横軸 (Incident Angle):

入射光の角度を示しています。
この角度は度数法で表され、0度が垂直方向、90度が水平方向を意味します。
ランダムに生成された入射光の角度がこの軸に表示されます。

縦軸 (Radiant Intensity):

出射光の放射束密度を示しています。
これはランベルト反射によって得られた出射光の強度を示します。
放射束密度は無次元の値で、ランベルト反射においては最大値が$1$です。

散布図 (Scatter Plot):

各点は、特定の入射角度に対応する出射光の放射束密度を表しています。
この散布図は、入射光の角度に対する出射光の振る舞いを視覚的に示します。
点が高いほど、出射光の強度が大きいことを示します。

タイトル (Title):

グラフのタイトルは「Lambertian Reflection」となっており、このグラフがランベルト反射に関するものであることを示します。

横軸ラベル (X-Axis Label):

「Incident Angle (degrees)」と表示されており、横軸が入射角度を表していることを示します。

縦軸ラベル (Y-Axis Label):

「Radiant Intensity」と表示されており、縦軸が出射光の放射束密度を表していることを示します。

グリッド (Grid):

グラフにはグリッドが表示されており、視覚的にデータの位置を把握しやすくなっています。

このグラフは、入射光の角度に対するランベル反射による出射光の振る舞いを表しており、ランダムな入射光の方向に対してランベル反射がどのように働くかを視覚的に理解するのに役立ちます。