☰
单透镜焦距偏差与六层膜设计:应用光学实验的Zemax/TFCalc解析
2026/10/28 2:07:52 网站建设 项目流程

简介:这份应用光学上机实验报告面向高校光学、光电信息类课程学生及自学者,围绕Zemax透镜设计与tfcalc光学薄膜分析两项上机任务,提供可对照复现的实验记录与结果整理。文档完整呈现F/4、焦距100mm、BK7玻璃透镜的波长与孔径设置、曲率半径和厚度调整、简单优化过程,并保留光线特性曲线、OPD图、点列图和焦点漂移图等关键图表,便于理解像质评价与离焦纠正思路;薄膜部分记录六层SiO2/TiO2膜系在400—700nm高透射、700—1200nm偏反射的分析结果,可帮助读者熟悉膜层材料与层数设置。压缩包共1个doc文件,约695KB,篇幅紧凑,适合作为实验预习、报告撰写、软件操作排错及结果复核的参考。已有596人学习,读者可据此梳理Zemax与tfcalc的基本流程、参数设置逻辑和图表判读方法,并借鉴实验报告的组织方式。

1. 标称 100mm 的 F/4 单透镜,为什么软件报出来的焦距只有 97.4mm

应用光学的上机实验里,第一个反直觉的地方往往出现在这里:按步骤在表面表里填上 R1=+100、R2=−100、中心厚 4mm、材料 BK7,再把像面距离填成 100mm,系统给出的有效焦距并不是 100mm,而是 97.41mm,后截距 96.08mm。于是第一次生成的光线特性曲线不是教科书上那种漂亮的 S 形,而是一条笔直的斜线。这条斜线不是像差,是离焦,是“你以为像面在焦点上、实际差了将近 4mm”的直观投影。搞懂这条斜线从哪来,就等于搞懂了表面表里每个数字到底在参与什么运算——这也正是这套实验报告最值得反复看的地方。

2. 表面表:F/4、三条谱线和正负号是怎么变成一组数字的

光学设计软件的表面表看起来像个 Excel,填进去的是曲率半径、厚度、玻璃牌号、半口径,但每一列背后都对应着一个明确的物理量,而且这些量之间是互相咬合的。改一个,另外几个的物理含义就跟着变。实验里那几步“输入波长、定义孔径、加第四个面、填 BK7、填 4mm、填 ±100”,单看是操作步骤,连起来其实是在构造一个近轴模型,后面所有的曲线都是从这个模型里推出来的。

2.1 F/4 与 25mm 入瞳:一个比值同时锁死了口径和光斑

F 数的定义是有效焦距除以入瞳直径,也就是 F/# = EFL / EPD。设计要求是 F/4、f=100mm,所以入瞳直径取 25mm。这一步没有讨价还价的余地,因为它是定义式的。但坑在于:当你把 R=±100 填进去之后,系统的实际 EFL 变成 97.41mm,而入瞳仍然是 25mm,于是真实工作 F 数是 97.41/25 ≈ 3.90,不是 4.00。

这个 2.5% 的偏差不是小数点后的噪音,它会直接改变你对后面所有图的判读。艾里斑半径的公式是 1.22λ·F/#,按 F/4 算出来是 1.22 × 0.587 × 4 ≈ 2.86μm;按 F/3.9 算是 2.79μm。更重要的是,球差、离焦敏感度、焦深这些量全都跟 F 数的幂次挂钩,纵向球差大致按 F/#² 缩放,横向弥散按 F/#³ 缩放。也就是说,你在优化过程中只要焦距一动,评价函数里那些跟光斑大小相关的项就会集体漂移,看起来像是“优化把系统搞坏了”,实际上是 F 数偷偷变了。

提示:判断一个镜头是不是真的工作在目标 F 数上,不要看设计目标,要看系统报告里的有效焦距除以入瞳直径,或者直接看近轴边缘光线在像面的高度。

2.2 486/587/656:三条谱线的来历与阿贝数

实验里输入的三个波长 486、587、656,对应的是氢的 F 线 486.13nm、氦的 d 线 587.56nm、氢的 C 线 656.27nm。这三条线不是随便挑的,它们是可见光谱里被标准化了几十年的特征谱线,折射率手册、玻璃目录、阿贝数定义全都围着它们转。权重都设成 1.0,意思是这三条线在评价函数里地位平等,没有谁被特殊照顾。

谱线波长 (nm)BK7 折射率用途
F486.13约 1.5224蓝端,色差短波极限
d587.56约 1.5168主波长,焦距与阿贝数的基准
C656.27约 1.5143红端,色差长波极限

阿贝数的定义是 Vd = (nd − 1) / (nF − nC)。代进上表的数据,Vd ≈ 0.5168 / 0.0081 ≈ 63.8,跟 BK7 标称的 64 左右对得上。这个数字马上就能换算成一个很实用的量:色焦移 Δf ≈ f / Vd ≈ 97.41 / 63.9 ≈ 1.5mm。也就是说,蓝光焦点和红光焦点在轴上差了大约 1.5mm,这个量级跟单透镜本身的球差是同一档次。

这一点特别值得停下来想一想。很多人做这个实验时,把“多色光焦点漂移图”当成一张走过场的插图,实际上它揭示的是:在 f/4 这个相对孔径下,单透镜的色差和球差谁也没法忽略,你不能先校色差再校球差,因为它们都藏在同一条光线特性曲线里。三条波长权重全设 1.0,意味着优化器会在这三个焦点之间找一个折中位置,而不是对准任意一条线。

2.3 曲率半径的符号:一个负号决定透镜是凸还是凹

表面表的曲率半径一列带符号,约定是:曲率中心在顶点右侧为正,左侧为负。这个约定听起来是形式主义,实际上决定了整个系统的性质。第一面 R=+100,光焦度 φ1 = (n₂ − n₁)/R = (1.5168 − 1)/100 = +0.005168;第二面 R=−100,光焦度 φ2 = (1 − 1.5168)/(−100) = +0.005168。两个面都是正光焦度,合起来才是会聚透镜。

如果把第二面填成 +100,情况立刻变了:φ2 = (1 − 1.5168)/100 = −0.005168,第一面是会聚、第二面是发散,整体变成一个弯月形透镜,光焦度大幅下降,焦距被拉长,同时球差贡献的方向也反了过来。曲线上看到的现象是:点列图散得更大,而且离焦修正后残余的三次项形状跟双凸时不一样。符号错一个,后面所有分析都白做。

2.4 厚透镜不是薄透镜:EFL 与 BFL 差在哪

薄透镜公式 1/f = (n−1)(1/R₁ − 1/R₂) 是每个学应用光学的人最先记住的式子。代进 n=1.5168、R₁=100、R₂=−100,算出来 f ≈ 96.75mm。但软件报的是 97.41mm,两者差了 0.66mm。这个差异来自中心厚度 4mm——公式里根本没有厚度这个变量。

要算准,得用近轴矩阵。下面这段代码做的就是这件事,把每个面的折射和面间的传播写成 2×2 矩阵,乘起来之后从矩阵元素直接读出焦距和后截距。

# 近轴光线追迹:用 2x2 矩阵算厚透镜的有效焦距(EFL)与后截距(BFL) # 光线矢量取 [y, n*u]:y 为高度,n*u 为约化孔径角 def surface(R, n1, n2): """球面折射矩阵。光焦度 phi = (n2 - n1) / R,R 带符号""" phi = (n2 - n1) / R return [[1.0, 0.0], [-phi, 1.0]] def transfer(t, n): """平移矩阵。t 为沿轴距离,n 为所在介质折射率""" return [[1.0, t / n], [0.0, 1.0]] def mul(A, B): return [[A[0][0]*B[0][0] + A[0][1]*B[1][0], A[0][0]*B[0][1] + A[0][1]*B[1][1]], [A[1][0]*B[0][0] + A[1][1]*B[1][0], A[1][0]*B[0][1] + A[1][1]*B[1][1]]] n_glass, R1, R2, t = 1.5168, 100.0, -100.0, 4.0 S1 = surface(R1, 1.0, n_glass) # 空气 -> 玻璃 T = transfer(t, n_glass) # 玻璃内部走 4mm S2 = surface(R2, n_glass, 1.0) # 玻璃 -> 空气 M = mul(S2, mul(T, S1)) # 系统矩阵 [[A,B],[C,D]] A, C = M[0][0], M[1][0] efl = -1.0 / C # 有效焦距 bfl = -A / C # 后截距:第二面顶点到焦点 print(f"EFL = {efl:.2f} mm, BFL = {bfl:.2f} mm") # 输出:EFL = 97.41 mm, BFL = 96.08 mm

代码里的关键点是C这个元素,它就是整个系统的负光焦度,EFL = −1/C。而 BFL = −A/C 给出的是从最后一个面顶点量起的距离,不是从主平面量起的。两者差的那 1.33mm,就是主平面往像方偏移的距离。

由此引出一个很实际的问题:像面距离该填多少?实验步骤里填的是 100,而真实的 BFL 是 96.08。填 100 意味着人为引入了约 3.9mm 的离焦。这正好解释了报告里“图一”和“图二(纠正离焦后)”为什么是两张图——第一张是带着离焦跑出来的,第二张是把像面挪到焦点附近之后的。

3. Ray Fan、点列图、OPD:同一份光线数据的三种投影

把像面调好之后,剩下的图才开始说真话。光线特性曲线、点列图、光程差曲线,这三张图经常被当成三个独立的检查项,实际上它们是同一批光线追迹数据的不同投影方式:一个横着看,一个竖着看,一个积分看。理解了这层关系,看图就不再靠猜。

3.1 斜率是离焦,S 形是球差

光线特性曲线的横轴是归一化光瞳坐标 ρ(从 0 到 1),纵轴是光线在像面上的横向偏差 ε,单位微米。它之所以长成那个样子,是因为横向像差可以展开成 ρ 的幂级数:

ε(ρ) = a·ρ + b·ρ³ + c·ρ⁵ + …

一次项 a·ρ 对应的就是离焦。当像面偏离焦点 Δz 时,边缘光线(ρ=1)的横向偏差约等于 Δz 乘以边缘光线的孔径角,而近轴光线(ρ→0)几乎不偏,于是整条曲线被拉成一条斜线,斜率的正负由离焦方向决定。这就是为什么第一次跑出来的图是一条直线:a 很大,b 相对小,肉眼看上去就是纯线性。

三次项 b·ρ³ 对应的是三级球差。球差的特点是它跟光瞳高度的三次方成正比,所以两侧对称、中间平坦、边缘翘起,形状像字母 S。当离焦被消掉(a≈0)之后,剩下的就是这条三次曲线。报告里“纠正离焦后”的那张图,曲线由斜线变成 S 形,本质上是把一次项归零、让三次项暴露出来。

提示:看光线特性曲线时先看两端,再看中间。两端翘起说明球差占主导,两端反向偏离说明离焦没校好,两端不对称则可能是视场或偏心引入的彗差。

3.2 点列图:把一个波长的所有光线落点摊开

点列图是另一种投影:把光瞳面上均匀分布的几百上千条光线逐条追迹到像面,把落点画成散点,然后统计 RMS 半径和几何半径。它比光线特性曲线更直观,但也更容易被误读。

统计量的差别很关键。GEO 半径是包围所有光线的圆半径,它由最差的那几条边缘光线决定,对个别离群点极其敏感;RMS 半径是均方根,反映的是整体能量集中度。优化器默认优化的是 RMS 类指标,所以经常出现“RMS 降下来了,GEO 还是很大”的情况——能量更集中了,但最外圈那几条光线还是飞在外面。

把 RMS 光斑跟艾里斑放在一起比,才知道系统还有没有救。前面算过,F/3.9 下的艾里斑半径约 2.8μm。一个 f/4 的 BK7 单透镜,球差没校正时 RMS 半径通常在几十微米这个量级,比艾里斑大一个数量级。这个对比说明的事情很明确:单透镜在这个相对孔径下根本不是衍射受限系统,它是像差受限的,再怎么调参数也不可能把光斑压到艾里斑尺度。

3.3 OPD:光线特性曲线的积分形态

光程差曲线画的是波前误差 W(ρ),单位是波长。它跟光线特性曲线是微积分关系:横向像差正比于波前误差对光瞳坐标的导数,ε ∝ −dW/dρ。

所以如果横向像差是三次曲线 b·ρ³,那么波前误差就是四次曲线 (b/4)·ρ⁴;如果离焦项还在,波前里还有一个二次项 W₀₂₀·ρ²。这解释了为什么 OPD 图看起来像个碗或者 W 形,而光线特性曲线是 S 形。同一个像差,在两张图上表现完全不同,但指向的是同一件事。

这也解释了一个实用技巧:当光线特性曲线看不出名堂时,去看 OPD。因为波前误差是标量叠加,不同来源的像差可以直接加减;而横向像差是导数,混在一起时不好拆。

3.4 优化的机制:评价函数到底在最小化什么

优化这一步,软件做的事比“自动帮你调好”要朴素得多。它把评价函数 Φ(x) 定义成一大堆误差项(各视场、各波长、各光瞳位置的光斑或波前误差)的加权平方和,然后用阻尼最小二乘法沿着梯度方向一步步挪动变量,直到 Φ 不再明显下降。

默认评价函数通常选 RMS 光斑半径或 RMS 波前误差。这两个选择在接近衍射极限时结果接近,但在像差很大时差别明显:RMS 光斑是几何量,对大的几何像差更敏感;RMS 波前是物理量,对相位更敏感。一个 f/4 单透镜的初始状态离衍射极限很远,用 RMS 光斑更合适。

变量的选择是这门手艺真正的分水岭。曲率半径当然是变量,因为它直接决定光焦度;厚度也应该是变量,因为后截距决定了像面位置,而离焦项在评价函数里权重极高,不放开厚度优化器就只能靠改曲率去凑焦,把好好的透镜形状改歪。

3.5 边界约束:优化器不会替你考虑镜片能不能加工

这里有个必须建立的认知:优化器只认数学,不认物理。如果只把曲率半径和厚度设成变量,不做任何约束,它会给你一组评价函数极低但根本造不出来的解——边缘厚度为负、两个面相交、镜片中心比边缘还薄。

常见的做法是加边界操作数:约束中心厚度和边缘厚度的上下限,约束焦距在目标值附近,必要时约束放大率或后截距。约束加得越多,可行域越小,评价函数的最终值越差,但解越可用。这是设计里最典型的一组取舍:你不可能既要无约束的数学最优,又要可加工的结构。

从优化结果看,单透镜即便把所有自由度都放开,最终也只能把球差压到某个下限。这个下限不是参数没调好,是结构决定的——球差是单透镜的固有属性,想突破只能换结构,比如双胶合或者加非球面。

4. TFCalc 的六层膜:四分之一波长堆凭什么这边透那边反

第二个任务换了个完全不同的物理机制。透镜靠折射逐步改变波前,薄膜靠的是每层界面上的分振幅干涉。软件里“设置层数、设置材料、跑出曲线”三步看起来比 Zemax 还简单,但如果不清楚每层膜在干什么,就只能对着曲线看图说话,改一个参数结果往哪个方向走全靠试。

4.1 特征矩阵:一层膜就是一个 2×2 复数矩阵

单层薄膜对光的作​​用,可以写成一个特征矩阵:

M = [[cos δ, (i/η)·sin δ], [i·η·sin δ, cos δ]]

其中 δ = 2π·n·d·cosθ/λ 是相位厚度,η 是有效导纳(s 偏振取 n·cosθ,p 偏振取 n/cosθ)。整个膜系的矩阵是各层矩阵按顺序相乘,然后由膜系总导纳算出反射率和透射率。

这个形式之所以好用,是因为它把“无限多次界面反射的叠加”压缩成了一次矩阵乘法。物理上,光在每一层界面都会分出一部分反射、一部分透射,这些分量在膜层内部来回反弹、互相干涉,理论上要写成无穷级数;矩阵法把这无穷级数求和的结果直接编码进了两个 2×2 矩阵的乘积里。这就是为什么层数加到几十层,计算量还是线性增长。

当 δ = π/2,也就是该层的光学厚度 n·d 正好等于 λ₀/4 时,cos δ = 0、sin δ = 1,矩阵退化成 [[0, i/η], [i·η, 0]]。这种“四分之一波长层”是薄膜设计里最基本的积木,因为它对导纳的作用最干脆:每经过一层,等效导纳就从 Y 变成 η²/Y,是一次纯粹的反演。

4.2 六层 HL 交替:等效导纳的递推

实验里用的六层结构是 SiO₂ 和 TiO₂ 交替,也就是低折射率 L(约 1.46)和高折射率 H(约 2.35)交替。在中心波长处,每一层都是四分之一波长厚度,于是等效导纳可以从基底开始一层层往上反演。

# 四分之一波长堆在中心波长处的峰值反射率 # 递推规则:每加一层 QWOT,导纳 Y -> n^2 / Y def peak_reflectance(n_inc, n_sub, layers): """layers 从入射侧到基底排列,元素为各层折射率""" Y = n_sub for n in reversed(layers): # 从基底一侧向入射侧反推 Y = n * n / Y return ((n_inc - Y) / (n_inc + Y)) ** 2 nH, nL = 2.35, 1.46 # TiO2 / SiO2 n_inc, n_sub = 1.0, 1.52 # 空气 / 玻璃基底 # 情况一:从入射侧数 L,H,L,H,L,H —— 低折射率贴空气 r1 = peak_reflectance(n_inc, n_sub, [nL, nH, nL, nH, nL, nH]) # 情况二:从入射侧数 H,L,H,L,H,L —— 高折射率贴空气 r2 = peak_reflectance(n_inc, n_sub, [nH, nL, nH, nL, nH, nL]) print(f"L 收尾: R = {r1:.1%}") # L 收尾: R = 70.4% print(f"H 收尾: R = {r2:.1%}") # H 收尾: R = 86.0%

同样是六层、同样两种材料、同样四分之一波长厚度,峰值反射率差了将近 16 个百分点。原因就在递推的最后一步:等效导纳从基底一侧被反演了六次,最后落在入射介质面前的那个值,取决于最外层是高折射率还是低折射率。高折射率收尾时,等效导纳被推到 26 左右,与空气的 1.0 严重失配,反射率自然高;低折射率收尾时只推到 0.087,虽然也是失配,但方向相反,反射率低一截。

这个细节在实际设计里经常被忽略,因为它不影响反射带的位置,只影响峰值。软件里改一个层序,曲线形状看着差不多,峰值差一截,很容易被当成数值误差放过去。

4.3 反射带有多宽:一个 arcsin 决定的事

四分之一波长堆的高反射区不是无限宽的,它的相对带宽有个解析式:

Δλ / λ₀ = (4/π) · arcsin[(ηH − ηL) / (ηH + ηL)]

代入 2.35 和 1.46,得到 (0.89)/(3.81) ≈ 0.234,arcsin 出来约 0.236 弧度,乘以 4/π 得 0.30。也就是说,反射带的相对宽度大约是中心波长的 30%。

如果中心波长设在 900nm,反射带大致覆盖 765nm 到 1035nm,宽度约 270nm。这个结果跟“700 到 1200nm 都适合反射”这个描述有明显出入——真实的高反区在两端都会掉下来,700nm 附近和 1200nm 附近其实是过渡区,反射率已经在往下走了。这不是实验做错了,而是六层堆的物理上限:层数不够,带宽就是不够宽。

想让带宽覆盖得更广,只有两条路:换折射率比更大的材料组合,或者用变厚度堆(chirped stack)把不同中心波长的子堆

本文还有配套的精品资源,点击获取

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询