符号概念
首先以折射球面为例,介绍一些基本概念和规则符号规则。如下图E是一个球面折射面,半径为r,左侧 A为物点,物空间折射率为 n ,A'点为像点,像空间折射率为 n' .A 与 A′ 都在光轴上。
1、光轴与球面O 称为顶点
2、光线与光轴的O 点的距离统称为截距AO的距离 L 为物方截距;A'O 的距离L'为像方截距。
3、光线与光轴的夹角统称为孔径角U为物方孔径角,U'为像方孔径角。
正负号说明:
- 沿轴线段:从左至右为正方向,并以顶点O为原点.例如图中标注的 -L,L',r .
- 垂轴线段:以光轴为基准,上方为正,下方为负.例如图中标注的 ℎ .
- 光线与光轴夹角:以锐角度量,由光轴转向光线,顺时针为正,逆时针为负.例如图中标注的-U,U′ .
- 光线与法线的夹角:以锐角度量,由光线转向法线,顺时针为正,逆时针为负.例如图中标注的 I,I′ 。
- 光轴与法线的夹角:以锐角度量,由光轴转向法线,顺时针为正,逆时针为负.例如图中标注的
- 相邻两折射面的间隔:由前一面的顶点到后一面的顶点,顺光线方向为正,反之为负,通常用 d 来表示.
单个折射面的光路公式:
对于共轴球面系统如下图:
其有过渡公式:
代码
绘制镜头数据函数
function drawLens(Dmin,n,d,r)
%% 求解不同镜面组矩阵 z
onenum=find(n(2:end-1)==1);
onenum=[0 onenum length(r)];
z=zeros(length(onenum)-1,length(r));
for i=1:length(onenum)-1
z(i,(onenum(i)+1:onenum(i+1)))=1;
end
%% 确定圆心矩阵 c
for dn=1:length(d)+1
if dn==1
c(dn,:)=[r(dn),0]; %c圆心矩阵
else
c(dn,:)=[r(dn)+sum(d(1:dn-1)),0];
end
end
%% 求两个曲面的交点位置X和Y,函数:caljiaodian
X=[];Y=[];
face=[];
for j=1:size(z,1)
rt= r.*z(j,:);
for i=1:length(rt)-1
if (rt(i)*rt(i+1)<0)
if(rt(i)>rt(i+1))
%求交点
[xx,yy]=caljiaodian(c(i,:),c(i+1,:),r(i),r(i+1));
X=[X xx];Y=[Y yy];
face=[face i];
else
end
else
end
end
end
H=min([Y Dmin]);
%% 绘制曲面
for len_m=1:length(r)
if len_m==1
dist=0;
else
dist=sum(d(1:len_m-1));
end
beginAngle=pi-asin(abs(H/r(len_m)));
% endAngle=pi+asin(abs(H/r(len_m)));
theta=(pi-asin(abs(H/r(len_m)))):pi/10000:(pi+asin(abs(H/r(len_m))));
if r(len_m)==inf
line([dist,dist],[-H,H],'LineWidth',2,'Color','b');
topPointsX(len_m)=dist+0.00001;
hold on
else
topPointsX(len_m)=c(len_m,1)+r(len_m)*cos(beginAngle);
lens_x=c(len_m,1)+r(len_m)*cos(theta);
lens_y=c(len_m,2)+r(len_m)*sin(theta);
plot(lens_x,lens_y,'LineWidth',2,'Color','b');
hold on
end
axis equal
end
for i=1:size(z,1)
pointsX=z(i,:).*topPointsX;
pointsX(pointsX==0)=[];
line(pointsX,H*ones(1, length(pointsX)),'LineWidth',2','Color','b');
hold on
line(pointsX,-H*ones(1, length(pointsX)),'LineWidth',2','Color','b');
end
end
求两个曲面的交点位置函数
%% c1=[0,0]; r1=2; c2=[2,0]; r2=1.5;
function [X,Y]=caljiaodian(c1,c2,r1,r2)
di=norm(c2-c1);
a=(r1^2-r2^2+di^2)/(2*di);
h=sqrt(r1^2-a^2);
p=c1+a*(c2-c1)/di;
X=abs(p(1)+h*(c2(2)-c1(2))/di);
Y=abs(p(2)-h*(c2(1)-c1(1))/di);
end
Dim是镜头最大半径宽度,n,d,r分别是镜头数据矩阵。
示例:
n=[ 1.0 , 1.51678944 , 1, 1.51678944 , 1.62003683,1.0];
r=[ inf, -12.800137 , 14.134810 , -3.889630,-8.841530 ];
d=[ 1.0 , 10 , 2.0 , 1.0 ];
drawLens(4,n,d,r);
结果:
计算光线函数:
function [x,y]=Ray(Raynum,L,Umax,R,d,n)
%U=0.05;
R(R==inf)=9999999;
r=R;
Imax=asin((L(1)-r(1))*sin(Umax)/r(1));
hmax=r(1)*sin(Umax+Imax);
xmax=(r(1)-r(1)*cos(Imax+Umax));
rangemin=-atan((hmax)/abs(L-xmax));
rangemax=atan((hmax)/abs(L-xmax));
ray=linspace(rangemin,rangemax,Raynum);
for i=1:Raynum
U=ray(i);
for m=1:length(r)
n1(m)=n(m+1);
h(m)=r(m)*sin(U(m)+I(m));
I1(m)=asin(n(m)/n1(m)*sin(I(m))); %折射定律
U1(m)=U(m)+I(m)-I1(m);
L1(m)=r(m)*(1+sin(I1(m))/sin(U1(m)));
if m==1
dist=0;
else
dist=sum(d(1:m-1));
end
x(i,m)=(r(m)-r(m)*cos(I1(m)+U1(m)))+dist;
y(i,m)=r(m)*sin(I1(m)+U1(m));
if m==length(r)
x0(i)=L(1);
x1(i)=L1(end)+dist;
y0(i)=0;
y1(i)=0;
break
end
U(m+1)=U1(m);
L(m+1)=L1(m)-d(m);
end
end
x=[x0' x x1'];
y=[y0' y y1'];
end
示例:
%% 计算光线
[x,y]=Ray(raynum,L,U,r,d,n);
[a,b]=find(ismissing(x)==1);
x(a,b)=max(x(:,end));
%% 绘制光线
for i=1:raynum
plot(x(i,:),y(i,:),'LineWidth',1.0,'Color','r');
hold on
end
结果:
仿真结果
球差