9. The Anatomy of Component

Make sure that the LensLab package is located either in the home directory, or on a directory path recognized by Mathematica for packages. The LensLab package is named LensLab.m and located in the LensLab directory, and the LensLab package is loaded with the following expression.

In[1]:=

Needs["LensLab`LensLab`"]

This loading process should only take a few seconds. In addition to being loaded as a package, the LensLab.m file is formated as a Mathematica notebook. The LensLab source code is made accessible so that you can develop new functions of your own by studying LensLab's built-in functions. This is particularly helpful when you wish to model new component ideas in LensLab. However, you should receive permission from Optica Software before distributing any user-created functions that are derived from the LensLab source code. The unauthorized distribution of LensLab-derived code may be a LensLab license agreement violation or a copyright infringement.

Introduction

Chapter 9 serves as a reference chapter about LensLab's Component object. The Component object contains rules characterizing one or more optical components. LensLab primarily uses these rule descriptions to control how rays interact with the components and how the components are rendered. Although you can create a Component object by entering the Component expression into Mathematica manually, it is much easier to use a component function to generate the object for you. When it is necessary to make a custom component, you can normally use genetic building blocks as shown in Chapter 5. The purpose of this chapter is to introduce each of the genetic rules expressed within Component.

Let's examine the genetic characteristics of a typical Component, namely PlanoConvexLens[100,50,10].

We use InputForm to look at the output expression normally suppressed from the screen.

In[2]:=

InputForm[PlanoConvexLens[100,50,10]]

Out[2]//InputForm=

Component[ComponentDescription -> {PlanoConvexLens, ComponentFoundation, ComponentRendering,
Refraction}, Surfaces ->
{{SurfaceFunction -> {-Sqrt[2690.707829696608 - #1^2 - #2^2] + 51.872033213443714 & , #1 & ,
#2 & }, SurfaceLabel -> SphericalShape, SurfaceValue -> 51.872033213443714,
SurfaceNormalFunction -> {{1 & , -(#1/Sqrt[2690.707829696608 - #1^2 - #2^2]) & ,
-(#2/Sqrt[2690.707829696608 - #1^2 - #2^2]) & },
{#1/Sqrt[2690.707829696608 - #1^2 - #2^2] & , 1 & , 0 & },
{#2/Sqrt[2690.707829696608 - #1^2 - #2^2] & , 0 & , 1 & }},
SurfaceRayIntersections -> Automatic, RotationMatrix -> {{1., 0., 0.}, {0., 1., 0.},
{0., 0., 1.}}, TranslationVector -> {0., 0., 0.}, SurfaceCenter -> {0., 0., 0.},
SurfaceBoundary -> 50., OffAxis -> {0., 0.}}, {SurfaceFunction -> {0. & , #1 & , #2 & },
SurfaceLabel -> PlanarShape, SurfaceValue -> Infinity, SurfaceNormalFunction ->
{{1 & , 0 & , 0 & }, {0 & , 1 & , 0 & }, {0 & , 0 & , 1 & }},
SurfaceRayIntersections -> Automatic, RotationMatrix -> {{1., 0., 0.}, {0., 1., 0.},
{0., 0., 1.}}, TranslationVector -> {10., 0., 0.}, SurfaceCenter -> {10., 0., 0.},
SurfaceBoundary -> 50., OffAxis -> {0., 0.}}},
Deflections -> {{{AddTo -> {NewRay}, TakeFrom -> {OriginalRay},
DeflectionFunction -> {Refraction, {100, BK7, True, IntrinsicMedium -> IntrinsicMedium, 20.,
OriginalRay}}}}}, EntranceCoordinates -> {{0., 0., 0.}, {10., 0., 0.}},
ConfinedPaths -> {{{SurfaceNumber -> 1, DeflectionNumber -> {1.}},
{SurfaceNumber -> 2, DeflectionNumber -> {1.}}},
{{SurfaceNumber -> 2, DeflectionNumber -> {1.}}, {SurfaceNumber -> 1,
DeflectionNumber -> {1.}}}}, RenderedSurfaces -> {{SurfaceNumber -> 1, RenderType -> Empty},
{SurfaceNumber -> 2, RenderType -> Empty}, {SurfaceNumber -> {1, 2}, RenderType -> Mesh}},
RenderedPolygons -> {{{{SurfaceNumber -> 1, StartPoint -> {-25., 0}, FinishPoint -> {25., 0}},
{SurfaceNumber -> 2, StartPoint -> {25., 0}, FinishPoint -> {-25., 0}}},
{RenderType -> {Fill, Trace}}}, {{{SurfaceNumber -> 1, StartPoint -> {0, -25.},
FinishPoint -> {0, 25.}}, {SurfaceNumber -> 2, StartPoint -> {0, 25.},
FinishPoint -> {0, -25.}}}, {RenderType -> {Fill, Trace}}}}]

Notice that Component contains densely nested lists of rules. On the primary level, there are seven genetic rule headings.

ComponentDescription
Surfaces
Deflections
EntranceCoordinates
ConfinedPaths
RenderedSurfaces
RenderedPolygons
.

For the remaining sections in this chapter, we will examine the contents of each of these headings in detail.

9.1 ComponentDescription

Here is how ComponentDescription is used in PlanoConvexLens.

In[3]:=

ComponentDescription ->
{PlanoConvexLens, ComponentFoundation,
ComponentRendering, Refraction}

Out[3]=

Next we define ComponentDescription.

ComponentDescription -> {descriptionlist} identifies the optical component and specifies the genetic building blocks used in the creation of Component.

In our example of ComponentDescription, we see that the first element in descriptionlist is PlanoConvexLens. This first element identifies the optical system being described by Component and is outputted to the screen in place of the entire Component expression. The remaining elements: ComponentFoundation, ComponentRendering, and Refraction, identify genetic building blocks used by PlanoConvexLens to create Component. If a genetic function is called more than once during Component creation, it is listed only once in ComponentDescription.

9.2 Surfaces

Next we define Surfaces.

Surfaces -> {...} gives a list of elements defining component surfaces.

Using the PlanoConvexLens example, we examine the contents of Surfaces.

Surfaces ->
{    {SurfaceFunction ->
{-(Sign[51.87203321344372]*
Sqrt[51.87203321344372^2 - #1^2 - #2^2])
+ 51.87203321344372 & , #1 & , #2 & },
SurfaceLabel -> SphericalShape,
SurfaceValue -> 51.87203321344372,
SurfaceNormalFunction ->
{{1&,
-(#1/(2690.707829696608-#1^2-#2^2)^(1/2))&,
-(#2/(2690.707829696608-#1^2-#2^2)^(1/2))&},
{#1/(2690.707829696608-#1^2-#2^2)^(1/2)&,
1&,0&},
{#2/(2690.707829696608-#1^2-#2^2)^(1/2)&,
0&, 1&}},
SurfaceRayIntersections -> Automatic,
RotationMatrix ->
{{1., 0., 0.}, {0., 1., 0.}, {0., 0., 1.}},
TranslationVector -> {0., 0., 0.},
SurfaceCenter -> {0., 0., 0.},
SurfaceBoundary -> 50., OffAxis -> {0., 0.}}
,
{SurfaceFunction -> {0. & , #1 & , #2 & },
SurfaceLabel -> PlanarShape,
SurfaceValue -> DirectedInfinity[1],
SurfaceNormalFunction ->
{{1&, 0&, 0&}, {0&, 1&, 0&}, {0&, 0&, 1&}},
SurfaceRayIntersections -> Automatic,
RotationMatrix ->
{{1., 0., 0.}, {0., 1., 0.}, {0., 0., 1.}},
TranslationVector -> {10., 0., 0.},
SurfaceCenter -> {10., 0., 0.},
SurfaceBoundary -> 50., OffAxis -> {0., 0.}}}

From PlanoConvexLens, Surfaces has two groupings of rules corresponding with the two lens surfaces. Ten rules normally describe each surface.

`OffAxis                      SurfaceLabelRotationMatrix               SurfaceNormalFunctionSurfaceBoundary              SurfaceRayIntersectionsSurfaceCenter                SurfaceValueSurfaceFunction              TranslationVector`

Names of parameters related to Surfaces.

Each of these rules is defined below and is followed by its use in the example above.

First we define SurfaceFunction.

SurfaceFunction gives a list of three parametric pure function equations {fx, fy, fz} that describe a particular optical surface in three-dimensional space.

Here is how SurfaceFunction was used to define a spherical surface.

SurfaceFunction -> {-(Sign[51.87203321344372]*
Sqrt[51.87203321344372^2 - #1^2 - #2^2])
+ 51.87203321344372 & , #1 & , #2 & }

Next we define SurfaceLabel.

SurfaceLabel indicates the shapes of surfaces created.

Here is how SurfaceLabel was used in the example to identify to LensLab's internal processes that SurfaceFunction is describing a spherical surface.

SurfaceLabel -> SphericalShape

Next we define SurfaceValue.

SurfaceValue  -> # specifies the curvature characteristics of the function given in SurfaceFunction. SurfaceValue is interpreted differently by LensLab according to the accompanying SurfaceLabel option.

Here is how SurfaceValue was used in the example to indicate the radius of curvature for the spherical surface.

SurfaceValue -> 51.87203321344372

Next we define SurfaceNormalFunction.

SurfaceNormalFunction describes the normals of the surface functions.

Here is how SurfaceNormalFunction was used to give the surface normal functions of the spherical surface.

SurfaceNormalFunction ->
{{1&, -(#1/(2690.707829696608-#1^2-#2^2)^(1/2))&,
-(#2/(2690.707829696608-#1^2-#2^2)^(1/2))&},
{#1/(2690.707829696608-#1^2-#2^2)^(1/2)&, 1&, 0&},
{#2/(2690.707829696608-#1^2-#2^2)^(1/2)&, 0&, 1&}}

Next we define SurfaceRayIntersections.

SurfaceRayIntersections indicates whether calculations are symbolic or direct numerical solutions for the ray/surface intersection points.

Here is how SurfaceRayIntersections was used to indicate the use of symbolic solutions at the spherical surface.

In[4]:=

SurfaceRayIntersections -> Automatic

Out[4]=

Next we define RotationMatrix.

RotationMatrix gives a 3 x 3 matrix of spatial rotations invoked on the original object coordinate system by Move functions.

Here is how RotationMatrix was used to specify the rotation given to the spherical surface in three-dimensional space.

RotationMatrix ->
{{1., 0., 0.}, {0., 1., 0.}, {0., 0., 1.}}

Next we define TranslationVector.

TranslationVector gives a three-dimensional vector that contains the spatial translations invoked on the original surface coordinate system by the Move functions.

Here is how TranslationVector was used in the example to specify a translation given to the spherical surface in three-dimensional space.

TranslationVector -> {0., 0., 0.}

Next we define SurfaceCenter.

SurfaceCenter gives the three-dimensional surface center coordinates.

Here is how SurfaceCenter was used to indicate the three-dimensional center point of the spherical surface.

SurfaceCenter -> {0., 0., 0.}

Next we define SurfaceBoundary.

SurfaceBoundary -> aperture gives a list of numbers describing the surface boundary.

Here is how SurfaceBoundary was used above to specify circular aperture dimensions having a 50-millimeter diameter.

SurfaceBoundary -> 50.

Finally we define OffAxis.

OffAxis -> {xoffset, yoffset} gives an offset of the axis of symmetry for curved surfaces.

Here is how OffAxis was used above to indicate that the spherical surface does not have an offset in its axis of symmetry.

OffAxis -> {0., 0.}

9.3 Deflections

Using the PlanoConvexLens example, we examine the contents of Deflections.

In[5]:=

Deflections ->
TakeFrom -> {OriginalRay},
DeflectionFunction ->
{Refraction,
{100, BK7, True,
IntrinsicMedium -> IntrinsicMedium,
20.,OriginalRay}}
}}}

Out[5]=

In the case of PlanoConvexLens, Deflections contains only one grouping of rules corresponding with a single ray-tracing function. Next we define Deflections.

Deflections -> {{functionelement1, functionelement2,...},{...},...} gives a list of elements that define the various functions used in tracing rays within a component.

Each functionelement of Deflections follows a standard format.

{TakeFrom -> {takefromobjects},
DeflectionFunction -> functionlisting}

Here takefromobjects indicates the objects used by DeflectionFunction and addtoobject indicates the objects given by DeflectionFunction. In some cases, ReplaceFor is used instead of AddTo.

DeflectionFunction supports a particular ray-tracing function each time it is present in Deflections. For the case of PlanoConvexLens, only the refraction function is used.

Here we define DeflectionFunction.

DeflectionFunction -> functionlisting relates to the ray-tracing behavior at component surfaces.

DeflectionFunction is used both as a function and as a rule parameter label in Component. As a rule parameter label, DeflectionFunction -> functionlisting is contained within the Deflections rule of Component, where functionlisting can be in a direct or indirect form.

In the direct form, the ray-tracing function is explicitly defined by the functionlisting. In this case, DeflectionFunction -> Function[#] specifies a pure function that uses in its input a list of objects specified by TakeFrom and returns its results to the objects specified by AddTo and ReplaceFor as a list of modified Ray or Component objects carrying only the ray or component parameters being modified.

In the indirect form, the ray-tracing function is defined elsewhere, and only parameter values, rather than the actual ray-tracing function definition, are passed in the functionlisting. In this case, DeflectionFunction -> {deflectionlabel, {inputparameters}} uses deflectionlabel as an identifying label to call up the appropriate external ray-tracing function.

In the case of indirect ray-tracing function definitions, DeflectionFunction also plays a role as the external function head. Here, DeflectionFunction[deflectionlabel, inputparameters] = Function[#] denotes the external ray-tracing function identified by deflectionlabel.

AddTo, ReplaceFor , and TakeFrom are used to indicate the type of Ray and Component information that is put into and taken out of the associated ray-tracing functions.

AddTo -> objecttypes designates the types of objects receiving the new parameter results.
ReplaceFor -> objecttypes designates which types of objects are replaced by the new parameter results of the ray-tracing function calculation.
TakeFrom -> objecttypes indicates which types of objects are used as inputs to the ray-tracing function calculation.

There are seven object types given by AddTo, TakeFrom, and ReplaceFor.

`AllCreatedRays   ChangedRay     CreatedRay OriginalRayChangedComponent ChangedSurface NewRay`

Names of object types used in AddTo, ReplaceFor, and TakeFrom.

These object types have the following definitions.

AllCreatedRays indicates that all Ray objects returned by previous ray-tracing function calculations are passed to or returned from DeflectionFunction.

ChangedComponent
specifies that the Component object may be passed to or returned from DeflectionFunction.

ChangedRay
indicates that the modified Ray objects returned by previous ray-tracing function calculations are passed to or returned from the current DeflectionFunction.

ChangedSurface
specifies that a slotted element from Surfaces may be passed to or returned from DeflectionFunction.

CreatedRay
indicates that the Ray objects created by previous ray-tracing function calculations are passed to or returned from DeflectionFunction.

NewRay
designates that newly created Ray objects are returned from DeflectionFunction.

OriginalRay
signifies that the original incoming Ray object is passed to DeflectionFunction.

Definitions of object types used in AddTo, ReplaceFor, and TakeFrom.

9.4 EntranceCoordinates

Here is how EntranceCoordinates is used in PlanoConvexLens.

In[6]:=

EntranceCoordinates -> {{0., 0., 0.}, {10., 0., 0.}}

Out[6]=

Next we define EntranceCoordinates.

EntranceCoordinates gives the center coordinates of the first surface encountered within each confined migration pathway.

The slot position of the each EntranceCoordinates element corresponds with a slot position within ConfinedPaths. EntranceCoordinates is used in constructing UnconfinedPath.

EntranceCoordinates from PlanoConvexLens gives the center coordinates of the first and second lens surfaces. These center-coordinate values get used for calculating the order of the ray-tracing surfaces in the unconfined pathway. These values change as the component is moved to different locations in space. The unconfined pathway is discussed further in Sections 2.1 and 6.7.

9.5 ConfinedPaths

Here is how ConfinedPaths is used in PlanoConvexLens.

In[7]:=

ConfinedPaths ->
{
{    {SurfaceNumber -> 1, DeflectionNumber -> {1.}},
{SurfaceNumber -> 2, DeflectionNumber -> {1.}}}
,
{    {SurfaceNumber -> 2, DeflectionNumber -> {1.}},
{SurfaceNumber -> 1, DeflectionNumber -> {1.}}}
}

Out[7]=

Next we define ConfinedPaths.

ConfinedPaths specifies a nested list of rules defining the confined propagation behavior of a ray migrating through the component.

ConfinedPaths lists all of the confined migration pathways available for the impinging ray. ConfinedPaths contains lists including SurfaceNumber and DeflectionNumber rules. In this example, there are two possible migration paths through the planoconvex lens. These migration paths correspond to rays impinging the lens on either the planar side or the convex side. ConfinedPaths is also discussed in Section 2.1.

If a ray touches the surface designated by the first SurfaceNumber of a confined path, then the ray will continue migrating through the confined pathway. You can learn more about ray migration in Sections 2.1, 6.7, and 9.3.

SurfaceNumber is a rule of both Ray and Component denoting the slot positions being used within Surfaces of Component.

DeflectionNumber is also important to ConfinedPaths. DeflectionNumber indicates ray-tracing functions to be used at a ray/surface intersection. In the case of this example, one ray-tracing function is used.

DeflectionNumber indicates the slot positions of ray-tracing functions listed in Deflections.

DeflectionNumber indicates all ray-tracing functions used when a ray hits the given surface. Each ray-tracing function is called up in sequence by the order of its list position in DeflectionNumber.

9.6 RenderedSurfaces

Here is how RenderedSurfaces is used in PlanoConvexLens.

In[8]:=

RenderedSurfaces ->
{
{SurfaceNumber -> 1, RenderType -> Empty},
{SurfaceNumber -> 2, RenderType -> Empty},
{SurfaceNumber -> {1, 2}, RenderType -> Mesh}
}

Out[8]=

Next we define RenderedSurfaces.

RenderedSurfaces indicates a nested list of rules defining the graphical rendering of simple surfaces.

RenderedSurfaces contains lists made up of SurfaceNumber, HoleBoundary, and RenderType rules. The purpose of RenderedSurfaces is to direct the rendering of surfaces. Each list element within RenderedSurfaces contains SurfaceNumber and RenderType. When SurfaceNumber points to a single number, then the surface from the corresponding slot position of Surfaces is rendered. If SurfaceNumber points to a list of numbers, then the interconnecting surface between the boundaries of the indicated surfaces is rendered. RenderType indicates the type of rendering to be performed. RenderType points to a list containing one or more of the following rendering commands: Empty, Fill, Trace, and Mesh.

Empty indicates no rendering.

Fill indicates that the surface graphics should be filled with shaded areas.

Trace specifies that surfaces get rendered with outlined borders and no shading.

Mesh specifies that the surface graphics should be rendered with mesh outlines.

Rendering commands used by RenderType.

9.7 RenderedPolygons

Here is how RenderedPolygons is used in PlanoConvexLens.

In[9]:=

RenderedPolygons ->
{
{
{{SurfaceNumber -> 1, StartPoint -> {-25.,0}, FinishPoint -> {25.,0}},
{SurfaceNumber -> 2, StartPoint -> {25.,0}, FinishPoint -> {-25.,0}}}
,
{RenderType -> {Fill, Trace}}
}
,
{
{{SurfaceNumber -> 1, StartPoint -> {0,-25.}, FinishPoint -> {0,25.}},
{SurfaceNumber -> 2, StartPoint -> {0,25.}, FinishPoint -> {0,-25.}}}
,
{RenderType -> {Fill, Trace}}
}
}

Out[9]=

Next we define RenderedPolygons.

RenderedPolygons directs the rendering of one or more planes whose polygonal shapes are defined by connecting surfaces given by SurfaceNumber.

RenderedPolygons contains nested lists composed of SurfaceNumber, StartPoint, FinishPoint, and RenderType rules. Within RenderedPolygons, StartPoint and FinishPoint give the starting and finishing coordinates used within each edge-connecting surface. In the Component example highlighted in this chapter, two planar surfaces that form a crosshatched lens shape between the front and back planoconvex lens surfaces are defined. RenderType -> {Fill, Trace} indicates that these surfaces are rendered solid with darkened edges.

LensLab is a trademark of Optica Software.
Mathematica ® is a registered trademark of Wolfram Research, Inc. All other product names mentioned are trademarks of their producers. Mathematica is not associated with Mathematica Policy Research, Inc. or MathTech, Inc.