尧图网络 高端网站定制 · 原创设计
免费咨询热线
400-888-6620
免费获取方案
MATLAB光学衍射模拟:衍射积分与傅立叶变换实现灰度图
简介这份资源面向光学、物理及光电专业的学生与教师以及需要开展衍射实验仿真验证的科研人员提供用MATLAB编程模拟光学衍射的完整文档。内容围绕衍射积分与傅立叶变换两条主线展开前者通过计算接收屏光强分布模拟单缝衍射、杨氏双缝干涉与黑白光栅衍射后者借助fft2、fftshift等函数对屏函数做功率谱分析复现圆孔、矩孔、三角孔、单缝、黑白光栅及正弦光栅的夫琅和费衍射图样并附有可直接运行的代码与光强分布图。资源包为1个doc文档约247KB结构紧凑便于按章节查阅与复现。目前已有791人学习适合作为课程实验、仿真作业或自学衍射原理的参考材料帮助读者在编程实践中直观理解干涉条纹受衍射因子调制及缺级等现象。1. 光学衍射 MATLAB 模拟从物理公式到灰度图的完整实现路径如果你正在做光学课程设计或者需要快速验证一个孔径的夫琅和费衍射图样长什么样又不想真的去搭光路、调激光器、买光栅那这份 MATLAB 光学衍射模拟资源就是为你准备的。它用两种完全不同的思路——衍射积分和傅立叶变换——把单缝衍射、杨氏双缝干涉、黑白光栅衍射、圆孔/矩孔/三角孔衍射以及正弦光栅衍射全部跑通最终输出灰度图和光强分布曲线。代码量不大但覆盖了从近场到远场、从一维到二维的典型场景。我第一次拿到这份代码时最直观的感受是原来课本上那些“光强分布公式”真的可以几行矩阵运算就变成屏幕上的条纹。它适合光学、物理、电子信息类专业的本科生做仿真作业也适合想用 MATLAB 快速验证衍射规律的工程师。2. 两种模拟路线衍射积分与傅立叶变换的架构拆解2.1 衍射积分方法把孔径拆成相干点源叠加衍射积分方法的核心思想很朴素把单缝或光栅看成由许多个分立相干点光源组成接收屏上任意一点的光场是所有这些点源在该点产生复振幅的叠加。对于单缝代码把缝宽a分成np51个点每个点对应一个相位alpha2*pi*yp*sinphi/lam然后分别累加余弦和正弦分量最后取模平方得到光强。这种“离散化求和”的做法本质上就是基尔霍夫衍射公式的数值近似。% 单缝衍射衍射积分法 clear lam 500e-9; % 波长 500nm a 1e-3; % 缝宽 1mm D 1; % 接收屏距离 1m ym 3*lam*D/a; % 观察屏范围取到第三级暗纹附近 ny 51; % 屏上采样点数 ys linspace(-ym, ym, ny); np 51; % 缝内分立的相干光源数 yp linspace(0, a, np); for i 1:ny sinphi ys(i)/D; % 近似小角度 alpha 2*pi*yp*sinphi/lam; % 各点源相位 sumcos sum(cos(alpha)); sumsin sum(sin(alpha)); B(i,:) (sumcos^2 sumsin^2)/np^2; % 归一化光强 end N 255; Br (B/max(B))*N; % 映射到 0~255 灰度 subplot(1,2,1) image(ym, ys, Br); % 左图灰度条纹 colormap(gray(N)); subplot(1,2,2) plot(B, ys); % 右图光强随位置变化曲线这段代码里lam、a、D是三个最关键的物理参数。改a会直接改变衍射条纹的宽度——缝越窄衍射越明显改D则影响观察屏上的尺度。np控制离散精度一般取 51 到 101 之间就足够平滑再大对结果改善有限但计算量线性增长。ym的取值决定了你看到几级条纹取3*lam*D/a大约能看到中央主极大和两侧第一、第二级暗纹。杨氏双缝干涉的代码思路类似但不再对缝内积分而是直接计算两个缝到屏上某点的光程差用phi2*pi*(r2-r1)/lam得到相位差光强按4*cos(phi/2)^2分布。这里有个容易忽略的点双缝代码里B(i,:)sum(4*cos(phi/2).^2)其实是对单点求值sum在这里没有实际聚合作用但结果正确。黑白光栅衍射则引入了多缝干涉因子(sin(N*beta)/sin(beta))^2和单缝衍射因子(sin(alpha)/alpha)^2的乘积能清晰看到缺级现象——当衍射因子为零时干涉主极大消失。2.2 傅立叶变换方法屏函数的功率谱就是衍射场傅立叶变换方法走的是另一条路夫琅和费衍射场的复振幅分布正比于衍射屏透射率函数的傅立叶变换。MATLAB 的fft2可以直接对图像矩阵做二维离散傅立叶变换取模后得到振幅谱再用fftshift把零频分量移到中心最后imshow显示。这条路线的好处是你不需要推导任何衍射积分公式只要把孔径形状画成黑白图像读进来做 FFT 就行。% 傅立叶变换法读取孔径图像计算衍射图样 clear a imread(aperture.bmp); % 黑白孔径图白色透光、黑色挡光 figure(1) imshow(a, []) % 显示原始孔径 afft fft2(a); % 二维离散傅立叶变换 aabs abs(afft); % 取模得到振幅谱 aabss fftshift(aabs); % 零频移到中心 figure(2) imshow(aabss, []) % 显示衍射图样 colormap(gray); colorbar figure(3) plot(aabss) % 一维剖面 colormap(gray); figure(4) meshc(aabss) % 三维网格观察强度分布这里的关键操作是fftshift。不做这一步零频分量在矩阵四角显示的频谱是“分裂”的看起来不直观。abs取模得到的是振幅谱如果想看光强分布应该取模的平方。imread读入的图像可以是自己用画图工具生成的黑白 BMP也可以用代码动态生成——比如正弦光栅那段就是用cos(xs)1生成灰度渐变条纹再保存成 BMP 的。两种方法各有适用场景衍射积分法物理意义明确适合理解公式和参数影响傅立叶变换法通用性强任意形状孔径只要画出黑白图就能算适合快速探索复杂孔径的衍射花样。3. 从零跑通环境配置、参数调优与结果验证3.1 环境准备与文件组织这份代码对 MATLAB 版本要求不高R2015a 之后的版本都能跑。不需要额外工具箱fft2、fftshift、imread、imshow都是基础函数。我一般会把不同实验的脚本分开存成独立.m文件比如single_slit.m、double_slit.m、grating.m、fft_diffraction.m避免变量互相污染。傅立叶变换法需要一个孔径图像文件建议放在脚本同目录下用相对路径读取这样换电脑不用改路径。% 生成正弦光栅图像并保存供傅立叶变换法使用 clear all xm 10*pi; ys xm; xs linspace(-xm, xm, 500); B cos(xs) 1; % 正弦透过率范围 0~2 N 255; Br B/2*N; % 归一化到 0~255 image(xs, ys, Br); colormap(gray(N)); imwrite(uint8(Br), sine_grating.bmp); % 保存为灰度 BMP这段代码生成的正弦光栅其傅立叶变换理论上只有三个衍射斑零级和正负一级跑出来如果看到更多级次说明图像量化或边界处理引入了高频分量。保存时用uint8转换避免imwrite对 double 类型做额外缩放。3.2 参数调优改什么、看什么衍射积分法的三个核心参数是波长lam、特征尺寸a缝宽或光栅常数、接收距离D。它们共同决定衍射角sinphi ≈ lam/a。如果你想看到更宽的衍射条纹把a减小一个数量级想看到更密集的干涉条纹把光栅常数d增大。黑白光栅代码里N2表示只取两个缝改成N10就能看到多缝干涉的细锐主极大。傅立叶变换法里衍射图样的尺度由孔径图像的像素尺寸和物理尺寸的对应关系决定。如果你用 500×500 像素表示 1cm×1cm 的孔径那频谱中心到第一暗环的像素距离就对应衍射角。实际做的时候我习惯先用小尺寸图像比如 128×128快速验证确认无误后再换成高分辨率图。提示fft2的输出默认零频在左上角一定要fftshift后再显示否则你会看到四个对称的“角”容易误判为高阶衍射。3.3 结果验证和理论值对一对单缝衍射第一暗纹位置理论值y lam*D/a。用lam500e-9、a1e-3、D1算出来是 0.5mm。跑完代码后在光强曲线上找第一个零点应该就在 0.5mm 附近。杨氏双缝干涉条纹间距理论值Δy lam*D/a这里a是双缝间距。黑白光栅的缺级条件d/a k/n比如d5a时第 5、10、15 级主极大缺失。这些验证点能帮你确认代码没有量纲错误或索引错位。傅立叶变换法的验证更直接圆孔衍射应该得到艾里斑中心亮斑加同心暗环矩孔衍射得到十字形亮纹三角孔衍射得到六角对称花样。如果跑出来不对称检查孔径图像是否居中、是否有非零边界。4. 避坑与排查衍射模拟中容易翻车的五个细节4.1 现象光强曲线出现负值或 NaN原因sin(alpha)./alpha在alpha0时产生0/0。虽然 MATLAB 对sin(0)/0返回NaN但实际极限是 1。光栅衍射代码里alpha和beta都可能为零。解决在计算前加一个极小量eps或者用逻辑索引单独处理零点。我一般写成alpha alpha (alpha0)*eps;这样既不影响非零值又避免 NaN。4.2 现象傅立叶变换法得到的衍射图样一片白或一片黑原因imshow(aabss, [])里的[]会自动缩放显示范围但如果图像本身动态范围极大零频分量比高频高好几个数量级高频细节会被压扁。另外如果读入的图像是 RGB 三通道fft2会对三个通道分别变换结果维度不对。解决读入后先rgb2gray转灰度再用log(1aabss)做对数压缩显示这样高频和低频都能看清。或者手动设置显示范围imshow(aabss, [0, max(aabss(:))/100])。4.3 现象衍射积分法跑出来的条纹不对称原因linspace(0, a, np)从 0 开始而不是从-a/2开始导致点源分布整体偏移了半个缝宽。对于单缝这只会引入一个整体相位因子不影响光强但对于双缝或多缝如果两个缝的采样起点不一致干涉条纹会偏移。解决把缝内采样改成linspace(-a/2, a/2, np)保证对称。双缝代码里直接用解析光程差公式不存在这个问题。4.4 现象fftshift之后图像中心不在正中间原因当图像尺寸为奇数时fftshift的零频位置在(N1)/2而不是N/21视觉上会偏一格。这是离散傅立叶变换的固有特性不是 bug。解决如果对中心位置敏感把图像尺寸补零到偶数。或者接受这一格偏移在后续分析时用ceil(size/2)定位中心。4.5 现象正弦光栅衍射出现多余级次原因生成正弦光栅时用了cos(xs)1但xs的范围是-10*pi到10*pi两端不连续相当于给正弦波加了矩形窗。矩形窗的傅立叶变换是 sinc 函数会引入额外高频。解决把范围取成2*pi的整数倍并且首尾值相等。或者用hann窗做渐变过渡。我一般直接取xs linspace(-10*pi, 10*pi, 500)然后检查首尾是否接近不接近就微调点数。5. 二次开发从固定孔径到参数化批量仿真5.1 把脚本改造成函数支持批量参数扫描原始代码都是脚本变量直接写在开头。如果你想研究“缝宽从 0.1mm 到 2mm 变化时衍射条纹如何演化”手动改参数再跑几十次太慢。我一般会把核心计算封装成函数输入物理参数输出光强分布矩阵。function [B, ys] single_slit_intensity(lam, a, D, ny, np) % 单缝衍射光强分布衍射积分法 % lam: 波长(m), a: 缝宽(m), D: 接收距离(m) % ny: 屏上采样点数, np: 缝内点源数 % 返回 B: 光强分布(ny×1), ys: 屏上坐标 ym 3*lam*D/a; ys linspace(-ym, ym, ny); yp linspace(-a/2, a/2, np); % 对称采样 B zeros(ny, 1); for i 1:ny sinphi ys(i)/D; alpha 2*pi*yp*sinphi/lam; sumcos sum(cos(alpha)); sumsin sum(sin(alpha)); B(i) (sumcos^2 sumsin^2)/np^2; end end封装之后批量扫描就变成两层循环外层遍历a内层调用函数把结果存到元胞数组或三维矩阵里。用imagesc把不同a对应的条纹拼成一张图能直观看到衍射角随缝宽减小而增大的趋势。5.2 用 App Designer 做一个交互式衍射模拟器如果你需要给不熟悉 MATLAB 的人演示可以拖几个滑块控件波长、缝宽、屏距离实时刷新衍射图样。核心回调函数就是上面那个single_slit_intensity把滑块的值传进去算完用imagesc或plot更新坐标轴。傅立叶变换法那边可以做一个“画孔径”的面板让用户用鼠标画任意形状然后实时 FFT 显示衍射花样。这个改造的工作量主要在界面布局计算部分几乎不用动。5.3 扩展到二维任意孔径从图像到衍射的通用流程傅立叶变换法最大的优势是通用性。你不需要为每种孔径推导公式只要生成对应的黑白图像。我常用的流程是先用poly2mask或insertShape生成孔径掩膜再做fft2。比如要模拟三角形孔用poly2mask指定三个顶点坐标要模拟字母“A”的衍射直接读入文字图像二值化。唯一需要注意的是图像尺寸要足够大避免边界截断引入伪影。一般取 1024×1024 或 2048×2048计算量在现代笔记本上完全可接受。5.4 一个我踩过的坑归一化方式影响对比度早期我做傅立叶变换衍射时直接imshow(abs(fft2(a)), [])结果图样对比度很低暗纹几乎看不见。后来发现是因为零频分量太大自动缩放把高频压没了。改成log(1abs(fft2(a)))再显示细节立刻清晰。另一个坑是fft2不做归一化不同尺寸图像的频谱幅度不可比。如果要做定量分析记得除以numel(a)。从那以后我每次做傅立叶变换衍射都强制走一遍“转灰度 → 补零到偶数尺寸 → fft2 → fftshift → log 压缩 → 显示”的流程再也没出现过一片白或一片黑的情况。希望这些经验能帮到你少走几个弯路。本文还有配套的精品资源点击获取
RELATED

相关推荐

Windows Server 2022 上搭建 IIS 与 DNS 的完整指南

Windows Server 2022 上搭建 IIS 与 DNS 的完整指南

简介:这份文档面向IT运维人员与Windows服务器初学者,系统讲解Windows Server 2022环境下Web服务器的搭建与配置流程,帮助读者从零完成服务器安装到网站对外访问的完整实践。内容涵盖操作系统安装、服务器功能测试、网站目录创建与素材拷贝、端…

📅 2026/10/24 19:38:31
dbc2000 64位服务端架设实战:从启动失败到稳定运行

dbc2000 64位服务端架设实战:从启动失败到稳定运行

简介:这份资源是DBC2000数据库管理系统的64位版本,面向需要在Windows 7、8或10 64位系统上架设“单击传奇”类游戏服务器的用户,尤其适合中文环境下的新手与进阶玩家。DBC2000专为Mud2U引擎设计,可用于创建、编辑和管理游戏数据库…

📅 2026/10/24 19:38:31
ESXi 7.0.0 安装硬约束与UEFI/驱动兼容性实战指南

ESXi 7.0.0 安装硬约束与UEFI/驱动兼容性实战指南

简介:本资源为VMware ESXi 7.0.0官方离线安装包(Build 15843807),面向虚拟化工程师、IT运维人员及私有云部署实践者,专为解决无外网环境或PowerCLI模块安装失败场景下的系统部署难题——如用户反馈的‘Install-Module …

📅 2026/10/24 19:33:28
MORE NEWS

更多资讯

📰

qgeval:轻量级文本生成评估工具包,支持BLEU/METEOR/ROUGE三指标统一计算

简介:qgeval是一个专为自然语言处理研究者与开发者设计的Python评估工具包,聚焦于机器翻译、文本生成等任务的自动化质量评测,支持Bleu、METEOR和ROUGE三大主流指标的一键计算,显著降低模型输出评估门槛。资源包共26个文件&#x…

📰

自动控制原理实验全攻略:从传递函数到Simulink仿真与稳定性分析

简介:这份文档面向具备基础控制理论与编程能力的高年级本科生、研究生及工程技术人员,围绕自动控制原理实验教学,系统讲解控制系统的建模、分析与校正方法。内容涵盖六个实验:控制系统数学模型的MWORKS与MATLAB实现、时域与频域分…

📰

基于理查逊直线法的金属逸出功测量实验:原理、实现与误差分析

简介:这份资源是华南理工大学国际校区物理实验报告的金属逸出功实验文档,面向正在修读大学物理实验课程、需要完成实验报告或准备相关考核的理工科学生。内容围绕电子逸出功这一金属材料基本属性展开,涉及查逊直线法测定金属钨逸出功、费米-狄…

📰

Java课程设计实战:基于Swing+MyBatis+MySQL的ATM柜员机模拟系统

简介:一份适合Java课程设计参考的ATM柜员机模拟系统项目报告,面向正在完成Java课程设计、或希望系统练习面向对象编程与Java Swing界面开发的学生。报告围绕用户登录、账户查询、存款、取款、修改密码等核心功能,从需求分析、功能图、界面设计…

📰

舒尔特表格:科学提升注意力的视觉训练工具

简介:本资源是一份专用于注意力训练的舒尔特表格练习文档,面向学生、职场人士、儿童教育者及需提升专注力的各类学习者,有效解决日常学习效率低、注意力易分散、视觉搜索慢等认知问题。文档内含5种规格(55至1010)的标准…

📰

UrsAI2Paho+AI2:MQTT扩展包配置与避坑全攻略

简介:面向App Inventor开发者和物联网初学者,这份UrsAI2Paho扩展包是基于Eclipse Paho的MQTT插件,可将Android应用快速接入MQTT服务器,实现设备间消息的发布与订阅。包内共139个文件,以Java源码、properties配置、aia示…

TODAY

今日更新

THIS WEEK

本周精选

THIS MONTH

本月热门

读完文章,想聊聊您的网站?

告诉我们您的行业与需求,资深顾问一对一梳理方案与报价,全程免费。

📞 💬