Optical Layout Example -- Twyman-Green Interferometer

Contents

Basic Example

% Use "sub-shapes" to specify parameters for the launch,
% the lenses, the beamsplitter, the mirrors, and the absorber,
% but do not draw anything yet.
LAUNCH   = davinci( 'optical_layout.beam_launch',  'Position',           [0 0], ...
                                                   'Direction',          [1 0], ...
                                                   'ConeAngle',             40, ...
                                                   'BeamLineWidth',          2 );
L1       = davinci( 'optical_layout.lens',         'LineWidth',              2 );
L2       = davinci( 'optical_layout.lens',         'DistanceToFocus',        4, ...
                                                   'LineWidth',              2 );
BS       = davinci( 'optical_layout.beamsplitter', 'LineWidth',              2 );
M1       = davinci( 'optical_layout.mirror',       'LineOrRectangle', 'rectangle', ...
                                                   'FaceVertexCData', [.3 .3 .3; .5 .5 .5; .3 .3 .3; .5 .5 .5], ...
                                                   'FaceColor',        'interp' );
M2       = M1;
ABSORBER = davinci( 'optical_layout.absorber',     'Thickness',              .6 );
% Assemble the first beam ("beam A").  Use the ">" operator to merge
% the "sub-shape" parameters with the travel distances.  Use the "/"
% operator to tilt the beamsplitter.  Do not draw anything yet.
BEAM_A = LAUNCH > 5 > L1 > 7 > (BS/-45) > 8 > M1;
% Draw the layout for beam path #1.  Attach data for retrieval by outside code.
[~,next_beam_launch] = davinci( 'optical_layout', 'Layout',                              BEAM_A, ...
                                                  'AttachDataForRetrievalByOutsideCode', true );
daspect([1 1 1])   % Set aspect ratio to 1:1.
% Draw the layout for beam path #2, which starts from the beamsplitter.
% Again attach data.
hold on
BEAM_B = next_beam_launch(1) > 8 > M2 > 15 > L2 > 6 > ABSORBER;
h_b = davinci( 'optical_layout', 'Layout',                              BEAM_B, ...
                                 'AttachDataForRetrievalByOutsideCode', true );
% The first segment on each "edge ray" is redundant.  The
% ray segments were drawn twice - once as the beam traveled up and
% once as the beam traveled down.  For purists, we delete the
% redundant segments, though this should not affect the drawing.
delete( h_b.edge_ray_1(1) );
delete( h_b.edge_ray_2(1) );
hold off

Retrieve the "appdata" davinci() attached to the axes object. Overlay arrows and circles onto the optical layout to illustrate the values of the position, axis_b, and axis_c parameters.

hold on
% Retrieve the "appdata" davinci() attached to the axes object.
ad = getappdata( gca, 'davinci' );
% For each optical component, draw:
%   -- a yellow circle at "position".
%   -- a red arrow extending from "position" in the direction
%      of the "c" axis.
%   -- a green arrow extending from "position" in the direction
%      of the "b" axis (except for the beam_launch, which does
%      not have a "b" axis).
components = ad.optical_layout.components;
for i = 1: length( components )
    this = components{i}';   % Note the '.
    this = struct( this{:} );
    position = this.position;  % For readability.
    % Draw a yellow circle at "position".
    davinci( 'rectangle', 'Position', position, 'Width', .6, 'Height', .6, 'CornerRadius', .3, 'Color', 'y', 'DrawMethod', 'patch', 'EdgeColor', 'k' )
    % Draw a red arrow in the direction of the "c" axis.
    arrow_args = { 'Shaft.Width', .2, ...
                   'Head.Width',  .8, ...
                   'Head.Length', .4, ...
                   'Head.Sweep',   0, ...
                   'EdgeColor',  'k' };
    davinci( 'arrow', 'X', [position(1) position(1)+this.axis_c(1)], ...
                      'Y', [position(2) position(2)+this.axis_c(2)], ...
                      arrow_args{:}, ...
                      'Color', 'r' );
    % Draw a green arrow in the direction of the "b" axis.
    if isfield(this,'axis_b')
        davinci( 'arrow', 'X', [position(1) position(1)+this.axis_b(1)], ...
                          'Y', [position(2) position(2)+this.axis_b(2)], ...
                          arrow_args{:}, ...
                          'Color', 'g' );
    end
end
hold off