Ray Tracing
SLAC and Stanford University Software Notices:
Introduction
- This package is designed to enable students to study simple optical systems beyond the usual thin lens approximation. As structured it is limited to the study of lens systems where the lenses have a cylindrical symmetry, so that it suffices to trace all rays in a single plane. The source code can be easily adapted to the more general case of lenses with astigmatism. In order to make it easy to develop more general code based on this package I expose the internal routines used by the workhouse function
RayTrace
.
- To use the basic package one only needs to understand the functions
MakeLens
,
RayTrace
and
display
. All of the other functions are only needed to design extensions to the basic package.
- Each command in the RayTracing package can be accessed by using either the
long form
or the
short form
of the command name in the command calling sequence.
- As the underlying implementation of the <Package_Name> package is a module, it is also possible to use the form <Package_Name>:-command to access a command from the package. For more information, see
Module Members
.
Starting
"running setup"
![[MakeLens, MakeRay, MakeUnitVec, RayTrace, RayTrace2, Transform, TransformL1, TransformL2, Transport, Transport_to_Surface, focal_length]](/view.aspx?SI=4813/RayTracing_2.gif)
To start a raytracing worksheet begin with the command with(RayTracing) . The restart command is at the top of this page so I can
clear all variables and start fresh without shutting down Maple.
The first thing you have to do when raytracing is define the left and right lens surfaces. This is done by specifying two functions, the left hand lens surface is specified by the function
and the right hand side by
. Note that the variable y
runs along the vertical axis and the function gives the set-back of the lens from the origin of the horizontal axis. Once we have them we can plot the lens by plotting two curves as shown below.
Examples
> |
lens1:=y->evalf(13-sqrt(13^2-y^2));
lens2:=y->evalf(sqrt(13^2-y^2)-13+2*lens1(3)+.3);
lens:=plot({[lens1(y),y,y=-3..3],[lens2(y),y,y=-3..3]}):
lens;
|
Later we want to deal with non-concentric lenses. This is accomplished below. Eventually we will define
to be
and then we can retrace
everything to see the effects.
> |
lens3:=x->evalf(sqrt(13^2-x^2)-13+2*lens1(3)+.4);
shifted_lens:=plot({[lens1(x),x,x=-3..3],[lens3(x),x,x=-3..3]}):
shifted_lens;
lens4:=x->evalf(sqrt(13^2-x^2)-13+2*lens1(3)+.5); |
![[[3, 12.37370934], [2.5, 12.75439394], [2.0, 13.05236428], [1.5, 13.27645196], [1.0, 13.43267504], [.5, 13.52494785]]](/view.aspx?SI=4813/RayTracing_17.gif)
The command RayTrace(p0,y_initial,index_of_refraction) to trace a single ray. The first argument to the function is the 2-d vector specifying the
starting point of the ray. The syntax <x0,y0> is Maple's shorthand way of specifying a vector. The next argument is the height at which you want
the first ray to hit the first surface of the lens. The last argument is the index of refraction
for Joel's material.
> |
display(RayTrace(<-10,1.5>,1.5,1.4735),RayTrace(<-10,1>,1,1.4735),RayTrace(<-10,.5>,.5,1.4735), RayTrace(<-10,-.5>,-.5,1.4735), RayTrace(<-10,-1>,-1,1.4735),RayTrace(<-10,-1.5>,-1.5,1.4735),lens); |
The plot below is the same but I have scaled it, and panned around to display the point of intersection and use Maple's ability to
get coordinates off the plot to calculate the point-spread for a point source at infinity.
> |
display(RayTrace(<-10,1.5>,1.5,1.4735),RayTrace(<-10,1>,1,1.4735),RayTrace(<-10,.5>,.5,1.4735), RayTrace(<-10,-.5>,-.5,1.4735), RayTrace(<-10,-1>,-1,1.4735),RayTrace(<-10,-1.5>,-1.5,1.4735),lens); |
The width of the spot at its minimum is 0.015mm, or 15 microns. This is the best resolution you will get with a lens masked to a 3mm diameter. It is about
twice as bad if we go out to 5mm diameter masking.
One can also raytrace the imaging of point sources at a finite distance from the lens on axis.
> |
p0:=<-40,0>;
display(RayTrace(p0,1.5,1.4735),RayTrace(p0,1,1.4735),RayTrace(p0,.5,1.4735), RayTrace(p0,-.5,1.4735), RayTrace(p0,-1,1.4735),RayTrace(p0,-1.5,1.4735),lens); |
The point spread for the source at a finite distance is 0.017mm or 17microns. Not much worse. Some more traces for on axis points
are shown below. Note that the image moves toward the focal point as the source moves further away.
> |
p0:=<-100,0>;display(RayTrace(p0,1.5,1.4735),RayTrace(p0,1,1.4735),RayTrace(p0,.5,1.4735), RayTrace(p0,-.5,1.4735), RayTrace(p0,-1,1.4735),RayTrace(p0,-1.5,1.4735),lens); |
> |
p0:=<-200,0>;display(RayTrace(p0,1.5,1.4735),RayTrace(p0,1,1.4735),RayTrace(p0,.5,1.4735), RayTrace(p0,-.5,1.4735), RayTrace(p0,-1,1.4735),RayTrace(p0,-1.5,1.4735),lens); |
Now we get to have some fun. What is the point spread for the image of an off-axis point? Scaling and measuring we get 0.018 mm. Worse but not bad.
Note the image is off axis. From this we get the magnification (or demagnification of a distant object by the lens.)
> |
p0:=<-100,.5>;display(RayTrace(p0,1.5,1.4735),RayTrace(p0,1,1.4735),RayTrace(p0,.5,1.4735), RayTrace(p0,-.5,1.4735), RayTrace(p0,-1,1.4735),RayTrace(p0,-1.5,1.4735),lens); |
Some more off axis plots. As we get more off axis the point spread gets only marginally worse 0.02mm. This is not the cause of our fuzziness.
> |
p0:=<-100,2>;display(RayTrace(p0,1.5,1.4735),RayTrace(p0,1,1.4735),RayTrace(p0,.5,1.4735), RayTrace(p0,-.5,1.4735), RayTrace(p0,-1,1.4735),RayTrace(p0,-1.5,1.4735),lens); |
> |
p0:=<-100,2>;display(RayTrace(p0,1.5,1.4735),RayTrace(p0,1,1.4735),RayTrace(p0,.5,1.4735), RayTrace(p0,-.5,1.4735), RayTrace(p0,-1,1.4735),RayTrace(p0,-1.5,1.4735),lens); |
> |
p0:=<-100,2>;display(RayTrace(p0,1.5,1.4735),RayTrace(p0,1,1.4735),RayTrace(p0,.5,1.4735), RayTrace(p0,-.5,1.4735), RayTrace(p0,-1,1.4735),RayTrace(p0,-1.5,1.4735),lens); |
Lets now redefine
so as to do some non-concentric problems.
> |
lens2:=x->evalf(sqrt(13^2-(x+.05)^2)-13+2*lens1(3)+.02); |
> |
MakeLens(lens1,lens2):
lens:=plot({[lens1(x),x,x=-3..3],[lens2(x),x,x=-3..3]}):
lens; |
Let's begin with a point source at infinity.
> |
display(RayTrace(<-10,1.5>,1.5,1.4735),RayTrace(<-10,1>,1,1.4735),RayTrace(<-10,.5>,.5,1.4735), RayTrace(<-10,-.5>,-.5,1.4735), RayTrace(<-10,-1>,-1,1.4735),RayTrace(<-10,-1.5>,-1.5,1.4735),lens); |
Legal Notice: The copyright for this application is owned by the author(s). Neither Maplesoft nor the author are responsible for any errors contained within and are not liable for any damages resulting from the use of this material. This application is intended for non-commercial, non-profit use only. Contact the author for permission if you wish to use this application in for-profit activities.