Warning
There is an issue with the generation of documentation from notebooks, such as this page, that causes interactive plots generated using the Plot3D function to appear incorrect. The examples should produce correct 3D plots when executed directly in Jupyter Lab.
Binocular design¶
This example has been inspired by the book Fischer, Tadic-Galeb, Yoder. Optical system design. Second edition; chapter 22, p642 where the design of a binocular is studied. Although the book does not provide any specific optical component to be used in the design, it does provide guidelines on how to choose and locate the optical components.
The binocular proposed in the book is a binocular. It is recommended to use an achromatic doublet of 200mm of focal length and 50mm of diameter as an objective and a double Porro prism of SK5 glass. It is suggested to leave at least 40mm from the exit surface of the second prism to the image plane. A symmetrical eyepiece, composed of two achromatic doublets, is suggested. The suggested eyepiece focal length is f is 30mm.
The example is developed step by step. The binocular has been designed using pyOpTools predefined components and lenses from the Edmund Optics Inc catalogue.
[1]:
from pyoptools.all import *
from math import pi
[2]:
# Lenses choice: We look in the catalogue for the appropriate objective lens
L1=library.Edmund.get("45179") # f=200 r= 25
OA=Ray(pos=(0,0,-10000),dir=(0,0,1),wavelength=.55) # Optical axis
C=CCD(size=(10,10))
S=System(complist=[(L1,(0,0,100),(0,pi,0)), (C,(0,0,320.053),(0,0,0))],n=1)
PB=parallel_beam_c(origin=(0,0,50),direction=(0,0,0),size=(15,15),num_rays=(5,5),wavelength=.55)
S.ray_add(PB)
S.propagate()
display(Plot3D(S,center=(0,0,180),size=(250,70),scale=4,rot=[(0,pi/2,0)]))
f=(nearest_points(PB[7].get_final_rays()[0],PB[8].get_final_rays()[0])[0][2])-(find_ppp(S, OA)[2])
print(f)
/home/docs/checkouts/readthedocs.org/user_builds/pyoptools/envs/latest/lib/python3.7/site-packages/pyoptools-0.2.0-py3.7-linux-x86_64.egg/pyoptools/raytrace/library/library.py:159: DeprecationWarning: This method is deprecated, you can use dictionary-style accessinstead
DeprecationWarning,
/home/docs/checkouts/readthedocs.org/user_builds/pyoptools/envs/latest/lib/python3.7/site-packages/ipywidgets/widgets/widget.py:501: DeprecationWarning: Passing unrecognized arguments to super(MeshPhongMaterial).__init__(ambient='#050505').
object.__init__() takes exactly one argument (the instance to initialize)
This is deprecated in traitlets 4.2.This error will be raised in a future release of traitlets.
super().__init__(**kwargs)
nan
[3]:
#Placing the objective and the Porro prism
L1=library.Edmund.get("45179") #f=200 r= 25
RP1=RightAnglePrism(width=55,height=55,material=material.schott["N-SK5"])
RP2=RightAnglePrism(width=40,height=40,material=material.schott["N-SK5"])
CC=CCD(size=(50,50))
S=System(complist=[(L1,(0,0,100),(0,0,0)), (RP1,(0,-22.5,150),(pi,-pi/4,pi/2)), (RP2,(-20,-40,140),(0,pi/4,0)),
(CC,(-40,-46.41421356, 195.64187845),(0,0,0))],n=1)
PB=parallel_beam_c(origin=(0,0,0),direction=(0,0,0),size=(15,15),num_rays=(5,5),wavelength=.55)
S.ray_add(PB)
S.propagate()
display(Plot3D(S,center=(0,-30,140),size=(250,150),scale=5,rot=[(0,pi/2.,0),(pi/6,0,0)]))
# Calculating the coordinates of the paraxial focal point
nearest_points(PB[10].get_final_rays()[0],PB[15].get_final_rays()[0])
/home/docs/checkouts/readthedocs.org/user_builds/pyoptools/envs/latest/lib/python3.7/site-packages/pyoptools-0.2.0-py3.7-linux-x86_64.egg/pyoptools/raytrace/library/library.py:159: DeprecationWarning: This method is deprecated, you can use dictionary-style accessinstead
DeprecationWarning,
/home/docs/checkouts/readthedocs.org/user_builds/pyoptools/envs/latest/lib/python3.7/site-packages/ipywidgets/widgets/widget.py:501: DeprecationWarning: Passing unrecognized arguments to super(MeshPhongMaterial).__init__(ambient='#050505').
object.__init__() takes exactly one argument (the instance to initialize)
This is deprecated in traitlets 4.2.This error will be raised in a future release of traitlets.
super().__init__(**kwargs)
[3]:
(array([-40. , -45.00001128, 195.64006397]),
array([-40. , -45.00000001, 195.64006439]),
1.1281287765385155e-05,
False)
[4]:
# Looking for the right eyepiece configuration
L2=library.Edmund.get("45175") # f=30 ; r=10
CC=CCD(size=(50,50))
S=System(complist=[(L2,(0,0,89.84),(0,pi,0)), (L2,(0,0,100),(0,0,0)), (CC,(0,0,1.18656541e+02),(0,0,0))],n=1)
## The distance between the two doublets is equal to the total lense thickness
PB=parallel_beam_c(origin=(0,0,0),direction=(0,0,0),size=(10,10),num_rays=(5,5),wavelength=.55)
S.ray_add(PB)
S.propagate()
display(Plot3D(S,center=(0,0,90),size=(100,50),scale=5,rot=[(0,pi/2,0)]))
#Distance between the center of the lense and the paraxial focal point
nearest_points(PB[7].get_final_rays()[0],PB[8].get_final_rays()[0])
/home/docs/checkouts/readthedocs.org/user_builds/pyoptools/envs/latest/lib/python3.7/site-packages/pyoptools-0.2.0-py3.7-linux-x86_64.egg/pyoptools/raytrace/library/library.py:159: DeprecationWarning: This method is deprecated, you can use dictionary-style accessinstead
DeprecationWarning,
/home/docs/checkouts/readthedocs.org/user_builds/pyoptools/envs/latest/lib/python3.7/site-packages/ipywidgets/widgets/widget.py:501: DeprecationWarning: Passing unrecognized arguments to super(MeshPhongMaterial).__init__(ambient='#050505').
object.__init__() takes exactly one argument (the instance to initialize)
This is deprecated in traitlets 4.2.This error will be raised in a future release of traitlets.
super().__init__(**kwargs)
[4]:
(array([-3.34259427e-02, 0.00000000e+00, 1.13920118e+02]),
array([-4.23616191e-04, 4.23616191e-04, 1.13914704e+02]),
0.03344612357265831,
False)
[5]:
## Placing the eyepiece: Binocular 7x50
L1=library.Edmund.get("45179") #f=200 r= 25
L2=library.Edmund.get("45175") # f=30 ; r=10
RP1=RightAnglePrism(width=55,height=55,material=material.schott["N-SK5"])
RP2=RightAnglePrism(width=40,height=40,material=material.schott["N-SK5"])
CC=CCD(size=(50,50))
S=System(complist=[(L1,(0,0,100),(0,0,0)), (RP1,(0,-22.5,150),(pi,-pi/4,pi/2)), (RP2,(-20,-40,140),(0,pi/4,0)),
#(L2,(-40,-46.41421356,195.64187847+12.32427176),(0,pi,0)),
#(L2,(-40,-46.41421356,195.64187847+12.32427176+10.16),(0,0,0)),
(L2,(-40,-44.99,195.64187847+12.32427176),(0,pi,0)),
(L2,(-40,-44.99,195.64187847+12.32427176+10.16),(0,0,0)),
(CC,(-40,-44.99,260),(0,0,0))],n=1)
OA=Ray(pos=(0,0,100),dir=(0,0,10),intensity=100, wavelength=.55) # Optical axis
PB=parallel_beam_c(origin=(0,0,0),direction=(0,0,0),size=(15,15),num_rays=(5,5),wavelength=.55)
S.ray_add(OA)
S.ray_add(PB)
S.propagate()
%pylab inline
display(Plot3D(S,center=(0,-20,170),size=(250,130),scale=2,rot=[(0,pi/2.,0),(0,0,0)]))
figure()
spot_diagram_c(CC)
/home/docs/checkouts/readthedocs.org/user_builds/pyoptools/envs/latest/lib/python3.7/site-packages/pyoptools-0.2.0-py3.7-linux-x86_64.egg/pyoptools/raytrace/library/library.py:159: DeprecationWarning: This method is deprecated, you can use dictionary-style accessinstead
DeprecationWarning,
/home/docs/checkouts/readthedocs.org/user_builds/pyoptools/envs/latest/lib/python3.7/site-packages/pyoptools-0.2.0-py3.7-linux-x86_64.egg/pyoptools/raytrace/library/library.py:159: DeprecationWarning: This method is deprecated, you can use dictionary-style accessinstead
DeprecationWarning,
Populating the interactive namespace from numpy and matplotlib
/home/docs/checkouts/readthedocs.org/user_builds/pyoptools/envs/latest/lib/python3.7/site-packages/IPython/core/magics/pylab.py:160: UserWarning: pylab import has clobbered these variables: ['Polygon', 'cross', 'pi', 'f', 'unwrap', 'sqrt']
`%matplotlib` prevents importing * from pylab and numpy
"\n`%matplotlib` prevents importing * from pylab and numpy"
/home/docs/checkouts/readthedocs.org/user_builds/pyoptools/envs/latest/lib/python3.7/site-packages/ipywidgets/widgets/widget.py:501: DeprecationWarning: Passing unrecognized arguments to super(MeshPhongMaterial).__init__(ambient='#050505').
object.__init__() takes exactly one argument (the instance to initialize)
This is deprecated in traitlets 4.2.This error will be raised in a future release of traitlets.
super().__init__(**kwargs)
[ ]: