从‘玻璃变慢光’说起:手把手用Python可视化理解折射率、相速度与波长关系
从‘玻璃变慢光’说起手把手用Python可视化理解折射率、相速度与波长关系当阳光穿过棱镜时那道彩虹般的色散现象总是令人着迷。但你是否想过为什么不同颜色的光在玻璃中会以不同速度传播这背后隐藏着折射率与光波频率的微妙关系。本文将通过Python代码带你亲手绘制光在介质中的减速轨迹用动态图表揭开色散现象背后的数学之美。1. 光学实验室的数字化准备理解光在介质中的行为需要三个关键工具描述折射率随波长变化的色散模型、计算相速度的物理公式以及将抽象概念可视化的编程手段。我们先从搭建数字实验室开始。1.1 柯西公式折射率的波长密码19世纪数学家柯西提出的经验公式完美描述了玻璃等透明介质在可见光波段的折射率变化import numpy as np def cauchy_dispersion(wavelength, A1.5, B3000): 柯西色散公式 (波长单位: nm) return A B/(wavelength**2) * 1e-6这个简洁的数学关系揭示了一个有趣现象蓝光450nm比红光650nm在玻璃中经历更强的折射。用以下代码生成折射率曲线import matplotlib.pyplot as plt wavelengths np.linspace(400, 700, 100) # 可见光谱范围 n_values cauchy_dispersion(wavelengths) plt.figure(figsize(10,6)) plt.plot(wavelengths, n_values, linewidth3) plt.xlabel(波长 (nm), fontsize12) plt.ylabel(折射率 n, fontsize12) plt.title(玻璃折射率的色散曲线, fontsize15) plt.grid(True) plt.show()你会看到一条典型的正常色散曲线——随着波长增加折射率单调递减。这就是棱镜分光的数学根源。1.2 相速度计算光速的介质变奏曲真空中所有光都以恒定速度c传播但在介质中相速度v与折射率n的关系为v c / n其中c≈3×10⁸ m/s。Python实现这个关系时需要注意单位统一c 299792458 # 真空光速 (m/s) def phase_velocity(n): return c / n # 计算红光(650nm)和蓝光(450nm)的相速度 n_red cauchy_dispersion(650) n_blue cauchy_dispersion(450) v_red phase_velocity(n_red) v_blue phase_velocity(n_blue) print(f红光相速度: {v_red/1e6:.2f} ×10⁶ m/s) print(f蓝光相速度: {v_blue/1e6:.2f} ×10⁶ m/s)典型输出结果会显示蓝光比红光慢约5%这个差异正是色散的直观体现。2. 波长压缩效应的动态演示当光从真空进入介质不仅速度改变波长也会发生压缩。这个现象可以通过波数和折射率的关系来理解。2.1 介质中的波长变形记波长λ与频率f的关系在介质中变为λ_medium v / f (c/n) / f λ_vacuum / n用Python对比真空与介质中的波长def wavelength_in_medium(wavelength_vacuum, n): return wavelength_vacuum / n # 计算650nm红光在玻璃中的波长 wvl_red_medium wavelength_in_medium(650, n_red) print(f红光波长压缩比: {650/wvl_red_medium:.2f}倍)2.2 交互式波长压缩可视化创建一个动态图表来展示不同颜色光的波长变化from ipywidgets import interact def plot_wavelength_compression(wavelength550): n cauchy_dispersion(wavelength) wvl_medium wavelength / n plt.figure(figsize(10,4)) plt.barh([真空,玻璃], [wavelength, wvl_medium], color[#FF6B6B,#4ECDC4]) plt.text(wavelength/2, 0, f{wavelength}nm, hacenter, vacenter, colorwhite) plt.text(wvl_medium/2, 1, f{wvl_medium:.1f}nm, hacenter, vacenter, colorwhite) plt.xlabel(波长 (nm)) plt.title(f{wavelength}nm光在玻璃中的波长压缩, pad20) plt.xlim(0, 700) plt.show() interact(plot_wavelength_compression, wavelength(400,700,10))拖动滑块时可以直观看到不同颜色光进入玻璃后的波长收缩效果折射率越大的光波压缩越明显。3. 波数与相速度的舞蹈波数k是理解波动传播的关键参数它与相速度有着精妙的数学联系。在光学中这个关系通过折射率完美呈现。3.1 波数的双重身份波数的物理定义是k 2π / λ但在介质中它还与折射率相关k_medium n × k_vacuum用Python验证这个关系def wave_number(wavelength): return 2 * np.pi / (wavelength * 1e-9) # 转换为国际单位 k_red_vac wave_number(650) k_red_med wave_number(650/n_red) print(f真空波数: {k_red_vac:.3e} rad/m) print(f介质波数: {k_red_med:.3e} rad/m) print(f比值: {k_red_med/k_red_vac:.3f} ≈ 折射率n{n_red:.3f})3.2 相速度的波数诠释相速度的波数表达式揭示了更深层的物理图景v_phase ω / k通过下面代码验证三种计算相速度方法的一致性frequency c / (650e-9) # 红光频率 omega 2 * np.pi * frequency v1 phase_velocity(n_red) # c/n v2 omega / wave_number(650) / n_red # ω/k_medium v3 omega / (n_red * wave_number(650)) # ω/(n*k_vacuum) print(f方法1: {v1:.3e} m/s) print(f方法2: {v2:.3e} m/s) print(f方法3: {v3:.3e} m/s)三种方法结果一致展示了折射率如何统一了不同视角下的相速度描述。4. 从单色光到脉冲传播的进阶探索当不同频率的光波组合成脉冲信号时折射率的频率依赖性会导致更复杂的传播现象。4.1 群速度与相速度的对比在色散介质中能量传播速度群速度与相位传播速度不同def group_velocity(wavelength, dispersion_func): 数值计算群速度 delta 1e-9 # 微小波长变化 n1 dispersion_func(wavelength - delta) n2 dispersion_func(wavelength delta) dn_dlambda (n2 - n1)/(2*delta) omega 2 * np.pi * c / (wavelength*1e-9) return c / (n1 - wavelength*dn_dlambda) wavelength 550 # 选择绿光 v_phase phase_velocity(cauchy_dispersion(wavelength)) v_group group_velocity(wavelength, cauchy_dispersion) print(f相速度: {v_phase/1e6:.2f} ×10⁶ m/s) print(f群速度: {v_group/1e6:.2f} ×10⁶ m/s)在正常色散介质中群速度通常小于相速度这个差异会导致脉冲形状在传播过程中发生畸变。4.2 脉冲传播的动态模拟创建一个高斯脉冲在色散介质中传播的动画from matplotlib.animation import FuncAnimation def gaussian_pulse(t, t00, width1e-14): return np.exp(-((t-t0)/width)**2) # 设置时间轴 t np.linspace(-2e-13, 2e-13, 1000) pulse_vacuum gaussian_pulse(t) # 在介质中传播后的脉冲简化模型 def dispersed_pulse(t, n, dn_domega): return gaussian_pulse(t) * np.exp(1j * dn_domega * t**2) fig, ax plt.subplots(figsize(10,6)) line1, ax.plot(t, pulse_vacuum.real, label真空中的脉冲) line2, ax.plot(t, np.zeros_like(t), label介质中的脉冲) ax.set_ylim(-1.1, 1.1) ax.legend() def update(frame): dn_domega frame * 1e-28 # 色散参数 pulse_medium dispersed_pulse(t, n_red, dn_domega).real line2.set_ydata(pulse_medium) return line1, line2 ani FuncAnimation(fig, update, frames50, interval100) plt.close()这段代码展示了随着色散增强脉冲如何逐渐展宽——这是光纤通信中必须克服的关键效应。