构建镜头模型
让我们用这个包建立一个理想镜头的模型 GeometricalOptics.jl. 我们将展示如何在一个画布上显示光束传播的几个图形,并在这个图形上实现射线优化过程,使图形的信息量最大。
光学系统参数
要指定镜头参数,您需要连接(并可能安装)库 GeometricalOptics.
Pkg.add( url="https://github.com/airspaced-nk5/GeometricalOptics.jl#master" )
Pkg.add( "Optim" )
using GeometricalOptics
gr(); # 该库使用这种图形渲染机制效果更好。
现在我们可以指定几个球面透镜和一个像平面。:
/物体/类型|材料|折射率|半径R1(mm)|半径R2(mm)|厚度/跟踪距离。 |
| ----------- | ----------- | ----------- | ----------- | ----------- | ----------- | ----------- | ----------- |
/镜头/双凸/[SK16](https://refractiveindex.info/?shelf=glass&book ;=HIKARI-SK&page;=SK16) | 1.6204 | 22 | 430 | 3 | 6 |
/镜头/biconcave/[F2](https://refractiveindex.info/?shelf=glass&book ;=肖特-F&页;=F2) | 1.6200 | 22 | 20 | 1 | 6 |
/镜头/双凸/[SK16](https://refractiveindex.info/?shelf=glass&book ;=HIKARI-SK&page;=SK16) | 1.6204 | 78 | 16 | 3 | 34 |
光学系统的最后一个元件是像平面。
测量单位(毫米)在计算中不起特殊作用,只要我们不考虑衍射和波长。
透镜的厚度等于光线沿着光轴穿过透镜的路径长度。
半径R1和R2被理解为每个透镜的每一侧的曲率半径:R1表征位于更靠近光源的"输入"侧的曲率半径,R2是位于更靠近像平面的透镜的输出侧。
让我们来描述这个光学系统,并建立一个小的可视化。:
surfsList = [ spherical, spherical,
spherical, spherical,
spherical, spherical,
zplane]
p_s = 10; # 图的左边缘到第一折射面的距离
stations = p_s .+ [ 0., 3., 9., 10., 16., 19., 53. ]
radii = [ 22., -430., -22., 20., 78., -16., 0.0 ]
coeffsList = [ [s, r] for (s,r) in zip(stations, radii)]
# 镜片材质,依序:SK16、F2、SK16
nList = [ 1., 1.6204,
1., 1.6200,
1., 1.6204,
1.]
optSta = opticalstack( coeffsList, surfsList, nList );
test_bundle = bundle( [0.], (-3:3:3), 0., 0., 0. );
p_lens = optSta( test_bundle; rend = "YZ", halfdomain=3.5 )
plot!( ylimits=(-5,5), aspect_ratio=:none, size=(600,200) )
一个小小的可视化让我们看到所有指定的元素。
将光束瞄准孔径
现在让我们假设该系统具有位于凹透镜后2毫米的光圈。
我们希望将光束穿过它,设置一定的入射角,并确保它们聚焦在图像平面上。
我们可以将模型分成两部分,并模拟膜片在两个方向上的传播(一个表面模型) [6:end],另一个为 [5:-1:1]). 但是由于射线只有在接近第一个透镜时才应该平行(它们在穿过光阑时不会相互平行),我们必须在穿过光阑时寻找每条射线的角度。
让我们走另一条路,"优化"两个参数:光束宽度和光束中心光束指向的Y轴上的点。 我们的目标是找到射线正好穿过膜片的光束的参数。
angles = [0.0, 0.1, 0.2]; # 每束射线的角度
colors = [:blue, :green, :red]; # 每个束都有自己的颜色
ypositions_init = [ 0., 3.0, 5.0]; # 沿Y轴发送中心射线的点的近似位置
bundle_halfwidth = 3; # 光束的半径
p = plot(); # 让我们绘制一些图表
for (angle, ypos, pc, plot_surface) in zip(angles, ypositions_init, colors, [true, false, false])
b = bundle([0.], range(-bundle_halfwidth,bundle_halfwidth,length=3) .- ypos, 0., angle, 0.)
optSta( b; rend = "YZ", color = pc, plobj = p, halfdomain=5.5, issurfplot=plot_surface )
end
plot!( p, p_s.+[12., 12.], [-2.5, 2.5], lw=2, lc=:black, markershape=:diamond, markercolor=:white );
plot!( p, ylimits=(-8,8), size=(900,400) )
如果我们放大光圈的图像,我们会看到我们的第一个近似值离所需的近似值不是很远,但是为了进行准确的计算,我们需要将光束发送的点移动一点。
光束与光轴的角度不会改变。 我们只是在寻找如何定位光束,使其精确地穿过隔膜。 这对于计算传感器尺寸和其他有趣的结果很有用。
plot!( xlimits=(p_s .+ [10, 14]), ylimits=(-3,3), aspect_ratio=:none, size=(500,500) )
现在让我们创建一个优化过程。
using Optim
# 以光圈"结束"的新配置(尽管您可以在任何镜头之间添加zplane)
optSta2 = opticalstack( [coeffsList[1:4]; [[p_s+12.]]], [surfsList[1:4]; zplane], [nList[1:4] ; 1.0] );
# 我们将优化的功能
function f(x, in_angle)
b_hw = x[1] # 光束半径
ypos = x[2] # 光束中心的Y偏移
b = bundle([0.], range(-b_hw,b_hw,length=3) .- ypos, 0., in_angle, 0.);
# 让我们研究光束与第6表面相交处的光斑
t_info = GeometricalOptics.trace_extract_terminus( optSta2( b ), 6, coord="y" );
# 两个优化标准:光点的两个边界都必须与光圈的大小相匹配
q1 = abs( minimum( t_info ) - (-2.5))
q2 = abs( maximum( t_info ) - ( 2.5))
return q1 + q2
end
angles_hw_list = []
y_positions_list = []
for (angle,y_pos_init) in zip(angles, ypositions_init)
# 我们分别对需要的每个角度值进行优化。
res = optimize(x -> f(x, angle), [bundle_halfwidth, y_pos_init])
angle_optim, ypos_optim = Optim.minimizer( res )
push!( angles_hw_list, angle_optim )
push!( y_positions_list, ypos_optim )
end
# 让我们显示一个优化结果表。
display([["光束方向"; "光束宽度"; "Y的起点"] [angles angles_hw_list y_positions_list]'] )
优化后,光学系统看起来像这样:
p = plot(); # 用于绘制多个图形的画布
for (angle, ypos, b_hw, pc, plot_surface) in zip(angles, y_positions_list, angles_hw_list, colors, [true, false, false])
b = bundle([0.], range(-b_hw,b_hw,length=3) .- ypos, 0., angle, 0.)
optSta( b; rend = "YZ", color = pc, plobj = p, halfdomain=5.5, issurfplot=plot_surface )
end
plot!( p, p_s.+[12., 12.], [-2.5, 2.5], lw=2, lc=:black, markershape=:diamond, markercolor=:white );
plot!( p, ylimits=(-8,8), size=(900,400) )
仔细检查膜片可以让你看到光点的正确位置。
plot!( xlimits=(p_s .+ [10, 14]), ylimits=(-3,3), aspect_ratio=:none, size=(500,500) )
库中的镜头尺寸
GeometricalOptics.jl它们在视觉上没有被考虑在内。 在某些情况下,例如,当创建多项式Цернике,光束在某个区域之外的通过导致开发人员提供的误差。
结论
如果将光学电路计算功能包装在优化过程中,则可以自动化许多光学系统设计步骤。 光束由单独的光线组成,它们在系统任何部分的参数都可以使用函数获得 trace_extract_terminus 对她подобных.
在少量额外代码的帮助下,可以计算AF范围和其他任务。
数据来源
[[1]](http://mir-3d-world.ipo.spb.ru/2016/3dworld_4_2016.pdf )在Zemax中构建理想光学[电子资源]//科普杂志"3D世界世界":网站。 网址:http://mir-3d-world.ipo.spb.ru/2016/3dworld_4_2016.pdf (请求日期:05.11.2024)。



