​
​
A Wolfram Notebook on the Construction of a Spherical Aberration–Free Lens
This construction follows the paper “General Formula for Bi-aspheric Singlet Lens Design Free of Spherical Aberration” by Rafael G. González-Acuña and Héctor A. Chaparro-Romo, published in Applied Optics, vol. 57, issue 31, pp. 9341–9345 (2018).
We consider a single lens of thickness
t
at the center. The distance from the object to the left surface is
ta
, and the distance from the right surface of the lens to the image is
tb
. The index of refraction of the lens is
n
.
The goal is the construction of an aberration-free lens. This means the optical path lengths of all rays must be the same. Compared with the optical path length of a ray along the center line, any other ray has a larger geometric arc length. To achieve a constant optical path length, the longer geometric path length must be compensated by a smaller distance of the ray within the lens. Given the shape of the left surface of the lens in the form
z=z(r)
, the equality of all optical path lengths determines the exit points for every ray, and so the shape of the right lens surface.
Using Snell's law, one can determine a parametrization of the right lens surface purely algebraically in terms of the shape of the left lens surface. The parametrization is in terms of the
r
coordinate of the left surface, as the
r
coordinate determines a unit entry point of the ray into the lens. No differential equation of the integral equation has to be solved. Such a construction is possible as long as the light rays don’t cross.
In the paper, the authors give Wolfram Language code to determine the right surface. Here is a slightly condensed form of their code:
In[1]:=
rightLensSurface[ra_,za_,n_,{ta_?Negative,t_,tb_?Positive}]:=​​Module{Φ,ri,zi,fi,z0,h0,h1,zb,rb,ζ=za[ra],d=
′
za
[ra],α,β},​​α=Sqrt[
2
ra
+
2
(ζ-ta)
];β=(ra+(ζ-ta)d)(nα(1+
2
d
));​​Φ=Sqrt1(1+
2
d
)-
2
β
;​​ri=β-dΦ;​​zi=d(ri+dΦ)+Φ;​​fi=ta-tb+α;​​h0=
2
ri
ζ+finzi-rarizi+(t+tb)
2
zi
-
2
n
(ζ+tzi);​​h1=
2
ra
+2rarit+
2
(tb-ζ)
+
2
t

2
ri
+
2
(zi-1)
-2t(tb-ζ)(zi-1);​​zb=h0+Sqrt[
2
zi

2
fi
-2fin(rari+
2
ri
t+zi(t(zi-1)-tb+ζ))+​​h1
2
n
-
2
(razi+ri(t+tb-ζ))
](1-
2
n
);​​rb=ra+ri(zb-ζ)zi;​​{zb,rb}
Here is an example of the left lens surface being defined through a Bessel function:
In[2]:=
leftLensSurface[ra_]:=BesselJ[0,ra/2]-1
This is the resulting lens shape. The left lens surface is plotted as a blue curve, and the right one as a dark red curve:
lensCurves=ParametricPlot[{{leftLensSurface[ra],ra},​​rightLensSurface[ra,leftLensSurface,1.5,{-20,3,30}]},{ra,-6.15,6.15},PlotStyle{Blue,Darker[Red]},AxesLabel{"z","r"}]
Out[3]=
Gluing the two surfaces together gives the lens:
In[4]:=
lens=Polygon[Join[#[[1,1]],Reverse[#[[2,1]]]]&[Cases[lensCurves,_Line,∞]]];
We define the path of a light ray through the lens:
In[5]:=
rayPath[ra_]:=Line[{{-20,0},{leftLensSurface[ra],ra},​​rightLensSurface[ra,leftLensSurface,1.5,{-20,3,30}],{30+3,0}}]
Graphics[{LightGray,EdgeForm[Black],lens,​​Darker[Yellow],Thickness[0.001],Table[rayPath[ra],{ra,-6.,6,12/40}]},​​AxesTrue,ImageSize800]
Out[6]=
Here is an explicit check that all rays have the same optical path length:
In[7]:=
pathLength[Line[{p0_,pa_,pb_,p1_}],n_]:=EuclideanDistance[p0,pa]+nEuclideanDistance[pa,pb]+EuclideanDistance[pb,p1]
pathLength[#,1.5]&/@Table[rayPath[ra],{ra,-6.,6,12/20}]
Out[8]=
{54.5,54.5,54.5,54.5,54.5,54.5,54.5,54.5,54.5,54.5,54.5,54.5,54.5,54.5,54.5,54.5,54.5,54.5,54.5,54.5,54.5}
Combining the lens construction and the ray drawing into a single function AberrationFreeLensRayPlot allows us to conveniently plot many lens shapes:
In[9]:=
makeLens[za_,n_,{ta_?Negative,t_,tb_?Positive},R_]:=​​Module[{lensCurves},​​lensCurves=ParametricPlot[{{za[ra],ra},rightLensSurface[ra,za,n,{ta,t,tb}]},{ra,-R,R},Exclusions{},PlotStyleBlack,AxesLabel{"z","r"}];​​Polygon[Join[#[[1,1]],Reverse[#[[2,1]]]]&[Cases[lensCurves,_Line,∞]]]]
In[10]:=
rayPath[ra_,za_,n_,{ta_?Negative,t_,tb_?Positive}]:=​​Line[{{ta,0},{za[ra],ra},​​rightLensSurface[ra,za,n,{ta,t,tb}],{tb+t,0}}]
In[11]:=
AberrationFreeLensRayPlot[za_,n_,{ta_?Negative,t_,tb_?Positive},R_,rc_]:=​​Module[{lens=makeLens[za,n,{ta,t,tb},R]},​​Graphics[{LightGray,EdgeForm[Black],lens,Darker[Yellow],Thickness[0.001],cc=Cases[tab=Table[N@rayPath[ra,za,n,{ta,t,tb}],{ra,-0.9R,0.9R,1.8R/rc}],Line[{{_Real,_Real}..}]]},​​AxesTrue,ImageSize680]]
Here is the same functional shape of the lens surface, but with smaller object and image distances:
The next graphic uses a much larger index of refraction:
The following two plots use spherical left lens surfaces:
Here is a flat left lens surface:
Here is a conical left lens surface:
To get an intuitive feeling for the shape of the right lens surface as a function(al) of the left surface, we implement an interactive demonstration that defines the left lens surface as an interpolation of six control points: