news 2026/9/30 14:04:10

双缝干涉:把两条缝的图样叠起来,光为什么自己跟自己打架

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
双缝干涉:把两条缝的图样叠起来,光为什么自己跟自己打架

一块挡板上开两条平行细缝,单色光打过去,屏幕上映出的不是两条亮线,而是一排等间距的明暗条纹。把其中一条缝遮住,条纹立刻消失、只剩一团中间亮两边暗的光斑——同一束光,只因「知道不知道它走了哪条缝」,结果就完全不同。

静态图讲不清两件事:条纹间距到底由什么决定?为什么挡住一条缝,条纹就没了?所以我把它做成了一个能拖、能遮、能一颗一颗发射光子的网页:上半屏是俯视波浪场(两条缝当成两个同频点波源,实时叠加并着色),下半屏是屏上光强曲线 I(y)/I₀ 与光子累积点阵,右边一块数值面板把 ΔY 和 y₁/y₂/y₃ 算给你看。

几条关键信息先摆出来:

  • 源码:Demo Park 公开仓库 → https://atomgit.com/deli007/demo_park/tree/main/codearts-double-slit-lab,index.html可直接下载
  • 生成物:单个index.html(约 28 KB),纯前端、零依赖、不联网、不上传,全部计算在本地完成
  • 本地运行:双击文件即可;或python -m http.server 8000
  • 本地验证:1920×1200 视口;默认 λ=550nm、d=0.30mm、L=1.50m 下 ΔY=2.750mm、y₁/y₂/y₃=2.750/5.500/8.250mm;自检 8/8 通过;连发 3600 颗光子后主峰落在 2.649mm,与理论 2.750mm 差 3.7%

它算的是理想化双缝。缝是无限细的抽象线(只有一个「缝间距 d」,没有缝宽对条纹的调制),光是标量波、没有偏振,也没有单光子探测器的计数噪声模型。下面会如实写它的边界。

为什么值得看:两条缝的差别,全在一个相位差里

屏上某点 y 到底亮还是暗,只看两条缝过来的光差了多少路程。这个路程差 Δ 写成相位就是φ = π·d·y / (λ·L)(d 是缝间距、L 是缝到屏的距离),两束光叠加后的相对光强是:

I(y)/I₀ = cos²(π·d·y / (λ·L)) 光强 ΔY = λ·L / d 条纹间距 yₘ = m·λ·L / d 第 m 级亮纹位置
  • y=0(屏中心)处两条缝的路程完全相等,φ=0,cos²=1——所以中心永远是亮纹,不管参数怎么改;
  • 相邻亮纹之间相位正好涨 π,于是 y 走λL/d就又亮一次,这就是 ΔY;
  • ΔY 和 d 成反比:缝拉得越开、条纹越密;ΔY 和 λ、L 都成正比:波长越长、屏越远,条纹越宽。

页面里有三个实现决定值得说清楚:

  1. 波浪场和光强曲线共用同一套公式。phaseRad()把物理量统一换算成相位,Irel()再取cos²;波浪场那两个点源用的也是同一个随距离衰减的相位差。所以上图里加强的方向和下图曲线的高峰位置是对齐的,不是两张各画各的图。
  2. 光子落点是按 I(y) 的累积分布采样出来的。makeSampler()先把曲线在 [-Ymax, Ymax] 上离散成 3000 段的累积分布,再反解出落点。所以「一颗一颗发射」不会均匀乱撒,而是老老实实按亮纹概率多、暗纹概率少来落——累积久了就还原出条纹。
  3. 波长到颜色是一条真正的光谱映射。wavelengthToRGB()用分段线性插值算出 RGB(紫→蓝→绿→黄→红),再乘一个端部衰减因子压暗两端,而不是简单按色相环取色。

也说几处真实的边界:

  • 缝是理想细缝。真实双缝实验里缝宽决定了单缝衍射包络——条纹会被一个中间亮、两边递减的包络调制,所以远处的条纹会越来越暗。这里干涉项是纯cos²,两侧条纹一样高(单缝模式下的包络是另一套sinc²公式)。
  • 光是标量波。没有偏振、没有光子的路径纠缠,屏幕亮度是概率意义上的,不是单个光子的轨迹。
  • 光点累积没有固定种子,用的是Math.random();每次连发点阵都不一样,但直方图轮廓会稳定收敛到同一条 I(y) 曲线上。

任务描述

需求是直接粘进码道 Web 输入框的,原文如下:

开发一个单文件 index.html 的「双缝干涉实验室」网页应用,纯前端、零依赖、不联网、不上传任何数据。 画面分两块: 1) 上方是俯视波浪场:两条缝当作两个同频点波源,各自向右侧发出圆形波,叠加处按瞬时振幅着色(波峰偏暖色、波谷偏冷色),能直接看出加强区和相消区连成的射线状条纹。 2) 下方是观察屏上的光强分布图:横轴是屏上位置 y(单位毫米),纵轴是相对光强 I/I0,曲线随参数实时重画。 物理公式必须真算,不要假数据: - 双缝干涉相对光强 I(y)/I0 = cos^2(pi * d * y / (lambda * L)) - 条纹间距 deltaY = lambda * L / d - 第 m 级亮纹位置 y_m = m * lambda * L / d - 波长到颜色用可见光谱近似映射(380nm 偏紫,450nm 蓝,520nm 绿,590nm 黄,620nm 橙,700nm 红) 交互: - 波长滑杆 380~750 nm,默认 550 - 缝间距滑杆 0.10~1.00 mm,默认 0.30 - 屏距离滑杆 0.50~3.00 m,默认 1.50 - 每个滑杆旁边配一个数字输入框可以精确输入;输入为空、非数字或超出范围时,页面上要给出明确中文提示(说明合法范围),并且保留上一次的有效值继续显示,页面不能崩 - 「光点累积」模式:可以点「发射 1 颗光子」单发,也可以点「连发 300 颗」;每颗光子按 I(y) 归一化后的概率密度随机落在屏上,累积成点阵条纹;提供「清空」按钮把累积点清零 - 「挡住一条缝」开关:关掉其中一条缝后,波浪场只剩一个波源,光强曲线从等间距干涉条纹变成单缝衍射包络(中央最亮、两侧迅速衰减),用来对比「知道走了哪条缝,条纹就没了」;再打开恢复干涉条纹 - 右上角数值面板实时显示:当前波长对应颜色、条纹间距 deltaY(毫米)、中央到第 1/2/3 级亮纹的位置 y1/y2/y3(毫米)、以及当前参数下一条缝与另一条缝到屏中心的光程差 自检:放一个「运行自检」按钮,点下去跑 8 条数值断言并在页面上逐条显示通过/失败,最后显示「自检 8/8 通过」或列出失败条目。断言至少包含:I(0) 等于 I0;y = deltaY/2 处强度约等于 0;条纹间距与缝间距成反比;条纹间距与波长成正比;条纹间距与屏距离成正比;650nm 的条纹间距大于 450nm 的;屏中心永远是亮纹;光子累积直方图的峰位与理论 y_m 的相对误差小于 10%。 界面:深色、简洁、字号够大,画布随窗口自适应。完成后打开预览,让我直接看到运行效果。

码道 Web 交回的是单文件index.html,自己起了内置预览。下面的数字全部来自我在本机浏览器里对这个文件的重跑,不是转述它的总结。

它实际长成了什么样:三个滑杆各拖一遍,ΔY 跟着怎么动

面板上默认参数是 λ=550nm、d=0.30mm、L=1.50m,它算出的 ΔY=2.750mm、y₁/y₂/y₃=2.750/5.500/8.250mm,屏中心光程差 0.0000mm。为了看清 ΔY 到底由谁决定,我把三个滑杆分别扫了一遍,每次都只动一个变量:

固定变动ΔY 实测ΔY × 变量
d=0.30、L=1.50λ=450nm2.250 mmΔY/λ = 0.00500
d=0.30、L=1.50λ=550nm2.750 mmΔY/λ = 0.00500
d=0.30、L=1.50λ=650nm3.250 mmΔY/λ = 0.00500
λ=550、L=1.50d=0.10mm8.250 mmΔY·d = 0.825
λ=550、L=1.50d=0.30mm2.750 mmΔY·d = 0.825
λ=550、L=1.50d=0.45mm1.833 mmΔY·d = 0.825
λ=550、d=0.30L=1.00m1.833 mmΔY/L = 1.833
λ=550、d=0.30L=1.50m2.750 mmΔY/L = 1.833
λ=550、d=0.30L=3.00m5.500 mmΔY/L = 1.833

三列比值全是常数,说明页面里 ΔY 确实严格正比于 λ 和 L、反比于 d,没有掺进别的因子。波长那一档最直观:450nm 的蓝光条纹最密,650nm 的红光最疏,同一个屏幕上条纹宽度差出 44%(2.250 → 3.250)。

光子累积那部分是这篇的主角。连点 12 次「连发 300 颗」,累积到 3600 颗,屏幕上的点阵是这样的:

  • 点阵主峰落在2.649mm,理论 y₁=2.750mm,相对偏差3.7%;
  • 3600 颗里有1542 颗(42.8%)落在 |y| < 1.5ΔY 的范围内,也就是被压进了中央那几条亮纹里;
  • 页面自检用 16000 颗光子重跑同一项,峰位 2.605mm、相对误差 5.29%——样本更多时峰位抖动量级就在几个百分点,这是蒙特卡洛的噪声底线,不是公式不准。

把一条缝挡住,条纹就没了。打开「挡住一条缝(单缝模式)」开关后:波浪场只剩一个点源向外发散(另一条缝被标了红叉),屏上曲线从等间距的cos²换成单缝的sinc²包络——中央最高、往两侧迅速衰减,而且面板里 ΔY、y₁、y₂、y₃ 四格直接变成「—(单缝)」。

之所以会有这个对比:干涉条纹的前提是「不知道光子走的哪条缝」。两条缝都开着时,屏上每一点都是两条路径的叠加,相位差决定加减;一旦遮掉一条,只剩一条路径可走,就不存在「两条路径差多少」这件事,条纹自然消失。这也是量子力学里那句常被引用的话的直观版本。

踩坑与边界:四处真实的不一致

一、590nm 的颜色名字不是需求里说的「黄」。我在需求里点名了「590nm 黄」,但页面把色名分成了 7 档:紫(<430)、蓝(430479)、蓝绿(480514)、绿(515559)、黄绿(560589)、橙(590~629)、红(≥630)。整套档位里没有单独的「黄」,590nm 正好落在「橙」档。实测 590nm 与 620nm 都是「橙」,560/570/580nm 都是「黄绿」。它的 RGB 插值其实是按物理分段来的(590nm 给的是偏黄橙的 r=1、g≈0.85),所以问题只出在色名的分档阈值上,不是颜色算错了。这提醒我:需求里点名的锚点,最好连「分几档、档位边界在哪」一起写清楚。

二、「必须是数字」这条提示,实际操作中走不到。三个输入框都是<input type="number">。浏览器不允许把abc这类文本写进 number 输入框的 value——脚本里赋值后读回来已经是空字符串,所以页面永远命中「不能为空」那条分支,而不是「必须是数字」。我实测:给 d 填abc,提示是「缝间距 d不能为空,请输入 0.1 ~ 1 之间的数字(单位 mm)。已恢复上次有效值。」,和真的留空完全一样。三条校验分支写得很全,但其中一条被输入框类型挡在了更前面。

三、错误提示 5 秒后自动消失。showErr()里挂了一个 5 秒的setTimeout把提示清空,而输入框和滑杆已经立刻回退到旧值。所以填错之后如果没马上看,画面上只会看到「数值没变」,看不到任何解释——想核对提示原文得赶在 5 秒内,或者再填一次。这个是设计选择(提示不长期占位),但它让「页面给出明确提示」这件事变得有时效性。

四、切到单缝模式后,数值面板有几格变空。需求写的是「数值面板实时显示 ΔY 和 y₁/y₂/y₃」,而单缝模式下这四格显示的是「—(单缝)」。从物理上讲这是对的(单缝没有干涉条纹间距),但严格对照需求就是「有 4 格不再是数值」。

顺带一个没踩到的点:我本来担心「连发 300 颗」点太快会让累积超过上限,实测光子有硬上限 5000 颗,到了会提示「已达上限 5000 颗,请清空后再发射。」,不会越界也不会卡死。

自检 8/8,但自检不能当验收

点「运行自检」,8 条断言我本机重跑的原文(面板逐条列出)是:

自检 8/8 通过 ✅ ✓ 通过:I(0) 恒等于 I₀ 屏中心相对光强 = cos²(0) = 1 ✓ 通过:y = ΔY/2 处强度 ≈ 0 半条纹间距处相位差为 π,cos²(π/2)=0;I(1.375mm)=2.59e-32 ✓ 通过:条纹间距与缝间距成反比 ΔY·d 为常数:0.825000 = 0.825000 ✓ 通过:条纹间距与波长成正比 ΔY/λ 为常数:0.005000000 ≈ 0.005000000 ✓ 通过:条纹间距与屏距离成正比 ΔY/L 为常数:1.833333 = 1.833333 ✓ 通过:650nm 的条纹间距 > 450nm 的 ΔY(650nm)=3.2500mm > ΔY(450nm)=2.2500mm ✓ 通过:屏中心永远是亮纹 对多组参数 I(0)=1(含单缝模式) ✓ 通过:光子累积峰位与理论 y₁ 误差 < 10% 实测峰位 2.605mm,理论 ΔY=2.750mm,相对误差 5.29%

八条覆盖了「中心恒亮」「半间距处相消」「ΔY 与三个变量的比例关系」「颜色对应的单调性」「光子分布收敛」。但它验的是公式和采样的自洽性,不验画面:曲线画没画对、纹理对不对、单缝包络长得对不对,这些它一句都没查——图上那两种情况(图 2 的点阵聚束、图 3 的包络切换)是我自己一张张看出来的。

失败路径写得不错,但提示是短暂出现的,三种非法输入的实际提示原文如下:

输入提示原文
缝间距填2缝间距 d超出范围:2mm。合法范围:0.1 ~ 1 mm,已恢复上次有效值。
屏距离填0.2屏距离 L超出范围:0.2m。合法范围:0.5 ~ 3 m,已恢复上次有效值。
波长留空波长 λ不能为空,请输入 380 ~ 750 之间的数字(单位 nm)。已恢复上次有效值。

三种都回退了上一次的有效值(550/0.30/1.50),页面继续正常显示,没有白屏。

准备环境:进入码道 Web

浏览器打开码道 Web 版:https://devcloud.cn-north-4.huaweicloud.com/chat?source=dmzntgwsf&sourcead=dmzntgwwbwz,登录后就能在对话窗口输入需求,不需要装软件。

码道有三种使用方式:WebUI(浏览器对话)、TUI(终端命令行)和桌面 IDE(IDE 插件)。本文用 WebUI 版演示。

本地复现

生成物只有一个index.html,复现没有依赖:

  1. 从 Demo Park 本案例目录下载index.html。
  2. 双击打开。默认 λ=550nm、d=0.30mm、L=1.50m,上半屏立刻能看到两个波源叠出的射线状条纹。
  3. 想走静态服务也行:python -m http.server 8000,然后访问http://localhost:8000。
  4. 把窗口拉到一个较大的视口(我用的是 1920×1200),两块画布都会跟着窗口自适应重画。

下面这些数是我本地逐条跑出来的,都能自己复验:

  1. 画布:视口 1920×1200 时波浪场画布 1302×552、光强画布 1302×444,都随窗口宽度自适应。
  2. 默认参数:ΔY=2.750mm,y₁=2.750mm、y₂=5.500mm、y₃=8.250mm,屏中心光程差 0.0000mm。
  3. 三组扫描:ΔY/λ=0.00500(450/550/650nm)、ΔY·d=0.825(0.10/0.30/0.45mm)、ΔY/L=1.833(1.00/1.50/3.00m),各自都是常数。
  4. 光子累积:3600 颗时主峰 2.649mm(理论 2.750mm,偏差 3.7%),其中 42.8% 落在 |y|<1.5ΔY 内。
  5. 单缝模式:波浪场只剩一个波源,曲线换成 sinc² 包络,ΔY 与 y₁/y₂/y₃ 显示「—(单缝)」。
  6. 自检:点「运行自检」8/8 通过,每条都带实测数字。
  7. 非法输入:越界 / 空值都给出中文提示并回退旧值,不白屏。

使用码道体会

  • 把公式三件套都写进需求。我在需求里同时给了I(y)/I₀、ΔY、yₘ三个公式和各自的单位,它交回来的页面就有了「曲线 + 面板数字 + 自检断言」三层互相印证的东西。只写「做一个双缝干涉动画」,很可能只会得到好看的波纹,量不出 ΔY。
  • 要求它把关键中间量摆出来。「数值面板实时显示 ΔY 和 y₁/y₂/y₃」这一条回报最大:上面那张扫描表我一次都没用计算器——改一个滑杆、读一次面板,三次就够看出比例关系。
  • 物理量之间的比例关系,交给它做成断言。需求里的 8 条自检断言(反比、正比、单调、中心恒亮)不是随便写的,它把「公式对不对」变成了「点一下就能看的勾」,我才敢在文章里直接引用后续测量的数字。
  • 没写进需求的分档细节,它就自己定一套。颜色那条我只给了 6 个锚点(380 紫 / 450 蓝 / 520 绿 / 590 黄 / 620 橙 / 700 红),没有给分档边界,于是它把「黄绿」当一档、让 590nm 落进了「橙」。锚点写清楚,档位边界也得写清楚。
  • 验收要自己动手。自检 8/8 全绿,但它验的是公式自洽,没验画面;点阵有没有真的聚成条纹、单缝包络有没有真的切过去,都是我自己看图确认的。Agent 说完成不算验收。

亲手点三下

页面打开就能验,三下够了:

  1. 看条纹间距:把「波长 λ」滑杆从 380 慢慢推到 750,盯住面板里的 ΔY 和屏上的曲线。曲线会跟着疏密变化,ΔY 从 1.900mm 一路涨到 3.750mm;换成推「缝间距 d」,方向正好相反——d 越大条纹越密。
  2. 看条纹消失:把「挡住一条缝(单缝模式)」开关打开,上半屏的波浪场会从两个源变成一个源,下半屏的曲线从等间距条纹变成中间高两边低的包络,面板里 ΔY 那几格变成「—(单缝)」;再关掉开关,条纹原样回来。
  3. 看失败路径:在「缝间距 d」的数字框里填2回车,必须看到一行中文红字提示、输入框退回 0.30、页面不白屏;再把「波长 λ」清空回车,提示会换成「不能为空」那一条。

直接下载试玩

  • Demo Park 仓库:https://atomgit.com/deli007/demo_park
  • 本案例目录:https://atomgit.com/deli007/demo_park/tree/main/codearts-double-slit-lab

总结

把双缝干涉做成能拖的页面之后,最值得记住的不是那排条纹,而是「挡住一条缝」那一下:条纹之所以存在,靠的是两条路径的相位差——把其中一条断掉,屏上每一点就只剩一个来源,装不出来干涉。所以条纹不是光照出来的花纹,而是「同一个光子有两条路可走」的直接后果;ΔY = λL/d 只是这件事在几何上的刻度。想接着玩,可以试试把缝间距 d 拉到最小(0.10mm)看条纹宽到只剩一两条、把 L 推到 3m 看条纹被拉得多开,或者在单缝模式下把波长换成 380nm,看单缝包络的中心亮斑是怎么收窄的。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/30 13:57:20

9435应用电路图深度解析:芯片应用设计与质量管控实战

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/30 13:53:59

AI算法落地实战:从模型训练到边缘部署的全链路工程指南

简介&#xff1a;本资源是2024年第六届全球校园人工智能算法精英大赛的官方赛题解析与参与指南&#xff0c;面向高校学生、AI方向教师及算法竞赛爱好者&#xff0c;旨在系统解决备赛过程中对赛题理解不清、解题路径不明、评价标准模糊等核心问题。内容覆盖AI生成人脸图像鉴别、…

作者头像 李华
网站建设 2026/9/30 13:53:22

提示词模板管理与Agent编排实战:从散乱到工程化

1. 项目概述与核心需求解析我写这个系列到第七篇的时候&#xff0c;后台收到最多的留言其实不是“怎么写提示词”&#xff0c;而是“提示词越来越多&#xff0c;项目越来越乱&#xff0c;改一个需求要连带改十几个地方&#xff0c;AI 的表现还不稳定”。这个问题非常真实&#…

作者头像 李华
网站建设 2026/9/30 13:53:19

ComfyUI与PS互补:AI商业出图工作流实战拆解

最近帮朋友做了一套电商产品海报的AI出图流程&#xff0c;从需求沟通到交付大概用了三天。整套东西不算复杂&#xff0c;但真正跑通之后才发现&#xff0c;ComfyUI和Photoshop并不是竞争关系&#xff0c;而是前后工序的互补关系。这次我就把工作中实际落地的那套东西完整拆开聊…

作者头像 李华
网站建设 2026/9/30 13:53:17

YOLO11cls实战:水稻叶病虫害15000张图像分类训练全流程

简介&#xff1a;面向水稻叶病虫害识别与图像分类项目的完整数据集资源&#xff0c;适合计算机视觉学习者、农业智能化开发者及算法训练人员使用。内容包含15000张真实场景高质量水稻叶片图像&#xff0c;按细菌性叶枯病、褐斑病、健康叶片、叶瘟病、叶鞘腐病、窄褐斑病、穗颈瘟…

作者头像 李华