レンズは光を集めたり発散させたりする光学素子であり、カメラ、望遠鏡、顕微鏡など多くの光学機器の心臓部です。本記事では薄レンズの公式を導出し、レンズによる結像の仕組みを理解します。
本記事の内容
- 薄レンズの近似
- 薄レンズの公式の導出
- 倍率
- 凸レンズと凹レンズの結像
- レンズメーカーの方程式
- Pythonでの光線追跡と可視化
前提知識
この記事を読む前に、以下の記事を読んでおくと理解が深まります。
薄レンズの近似
薄レンズの近似(thin lens approximation)とは、レンズの厚さがその焦点距離に比べて十分小さいとみなし、光線がレンズの中心面で屈折すると考える近似です。
この近似のもとでは、光軸に近い光線(近軸光線: paraxial ray)に対して、以下の3つの基本光線を考えます。
- 光軸に平行な光線: レンズを通過後、焦点を通る
- レンズの中心を通る光線: 方向を変えずに直進する
- 焦点を通る光線: レンズを通過後、光軸に平行になる
薄レンズの公式の導出
物体距離(レンズから物体までの距離)を $a$、像距離(レンズから像までの距離)を $b$、焦点距離を $f$ とします。
物体の高さを $h$、像の高さを $h’$ とします。光軸に平行に入射した光線は焦点 $F’$ を通り、レンズ中心を通る光線は直進します。
幾何学的導出
レンズ中心を通る光線に関する三角形の相似から:
$$ \frac{h’}{h} = -\frac{b}{a} $$
焦点を通る光線に関する三角形の相似から:
$$ \frac{h’}{h} = -\frac{b – f}{f} $$
これら2式を等置します。
$$ \begin{align} \frac{b}{a} &= \frac{b – f}{f} \\ bf &= a(b – f) \\ bf &= ab – af \\ af + bf &= ab \end{align} $$
両辺を $abf$ で割ると:
$$ \frac{1}{b} + \frac{1}{a} = \frac{1}{f} $$
$$ \boxed{\frac{1}{f} = \frac{1}{a} + \frac{1}{b}} $$
これが薄レンズの公式(thin lens equation)です。
倍率
横倍率(lateral magnification)$m$ は:
$$ \boxed{m = \frac{h’}{h} = -\frac{b}{a}} $$
- $|m| > 1$: 拡大像
- $|m| < 1$: 縮小像
- $m > 0$: 正立像(虚像)
- $m < 0$: 倒立像(実像)
凸レンズと凹レンズ
凸レンズ(収束レンズ): $f > 0$
物体の位置に応じて像が変化します。
| 物体距離 $a$ | 像の種類 | 像の大きさ |
|---|---|---|
| $a > 2f$ | 実像 | 縮小 |
| $a = 2f$ | 実像 | 等倍 |
| $f < a < 2f$ | 実像 | 拡大 |
| $a = f$ | 像なし(∞) | — |
| $a < f$ | 虚像 | 拡大 |
凹レンズ(発散レンズ): $f < 0$
凹レンズは常に縮小の正立虚像を作ります。レンズの公式で $f < 0$ とすると $b < 0$ となり、像はレンズと同じ側にできます。
レンズメーカーの方程式
レンズの焦点距離は、レンズの屈折率と曲率半径によって決まります。レンズの屈折率を $n$、周囲媒質の屈折率を $n_0$(通常は空気で $n_0=1$)、前面の曲率半径を $R_1$、後面の曲率半径を $R_2$ とすると:
$$ \boxed{\frac{1}{f} = \left(\frac{n}{n_0} – 1\right)\left(\frac{1}{R_1} – \frac{1}{R_2}\right)} $$
これがレンズメーカーの方程式(lensmaker’s equation)です。
符号の規約
- 光は左から右に進むとする
- 曲面の中心が右側にあるとき $R > 0$(凸面)
- 曲面の中心が左側にあるとき $R < 0$(凹面)
導出
球面屈折の公式を前面と後面に順に適用して導出します。
屈折率 $n_1$ から $n_2$ の球面境界(曲率半径 $R$)での屈折公式は:
$$ \frac{n_1}{s} + \frac{n_2}{s’} = \frac{n_2 – n_1}{R} $$
前面($n_0 \to n$、曲率半径 $R_1$):
$$ \frac{n_0}{s_1} + \frac{n}{s_1′} = \frac{n – n_0}{R_1} $$
後面($n \to n_0$、曲率半径 $R_2$)。薄レンズ近似より $s_2 = -s_1’$:
$$ \frac{n}{s_2} + \frac{n_0}{s_2′} = \frac{n_0 – n}{R_2} $$
2式を足し合わせると:
$$ \frac{n_0}{s_1} + \frac{n_0}{s_2′} = (n – n_0)\left(\frac{1}{R_1} – \frac{1}{R_2}\right) $$
$s_1 = a$、$s_2′ = b$ とおき、$n_0$ で割って $1/a + 1/b = 1/f$ と対応させると、レンズメーカーの方程式が得られます。
Pythonでの実装
薄レンズの結像シミュレーション
import numpy as np
import matplotlib.pyplot as plt
def thin_lens_image(a, f):
"""薄レンズの公式から像距離を計算"""
if abs(1/f - 1/a) < 1e-10:
return np.inf # 物体が焦点上
b = 1.0 / (1.0/f - 1.0/a)
return b
def draw_lens_diagram(a, f, h=1.0, ax=None):
"""光線追跡による結像図を描画"""
if ax is None:
fig, ax = plt.subplots(figsize=(12, 5))
b = thin_lens_image(a, f)
m = -b / a
h_prime = m * h
# レンズ(中心に縦線)
lens_height = max(abs(h), abs(h_prime), 2) * 1.5
ax.plot([0, 0], [-lens_height, lens_height], 'b-', linewidth=2, label='Lens')
# 光軸
x_range = max(abs(a), abs(b), abs(2*f)) * 1.3
ax.axhline(y=0, color='gray', linewidth=0.5)
# 焦点
ax.plot([-f, f], [0, 0], 'rx', markersize=10)
ax.annotate('F', xy=(-f, -0.3), fontsize=11, color='red', ha='center')
ax.annotate("F'", xy=(f, -0.3), fontsize=11, color='red', ha='center')
# 物体(矢印)
ax.annotate('', xy=(-a, h), xytext=(-a, 0),
arrowprops=dict(arrowstyle='->', color='green', lw=2))
ax.text(-a, h + 0.2, 'Object', ha='center', fontsize=10, color='green')
# 光線1: 光軸に平行 → 焦点を通る
ax.plot([-a, 0], [h, h], 'r-', linewidth=1, alpha=0.7)
if np.isfinite(b):
ax.plot([0, b], [h, h_prime], 'r-', linewidth=1, alpha=0.7)
# 光線2: レンズ中心を通る
if np.isfinite(b):
ax.plot([-a, b], [h, h_prime], 'orange', linewidth=1, alpha=0.7)
# 光線3: 焦点を通る → 光軸に平行
slope_to_F = (h - 0) / (-a - (-f))
y_at_lens = h + slope_to_F * (0 - (-a))
# 前焦点を通る光線がレンズに到達する高さ
y_at_lens_3 = h * f / (a - f) if abs(a - f) > 1e-10 else h
# 前焦点からレンズまで
ax.plot([-a, 0], [h, h + (0 - (-a)) * (0 - h) / ((-f) - (-a))], 'm-', linewidth=1, alpha=0.7)
# 像(矢印)
if np.isfinite(b) and abs(b) < x_range * 2:
if b > 0: # 実像
ax.annotate('', xy=(b, h_prime), xytext=(b, 0),
arrowprops=dict(arrowstyle='->', color='blue', lw=2))
ax.text(b, h_prime - 0.4 * np.sign(h_prime), 'Real image',
ha='center', fontsize=10, color='blue')
else: # 虚像
ax.annotate('', xy=(b, h_prime), xytext=(b, 0),
arrowprops=dict(arrowstyle='->', color='purple', lw=2, ls='--'))
ax.text(b, h_prime + 0.3, 'Virtual image',
ha='center', fontsize=10, color='purple')
ax.set_xlim(-x_range, x_range)
ax.set_ylim(-lens_height, lens_height)
ax.set_xlabel('z [arbitrary unit]', fontsize=11)
ax.set_ylabel('y [arbitrary unit]', fontsize=11)
ax.set_aspect('equal')
ax.grid(True, alpha=0.3)
return ax
# --- 3つの結像パターンを描画 ---
fig, axes = plt.subplots(3, 1, figsize=(12, 12))
f = 2.0
# ケース1: a > 2f(縮小実像)
draw_lens_diagram(a=6.0, f=f, h=1.0, ax=axes[0])
axes[0].set_title('Case 1: a > 2f → Reduced real image', fontsize=12)
# ケース2: f < a < 2f(拡大実像)
draw_lens_diagram(a=3.0, f=f, h=1.0, ax=axes[1])
axes[1].set_title('Case 2: f < a < 2f → Magnified real image', fontsize=12)
# ケース3: a < f(拡大虚像)
draw_lens_diagram(a=1.0, f=f, h=1.0, ax=axes[2])
axes[2].set_title('Case 3: a < f → Magnified virtual image', fontsize=12)
plt.tight_layout()
plt.show()
物体距離と像距離の関係
import numpy as np
import matplotlib.pyplot as plt
# --- 物体距離に対する像距離と倍率のグラフ ---
f = 5.0 # 焦点距離
a = np.linspace(0.5, 30, 1000)
# 薄レンズの公式
b = 1.0 / (1.0/f - 1.0/a)
m = -b / a
fig, axes = plt.subplots(1, 2, figsize=(14, 5))
# 像距離
axes[0].plot(a, b, 'b-', linewidth=2)
axes[0].axhline(y=f, color='r', linestyle='--', alpha=0.5, label=f'b = f = {f}')
axes[0].axvline(x=f, color='g', linestyle='--', alpha=0.5, label=f'a = f = {f}')
axes[0].set_xlabel('Object distance a', fontsize=12)
axes[0].set_ylabel('Image distance b', fontsize=12)
axes[0].set_title('Image distance vs Object distance', fontsize=13)
axes[0].set_xlim(0, 30)
axes[0].set_ylim(-30, 30)
axes[0].legend(fontsize=11)
axes[0].grid(True, alpha=0.3)
# 倍率
axes[1].plot(a, m, 'r-', linewidth=2)
axes[1].axhline(y=-1, color='gray', linestyle='--', alpha=0.5, label='m = -1 (equal size)')
axes[1].axhline(y=0, color='gray', linewidth=0.5)
axes[1].axvline(x=f, color='g', linestyle='--', alpha=0.5, label=f'a = f = {f}')
axes[1].set_xlabel('Object distance a', fontsize=12)
axes[1].set_ylabel('Magnification m', fontsize=12)
axes[1].set_title('Magnification vs Object distance', fontsize=13)
axes[1].set_xlim(0, 30)
axes[1].set_ylim(-5, 5)
axes[1].legend(fontsize=11)
axes[1].grid(True, alpha=0.3)
plt.tight_layout()
plt.show()
まとめ
本記事では、レンズの公式と結像について解説しました。
- 薄レンズの公式: $1/f = 1/a + 1/b$
- 横倍率: $m = -b/a$
- 凸レンズ: 物体の位置に応じて実像・虚像を作る
- 凹レンズ: 常に縮小正立虚像を作る
- レンズメーカーの方程式: $1/f = (n/n_0 – 1)(1/R_1 – 1/R_2)$
次のステップとして、以下の記事も参考にしてください。