本文基于光学原理,用Matlab实现光场传输函数。
以下展示了两种菲涅尔光场传输的数值计算方法:
- 菲涅尔衍射积分的离散求和
- 菲涅尔衍射FFT法
Project Code
% 作者:ZQJ
% 日期:2021.7.22 星期四
%***********************光场传输函数**************************
function Light_transmissions = f_Lightfield_transmission
Light_transmissions.Fresnel_integrate = @trans_1;
Light_transmissions.CONV_ = @trans_2;
Light_transmissions.FFT_ = @trans_3;
Light_transmissions.matrix_multiplication = @trans_4;
end
function transmission_E = trans_1(lamda,E0,E_x,E_y,screen_x,screen_y,Nx,Ny,z)
% 函数功能: 基于菲涅尔衍射积分的光场传输 (计算结果较准确,但计算速度较慢1024*1024特慢)
% 参数
% lamda: 波长
% E0: 原光场(传播前)分布情况——2D matrix
% E_x:原光场x方向总长度
% E_y:原光场y方向总长度
% screen_x:接收屏x方向总长度
% screen_y:接收屏y方向总长度
% Nx,Ny: 接收屏x,y方向等分割数目
% z: 传输距离
k = 2*pi/lamda;
[E0_nx,E0_ny] = size(E0);
[x0,y0] = meshgrid(linspace(-E_x/2,E_x/2,E0_nx),linspace(-E_y/2,E_y/2,E0_ny)); % 原电场坐标
[x1,y1] = meshgrid(linspace(-screen_x/2,screen_x/2,Nx),linspace(-screen_y/2,screen_y/2,Ny)); % 接收屏坐标
E1 = zeros(Nx,Ny);
for sx = 1:Nx
for sy = 1:Ny
%菲涅尔衍射积分公式
E1(sx,sy) = exp(1i*k*z)/(1i*lamda*z)*sum(sum(E0.*exp(1i*k/2/z*((x1(sx,sy)-x0).^2+(y1(sx,sy)-y0).^2))));
end
end
transmission_E = E1;
end
function transmission_E = trans_3(lamda,E0,screen_x,screen_y,z)
% 函数功能: 基于菲涅尔衍射傅里叶变换运算的光场传输 (计算速度较快)
% 参数
% lamda: 波长
% E0: 原光场(传播前)分布情况——2D matrix
% screen_x:接收屏x方向总长度
% screen_y:接收屏y方向总长度
% z: 传输距离
k = 2*pi/lamda;
[E0_nx,E0_ny] = size(E0);
F_sx = linspace(-E0_ny/screen_x/2,(E0_ny-2)/screen_x/2,E0_ny);
F_sy = linspace(-E0_nx/screen_y/2,(E0_nx-2)/screen_y/2,E0_nx);
[Fx,Fy] = meshgrid(F_sx,F_sy); % 接收屏的频域坐标(与时域坐标有对应关系,分辨率因子变了)
H = exp(1i*pi*lamda*z*(Fx.^2+Fy.^2)).*exp(-1i*k*z); % 菲涅耳衍射空间传递函数
H = fftshift(H);
F_E0 = fft2(fftshift(E0));
transmission_E = fftshift(ifft2(H.*F_E0));
end
专栏内容供作者本人或大家学习使用,多多指教 ~