mjhoptics / ray-optics

geometric ray tracing for optical systems
BSD 3-Clause "New" or "Revised" License
263 stars 54 forks source link

Wedge or mirror ? #96

Closed khoroshyy closed 1 year ago

khoroshyy commented 1 year ago

Hi. Can I use wedged window, angled mirror or off axis beam? Thanks. Petro.

mjhoptics commented 1 year ago

Hello Petro, Yes, you can specify any of these things. The ray trace is fully 3D. The lens picture capability will not draw fully 3D systems correctly however. If the model is bi-laterally symmetric, e.g. all tilts and decenters are in the y-z plane, then the lens picture should look OK. Hope this helps Mike

khoroshyy commented 1 year ago

Hello Petro, Yes, you can specify any of these things. The ray trace is fully 3D. The lens picture capability will not draw fully 3D systems correctly however. If the model is bi-laterally symmetric, e.g. all tilts and decenters are in the y-z plane, then the lens picture should look OK. Hope this helps Mike

Thanks. Could you show me an example of two mirror periscope? I cannot grasp how to put in flat mirror. Thanks. Petro.

mjhoptics commented 1 year ago

Here's an example with a lens and 2 tilted mirrors. Let me know if you have further questions. Mike

from rayoptics.environment import *

# Create a new model
opm = OpticalModel()
sm  = opm['seq_model']
osp = opm['optical_spec']
pm = opm['parax_model']
em = opm['ele_model']
pt = opm['part_tree']
ar = opm['analysis_results']

### Define first order aperture and field for system
pupil_diameter = 40.
pupil_radius = pupil_diameter/2
osp.pupil = PupilSpec(osp, key=['object', 'pupil'], value=pupil_diameter)
# single field on-axis
osp.field_of_view = FieldSpec(osp, key=['object', 'angle'], flds=[0.0])
# wavelength for analysis: 550nm
osp.spectral_region = WvlSpec([(550.0, 1.0)], ref_wl=0)

### object at infinity, i.e. collimated input
sm.gaps[0].thi = 1e+11

### Add a lens for focusing
sm.add_surface([0.004, 5, 'N-BK7', 'Schott', 20.])
sm.add_surface([-0.004, 25])

### add 2 fold mirrors to form the periscope
### The 'bend' type of decenter is used. This is designed to make
### entry of fold mirrors easy. "Borrowed" from CODE V's Decenter and Bend capability
sm.add_surface([0.0, -80., 'REFL', 20.])
sm.ifcs[sm.cur_surface].decenter = srf.DecenterData('bend', alpha=45.)
sm.add_surface([0., 135.25, 'REFL', 20.])
sm.ifcs[sm.cur_surface].decenter = srf.DecenterData('bend', alpha=-45.)

### all of the system data has been entered, update the model
opm.update_model()

### sequential mode list including decenter data
sm.list_sg()

# # Draw a lens picture
layout_plt = plt.figure(FigureClass=InteractiveLayout, opt_model=opm, do_draw_rays=True).plot()

Periscope

khoroshyy commented 1 year ago

Thanks a lot. Exactly what I wanted. If I may ask the last question? How can I specify a cylindrical lens? Thanks. Petro.

mjhoptics commented 1 year ago

You can use the YToroid or XToroid surface profiles, with a 0.0 sweep curvature. For instance, to make a y cylindrical plano-convex lens, you would enter:

from rayoptics.elem.profiles import YToroid

sm.add_surface([0.008, 5, 'N-BK7,Schott', 20.])
sm.ifcs[sm.cur_surface].profile = YToroid(0.008)

sm.add_surface([0.0, 25])

Note that if you need a profile in the XZ plane, it will ray-trace correctly, but there isn't a way of showing it in a lens picture.

Mike

khoroshyy commented 1 year ago

Thanks again for the explanation.