import gradio as gr import numpy as np import matplotlib.pyplot as plt def plot_interference(wavelength_nm, slit_distance_um): # 将单位转换为国际标准单位 (米) wavelength = wavelength_nm * 1e-9 d = slit_distance_um * 1e-6 L = 1.0 # 假设屏幕距离双缝 1 米 # 屏幕上的观测位置 (正负 1.5 厘米范围) y = np.linspace(-0.015, 0.015, 1000) # 计算相位差和光强度公式: I = I_0 * cos^2(pi * d * y / (lambda * L)) phase = (np.pi * d * y) / (wavelength * L) intensity = np.cos(phase)**2 # 根据波长近似设置图表颜色 (仅为科普视觉效果) color = '#2ca02c' # 默认绿色 if wavelength_nm < 450: color = '#1f77b4' # 蓝紫 elif wavelength_nm < 550: color = '#2ca02c' # 绿 elif wavelength_nm < 650: color = '#ff7f0e' # 橙黄 else: color = '#d62728' # 红 # 创建图表 fig, (ax1, ax2) = plt.subplots(2, 1, figsize=(10, 8)) # 1. 绘制模拟的屏幕干涉条纹 X, Y = np.meshgrid(np.linspace(0, 1, 100), y) # 将一维强度扩展为二维图像 img_intensity = intensity.reshape(-1, 1) * np.ones((1, 100)) ax1.imshow(img_intensity, cmap='gray', aspect='auto', extent=[0, 1, y[0]*1000, y[-1]*1000]) ax1.set_title('屏幕上的干涉图样 (亮处代表光子到达概率高)', fontsize=14) ax1.set_ylabel('屏幕上的位置 (毫米)', fontsize=12) ax1.set_xticks([]) # 隐藏X轴刻度 # 2. 绘制光强度的数学分布曲线 ax2.plot(y * 1000, intensity, color=color, linewidth=2) ax2.fill_between(y * 1000, intensity, color=color, alpha=0.3) ax2.set_title('光强分布曲线 (波峰=亮条纹,波谷=暗条纹)', fontsize=14) ax2.set_xlabel('屏幕上的位置 (毫米)', fontsize=12) ax2.set_ylabel('相对光强度', fontsize=12) ax2.grid(True, linestyle='--', alpha=0.6) plt.tight_layout() return fig # 构建 Gradio 用户交互界面 demo = gr.Interface( fn=plot_interference, inputs=[ gr.Slider(minimum=400, maximum=700, step=10, value=500, label="光的波长 (纳米) - 决定颜色,红色波长较长,蓝色较短"), gr.Slider(minimum=10, maximum=100, step=5, value=50, label="双缝间距 (微米) - 两条缝隙的距离") ], outputs=gr.Plot(label="实验结果"), title="🌌 简易双缝干涉实验模拟器", description="**这就是量子力学的经典大门!** \n\n想象光是水波,当它穿过两条狭缝时,两股波会相互碰撞。波峰和波峰叠加的地方会变得更亮(亮条纹),波峰和波谷相遇的地方光会消失(暗条纹)。你可以试着拉动滑块:\n* **波长变大(偏红光)**:条纹会变得更宽敞吗?\n* **双缝间距变大**:条纹会变得更密集还是更稀疏?", theme=gr.themes.Soft() ) # 启动应用 if __name__ == "__main__": demo.launch()