用Python模拟单缝衍射从公式到可视化光强分布图当一束光穿过比波长略宽的狭缝时会在屏幕上形成明暗相间的条纹——这就是著名的单缝衍射现象。作为波动光学的基础实验之一单缝衍射不仅揭示了光的波动本质其数学描述和模拟实现更是理解现代光学系统的关键。本文将带你用Python从零构建单缝衍射模型通过代码实现理论公式的可视化直观展示缝宽、波长等参数如何影响衍射图样。1. 理论基础与模型搭建单缝夫琅禾费衍射的光强分布由经典公式决定$$ I I_0 \left( \frac{\sin u}{u} \right)^2 $$其中 $u \frac{\pi a \sin \theta}{\lambda}$$a$为缝宽$\lambda$为波长$\theta$为衍射角。中央明纹强度$I_0$与入射光强成正比。关键参数关系表参数物理意义典型值范围影响规律a单缝宽度0.01-1mm与条纹宽度成反比λ光波长400-700nm波长越长衍射越明显f透镜焦距0.5-2m决定屏幕上的实际尺度建立计算模型需要三个核心步骤定义参数空间设置合理的物理参数和计算范围离散化处理将连续角度θ转换为数值计算可处理的离散点归一化处理将光强统一缩放到[0,1]区间便于可视化import numpy as np import matplotlib.pyplot as plt # 基础参数设置 wavelength 632.8e-9 # 氦氖激光波长(单位:m) a 0.1e-3 # 单缝宽度(单位:m) f 1.0 # 透镜焦距(单位:m)2. 光强分布计算实现采用NumPy进行向量化计算可显著提升效率。衍射角的处理需要注意实际实验中θ通常很小5°故采用小角度近似$\sinθ ≈ \tanθ x/f$计算范围应覆盖多个明暗条纹周期def calculate_intensity(a, wavelength, f, screen_width0.02): 计算单缝衍射光强分布 x np.linspace(-screen_width/2, screen_width/2, 2000) # 屏幕坐标 theta np.arctan(x/f) # 衍射角计算 u np.pi * a * np.sin(theta) / wavelength intensity (np.sin(u)/u)**2 # 光强公式 intensity[np.isnan(intensity)] 1 # 处理u0处的奇异点 return x, intensity常见问题处理技巧当u接近0时会出现0/0不定式需特殊处理使用np.sinc函数可能产生精度问题建议显式计算屏幕采样点数需足够多建议1000以避免aliasing效应3. 结果可视化与参数分析Matplotlib提供了灵活的绘图工具我们可以创建专业级可视化def plot_diffraction(x, intensity, params): 绘制衍射光强分布图 plt.figure(figsize(12, 6)) # 光强曲线绘制 plt.subplot(1, 2, 1) plt.plot(x*1000, intensity, b-, linewidth1.5) plt.xlabel(屏幕位置 (mm)) plt.ylabel(相对光强) plt.title(单缝衍射光强分布曲线) # 二维灰度图模拟 plt.subplot(1, 2, 2) pattern np.outer(intensity, np.ones(100)) # 扩展为二维 plt.imshow(pattern.T, cmapgray, extent[x[0]*1000, x[-1]*1000, 0, 1], aspectauto) plt.xlabel(屏幕位置 (mm)) plt.title(衍射条纹灰度模拟) plt.tight_layout() plt.show()执行计算与绘图x, intensity calculate_intensity(a, wavelength, f) plot_diffraction(x, intensity, {a: a, λ: wavelength})4. 参数影响与交互探索通过改变关键参数观察衍射图样变化可以验证光学原理缝宽a的影响widths [0.05e-3, 0.1e-3, 0.2e-3] # 不同缝宽 plt.figure(figsize(10, 6)) for a in widths: x, intensity calculate_intensity(a, wavelength, f) plt.plot(x*1000, intensity, labelfa{a*1e3:.2f}mm) plt.legend() plt.title(不同缝宽下的衍射图样对比)波长λ的影响wavelengths [400e-9, 550e-9, 700e-9] # 可见光范围 plt.figure(figsize(10, 6)) for λ in wavelengths: x, intensity calculate_intensity(a, λ, f) plt.plot(x*1000, intensity, labelfλ{λ*1e9:.0f}nm) plt.legend() plt.title(不同波长下的衍射图样对比)衍射反比律验证 中央明纹宽度$\Delta x 2fλ/a$可通过测量不同参数组合下的实际条纹宽度验证这一基本规律。5. 高级扩展与实验对比将理论模拟与实际实验数据对比是验证模型准确性的好方法。我们可以添加噪声模拟noisy_intensity intensity 0.02*np.random.randn(len(intensity)) noisy_intensity np.clip(noisy_intensity, 0, 1) # 保持物理合理性考虑非理想因素光源尺寸效应透镜像差影响缝边缘衍射效应创建交互工具 使用IPython widgets构建参数调节界面from ipywidgets import interact interact(a(0.01, 0.5, 0.01), λ(400, 700, 10)) def interactive_diffraction(a0.1, λ632.8): a * 1e-3 # 转换为米 λ * 1e-9 x, intensity calculate_intensity(a, λ, f) plot_diffraction(x, intensity, {a: a, λ: λ})在实际教学中这种可视化模拟可以帮助学生直观理解为什么几何光学在aλ时成立如何通过衍射图样反推缝宽光学仪器分辨率限制的来源