free514dom's picture
Create app.py
e55b902 verified
Raw
History Blame Contribute Delete
2.95 kB
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()