%%
%% This is file `pst-optexp.tex',
%%
%% IMPORTANT NOTICE:
%%
%% Package `pst-optexp.tex'
%%
%% Christoph Bersch <usenet _at_ bersch.net>
%%
%% This program can be redistributed and/or modified under the terms
%% of the LaTeX Project Public License Distributed from CTAN archives
%% in directory CTAN:/macros/latex/base/lppl.txt.
%%
%% DESCRIPTION:
%%   `pst-optexp' is a PSTricks package to draw optical experimental setups
%%
\csname PSToptexpLoaded\endcsname
\let\PSToptexpLoaded\endinput
%
%
\def\fileversion{1.0}
\def\filedate{2007/07/18}
\message{`pst-optexp' v\fileversion, \filedate\space (CB)}
%
% DPC interface to the `keyval' package (until keyval based version of PSTricks)
%
\edef\PstAtCode{\the\catcode`\@} \catcode`\@=11\relax
\pst@addfams{optexp}
\SpecialCoor
%
% In some versions of pstricks-add previous to 2.81 the macro
% \nlput is buggy. In these cases it is redefined here.
\ifdim\pstricksaddfileversion pt<2.81pt
\typeout{}
\typeout{pst-optexp: please update pstricks-add to version >= 2.81}
\typeout{}
\def\psLDNode(#1)(#2)#3#4{%
% #1: node A  #2: node B  #3: dimen measured from A  #4: node name
  \pst@getcoor{#1}\pst@tempA%
  \pst@getcoor{#2}\pst@tempB%
  \pssetlength\pst@dimp{#3}%
  \pnode(!%
    \pst@tempA /YA exch \pst@number\psyunit div def
    /XA exch \pst@number\psxunit div def
    \pst@tempB /YB exch \pst@number\psyunit div def
    /XB exch \pst@number\psxunit div def
    /dx XB XA sub def
    /dy YB YA sub def
    /angle dy dx Atan def
    /linelength \pst@number\pst@dimp \pst@number\psunit div def
    XA linelength angle cos mul add YA linelength angle sin mul add ){#4}%
}
\def\nlput{\pst@object{nlput}}
\def\nlput@i(#1)(#2)#3#4{%
  \begin@SpecialObj
  \psLDNode(#1)(#2){#3}{temp@lnput}
  \pcline[linestyle=none](#1)(temp@lnput)%
  \ncput[npos=1]{#4}%
  \end@SpecialObj
}%
\fi
% IF's
%
\newif\ifPst@optexp@variable
\newif\ifPst@optexp@crystal@voltage
\newif\ifPst@optexp@crystal@caxisinv
\newif\ifPst@optexp@reverse
\newif\ifPst@optexp@crystal@lamp
\newif\ifPst@optexp@component@optional
\newif\ifPst@optexp@debug@showoptdots
\newif\ifPst@optexp@endbox
\newif\ifPst@optexp@labelrelative
%
% Strings
\def\pst@string@pol@polperp{perp}
\def\pst@string@pol@polparallel{parallel}
\def\pst@string@pol@polmisc{misc}
\def\pst@string@pol@polrcirc{rcirc}
\def\pst@string@pol@pollcirc{lcirc}
\def\pst@string@mirror@type@piezo{piezo}
\def\pst@string@mirror@type@plain{plain}
\def\pst@string@mirror@type@extended{extended}
%
\def\pst@string@lens@type@plainconvex{plainconvex}
\def\pst@string@lens@type@convexplain{convexplain}
\def\pst@string@lens@type@biconvex{biconvex}
\def\pst@string@lens@type@plainconcave{plainconcave}
\def\pst@string@lens@type@concaveplain{concaveplain}
\def\pst@string@lens@type@biconcave{biconcave}
%
\newpsstyle{OptionalStyle}{linestyle=dotted}
\newpsstyle{ExtendedMirror}{linestyle=none,%
                hatchwidth=0.5\psk@optexp@mirror@linewidth,%0.6pt,%
                hatchsep=1.4\psk@optexp@mirror@linewidth,%
                fillstyle=hlines}
\newpsstyle{PiezoMirror}{fillstyle=solid,fillcolor=black!30}
%
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% Parameterdefinitions
%
% General
\define@key[psset]{optexp}{optional}[true]{\@nameuse{Pst@optexp@component@optional#1}}
\define@key[psset]{optexp}{position}{\edef\psk@optexp@position{#1}}
\define@key[psset]{optexp}{abspos}{\edef\psk@optexp@abspos{#1}}
\define@key[psset]{optexp}{angle}{\edef\psk@optexp@angle{#1}}
\define@key[psset]{optexp}{reverse}[true]{\@nameuse{Pst@optexp@reverse#1}}
%
% Lens
\define@key[psset]{optexp}{lensheight}{\edef\psk@optexp@lens@height{#1}}
\define@key[psset]{optexp}{lenswidth}{\edef\psk@optexp@lens@width{#1}}
\define@key[psset]{optexp}{lensradius}{\edef\psk@optexp@lens@radius{#1}}
% Lens Type
% 0 -> plainconvex
% 1 -> convexplain
% 2 -> biconvex
% 3 -> plainconcave
% 4 -> concaveplain
% 5 -> biconcave
%
\define@key[psset]{optexp}{lenstype}{%
  \def\pst@tempA{#1}
  \edef\psk@optexp@lens@type{%
    \ifx\pst@string@lens@type@plainconvex\pst@tempA 0\else
    \ifx\pst@string@lens@type@convexplain\pst@tempA 1\else
    \ifx\pst@string@lens@type@biconvex\pst@tempA 2\else
    \ifx\pst@string@lens@type@plainconcave\pst@tempA 3\else
    \ifx\pst@string@lens@type@concaveplain\pst@tempA 4\else
    \ifx\pst@string@lens@type@biconcave\pst@tempA 5%
    \fi\fi\fi\fi\fi\fi%
}}
%
% Pinhole
\define@key[psset]{optexp}{iwidth}{\edef\psk@optexp@pinhole@iwidth{#1}}
\define@key[psset]{optexp}{owidth}{\edef\psk@optexp@pinhole@owidth{#1}}
\define@key[psset]{optexp}{phlinewidth}{\edef\psk@optexp@pinhole@linewidth{#1}}
%
% Beamsplitter
\define@key[psset]{optexp}{bswidth}{\edef\psk@optexp@bswidth{#1}}
%
% Crystal
\define@key[psset]{optexp}{crystalwidth}{\edef\psk@optexp@crystal@width{#1}}
\define@key[psset]{optexp}{crystalheight}{\edef\psk@optexp@crystal@height{#1}}
\define@key[psset]{optexp}{caxislength}{\edef\psk@optexp@crystal@caxislength{#1}}
\define@key[psset]{optexp}{voltage}[true]{\@nameuse{Pst@optexp@crystal@voltage#1}}
\define@key[psset]{optexp}{caxisinv}[true]{\@nameuse{Pst@optexp@crystal@caxisinv#1}}
\define@key[psset]{optexp}{lamp}[true]{\@nameuse{Pst@optexp@crystal@lamp#1}}
\define@key[psset]{optexp}{lampscale}{\def\psk@optexp@lamp@scale{#1}}
%
% Mirror
\define@key[psset]{optexp}{mirrorwidth}{\edef\psk@optexp@mirror@width{#1}}
\define@key[psset]{optexp}{mirrorlinewidth}{\edef\psk@optexp@mirror@linewidth{#1}}
\define@key[psset]{optexp}{mirrortype}{\edef\psk@optexp@mirror@type{#1}}% piezo, extended, plain
\define@key[psset]{optexp}{mirrordepth}{\edef\psk@optexp@mirror@depth{#1}}
\define@key[psset]{optexp}{variable}[true]{\@nameuse{Pst@optexp@variable#1}}
%
% Grid
\define@key[psset]{optexp}{optgridcount}{\edef\psk@optexp@optgrid@count{#1}}
\define@key[psset]{optexp}{optgridwidth}{\edef\psk@optexp@optgrid@width{#1}}
\define@key[psset]{optexp}{optgridheight}{\edef\psk@optexp@optgrid@height{#1}}
\define@key[psset]{optexp}{optgriddepth}{\edef\psk@optexp@optgrid@depth{#1}}
\define@key[psset]{optexp}{optgridlinewidth}{\edef\psk@optexp@optgrid@linewidth{#1}}
%
% Box
\define@key[psset]{optexp}{optboxwidth}{\edef\psk@optexp@optbox@width{#1}}
\define@key[psset]{optexp}{optboxheight}{\edef\psk@optexp@optbox@height{#1}}
\define@key[psset]{optexp}{endbox}[true]{\@nameuse{Pst@optexp@endbox#1}}
%
% Plate
\define@key[psset]{optexp}{platelinewidth}{\edef\psk@optexp@plate@linewidth{#1}}
\define@key[psset]{optexp}{plateheight}{\edef\psk@optexp@plate@height{#1}}
%
% Optical Retardation Plate
\define@key[psset]{optexp}{platewidth}{\edef\psk@optexp@plate@width{#1}}
%
% Detector
\define@key[psset]{optexp}{detsize}{\edef\psk@optexp@detector@size{#1}}
%
% Polarisation
\define@key[psset]{optexp}{polwidth}{\edef\psk@optexp@polarisation@width{#1}}
\define@key[psset]{optexp}{pollinewidth}{\edef\psk@optexp@polarisation@linewidth{#1}}
\define@key[psset]{optexp}{pol}{\edef\psk@optexp@pol{#1}}
%
% Label
\define@key[psset]{optexp}{labelangle}{\edef\psk@optexp@label@angle{#1}}
\define@key[psset]{optexp}{labeloffset}{\edef\psk@optexp@label@offset{#1}}
\define@key[psset]{optexp}{labelstyle}{\def\psk@optexp@label@style{#1}}
\define@key[psset]{optexp}{labelalign}{\def\psk@optexp@label@align{#1}}
\define@key[psset]{optexp}{labelrelative}[true]{\@nameuse{Pst@optexp@labelrelative#1}}
%
% Debug
\define@key[psset]{optexp}{showoptdots}[true]{\@nameuse{Pst@optexp@debug@showoptdots#1}}
%
%
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% Makros
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\def\lens{\@ifnextchar[{\pst@lens}{\pst@lens[]}}
\def\pinhole{\@ifnextchar[{\pst@pinhole}{\pst@pinhole[]}}
\def\beamsplitter{\@ifnextchar[{\pst@beamsplitter}{\pst@beamsplitter[]}}
\def\crystal{\@ifnextchar[{\pst@crystal}{\pst@crystal[]}}
\def\optgrid{\@ifnextchar[{\pst@optgrid}{\pst@optgrid[]}}
\def\mirror{\@ifnextchar[{\pst@mirror}{\pst@mirror[]}}
\def\polarisation{\@ifnextchar[{\pst@polarisation}{\pst@polarisation[]}}
\def\optbox{\@ifnextchar[{\pst@optbox}{\pst@optbox[]}}
\def\optplate{\@ifnextchar[{\pst@optplate}{\pst@optplate[]}}
\def\optretplate{\@ifnextchar[{\pst@optretplate}{\pst@optretplate[]}}
\def\detector{\@ifnextchar[{\pst@detector}{\pst@detector[]}}
\def\optdipole{\@ifnextchar[{\pst@optdipole}{\pst@optdipole[]}}
\def\opttripole{\@ifnextchar[{\pst@opttripole}{\pst@opttripole[]}}
%
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% default settings
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\psset{%
        angle=0
        ,lenswidth=0.2
        ,lensheight=1
        ,lenstype=biconvex
        ,mirrorwidth=1
        ,mirrordepth=0.08
        ,pol=\pst@string@pol@polparallel
        ,optgridcount=10
        ,optgridwidth=1
        ,optgridheight=0.1
        ,optgriddepth=0.05
        ,bswidth=1
        ,owidth=1
        ,iwidth=0.1
        ,crystalwidth=2
        ,crystalheight=0.8
        ,caxislength=0.6
        ,optboxwidth=1
        ,optboxheight=0.5
        ,position=\@empty
        ,abspos=\@empty
        ,labeloffset=1
        ,labelangle=-90
        ,labelstyle=\small
        ,mirrortype=\pst@string@mirror@type@plain,
        ,labelalign=c
        ,lensradius=\@empty
        ,mirrorlinewidth=2\pslinewidth
        ,plateheight=1
        ,platelinewidth=2\pslinewidth
        ,platewidth=0.1
        ,polwidth=0.6
        ,pollinewidth=0.7\pslinewidth
        ,optgridlinewidth=0.7\pslinewidth
        ,phlinewidth=2\pslinewidth
        ,lampscale=0.3
        ,detsize=0.5
}%
%
%
%
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% 
% Macro implementations
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
%   Some of the components need three points to be positioned. 
%   These are:
%
%       1. startpoint of the beam (in the PS-Code: (XA,YA))
%       2. reflectionpoint on the surface (XG, YG)
%       3. endpoint (XB,YB)
%
%  With these three points \pst@calcNodes calculates two new points 'tempNode@A' 
%  and 'tempNode@B', between which the component is placed by the macro 
%  \pst@draw@component in the way, that 'angle of incidence' == 'angle of deflection'
%  regarding the reflection surface (mirror, diagonal of the beamsplitter, 
%  grid etc.)
% 
\def\pst@calcNodes#1#2#3{{%
  \pst@getcoor{#1}\pst@tempa%
  \pst@getcoor{#2}\pst@tempb%
  \pst@getcoor{#3}\pst@tempc%
  \pnode(!%
        \pst@tempa /YA exch \pst@number\psyunit div def
        /XA exch \pst@number\psxunit div def
        \pst@tempb /YG exch \pst@number\psyunit div def
        /XG exch \pst@number\psxunit div def
        \pst@tempc /YB exch \pst@number\psyunit div def
        /XB exch \pst@number\psxunit div def
        /ax XG XA sub def
        /ay YG YA sub def
        /bx XB XG sub def
        /by YB YG sub def
        /a ax 2 exp ay 2 exp add sqrt def
        /b bx 2 exp by 2 exp add sqrt def
        /cx ax a div bx b div add def
        /cy ay a div by b div add def
        /c cx 2 exp cy 2 exp add sqrt def
        %
        % if c=0, then set the coordinates of the vector manually
        % depending on the dotproduct (and thus, if 'a' and 'b'
        % are parallel or antiparallel
        c 0 eq
          {/dotprod ax bx mul ay by mul add def
           dotprod 0 gt
             % if dotprod > 0 then a and b are parallel
             {/cx ax def
              /cy ay def}
             % else a and b are antiparallel
             {/cx ay def
              /cy ax neg def} ifelse
           /c a def
          }if
        /X@A XG cx c div add def
        /Y@A YG cy c div add def
        /X@B XG cx c div sub def
        /Y@B YG cy c div sub def
        %
        % chirality:
        % test the order of the input points as a input angle > 90°
        % doesn't really make sens.
        % So if 'chir' <= 0 exchange the calculated coordinates of 
        % A and B and otherwise leave it as is
        /chir ax by mul ay bx mul sub def
        chir 0 le
          {/XAtmp X@A def
           /YAtmp Y@A def       
           /X@A X@B def
           /Y@A Y@B def
           /X@B XAtmp def
           /Y@B YAtmp def}if
        X@A Y@A){tempNode@A}%
  \pnode(! X@B Y@B){tempNode@B}%
}\ignorespaces}%
%
%
% If a macro requests only two points, they are equivalent to 
% 'tempNode@A' and 'tempNode@B'. But for easier implementation of other 
% macros the given points are assigned to the temporary nodes. In 
% addition \pst@regNodes defines the x- and the y-coordinate of the two
% inputpoints (XA,YA) (XB,YB) in PS-Code
%
%
\def\pst@regNodes#1#2{{%
    \pnode(#1){tempNode@A}
    \pnode(#2){tempNode@B}
}\ignorespaces}%
%
%
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% COMPONENT WRAPPERS
%
\def\pst@lens[#1](#2)(#3)#4{{%
   \pst@regNodes{#2}{#3}%
   \pst@draw@component{#1}{#4}\pst@draw@lens%
}\ignorespaces}%
%
%
%
\def\pst@pinhole[#1](#2)(#3)#4{{%
   \pst@regNodes{#2}{#3}%
   \pst@draw@component{#1}{#4}\pst@draw@pinhole%
}\ignorespaces}%
%
%
%
\def\pst@mirror[#1](#2)(#3)(#4)#5{{%
    \pst@calcNodes{#2}{#3}{#4}%
    \pst@draw@component{#1}{#5}\pst@draw@mirror%
}\ignorespaces}%
%
%
%
\def\pst@optgrid[#1](#2)(#3)(#4)#5{{%
    \pst@calcNodes{#2}{#3}{#4}%
    \pst@draw@component{#1}{#5}\pst@draw@optgrid%
}\ignorespaces}%
%
%
%
\def\pst@beamsplitter[#1](#2)(#3)(#4)#5{{%
    \pst@calcNodes{#2}{#3}{#4}%
    \pst@draw@component{#1}{#5}\pst@draw@beamsplitter%
}\ignorespaces}%
%
%
%
\def\pst@crystal[#1](#2)(#3)#4{{%
    \pst@regNodes{#2}{#3}%
    \pst@draw@component{#1}{#4}\pst@draw@crystal%
}\ignorespaces}%
%
%
%
\def\pst@optbox[#1](#2)(#3)#4{{%
    \pst@regNodes{#2}{#3}%
    \psset{labeloffset=0}%
    \pst@draw@component{#1}{#4}\pst@draw@optbox%
}\ignorespaces}%
%
%
%
\def\pst@optplate[#1](#2)(#3)#4{{%
    \pst@regNodes{#2}{#3}%
    \pst@draw@component{#1}{#4}\pst@draw@optplate%
}\ignorespaces}%
%
%
%
\def\pst@optretplate[#1](#2)(#3)#4{{%
    \pst@regNodes{#2}{#3}%
    \pst@draw@component{#1}{#4}\pst@draw@optretplate%
}\ignorespaces}%
%
%
%
\def\pst@detector[#1](#2)(#3)#4{{%
    \pst@regNodes{#2}{#3}%
    \psset{endbox}
    \pst@draw@component{#1}{#4}\pst@draw@detector%
}\ignorespaces}%
%
%
%
\def\pst@polarisation[#1](#2)(#3){{%
    \pst@regNodes{#2}{#3}%
    \pst@draw@component{#1}{}\pst@draw@polarisation%
}\ignorespaces}%
%
%
%
\def\pst@optdipole[#1](#2)(#3)#4#5{{%
    \pst@regNodes{#2}{#3}%
    \pst@draw@component{#1}{#5}{\pnode(0,0){tempNode@Label}#4}%
}\ignorespaces}%
%
%
%
\def\pst@opttripole[#1](#2)(#3)(#4)#5#6{{%
    \pst@calcNodes{#2}{#3}{#4}%
    \pst@draw@component{#1}{#6}{\pnode(0,0){tempNode@Label}#5}%
}\ignorespaces}%
%
%
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% DRAW COMPONENTS
%
% This macro is called by every unit
%
\def\pst@draw@component#1#2#3{{%
    \psset{labelsep=1}%
    \psset{#1}%
%
    \ifPst@optexp@endbox%
       \psset{position=1}%
    \fi%
%
% linestyle to use, if component should be marked as optional
    \ifPst@optexp@component@optional
      \psset{style=OptionalStyle}
    \fi
    \ncline[linestyle=none,fillstyle=none,npos=]{tempNode@A}{tempNode@B}%
%
% if parameter 'position' is given, use it for 'npos'
    \ifx\psk@optexp@position\@empty
%
% then check if absolute positioning is wanted
        \ifx\psk@optexp@abspos\@empty
            \ncput[nrot=:U,npos=]{#3}
        \else
            \nlput[nrot=:U](tempNode@A)(tempNode@B){\psk@optexp@abspos}{#3}
        \fi
    \else
        \ncput[nrot=:U,npos=\psk@optexp@position]{#3}
    \fi
    \ifPst@optexp@labelrelative
       \ncline[linestyle=none]{tempNode@A}{tempNode@Label}
       \ncput[nrot=:U,npos=1]{\rput[\psk@optexp@label@align](0,0){\psk@optexp@label@style #2}}%
    \else
       \nput[labelsep=\psk@optexp@label@offset]%
           {\psk@optexp@label@angle}%
           {tempNode@Label}%
           {\rput[\psk@optexp@label@align](0,0){\psk@optexp@label@style #2}}%
    \fi
%
% Show dots for debugging
    \ifPst@optexp@debug@showoptdots
        \psdot[linecolor=red](tempNode@Label)
        \psdot[linecolor=black](tempNode@A)
        \psdot[linecolor=black](tempNode@B)
    \fi
}\ignorespaces}%
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% MIRROR
%
\def\pst@draw@mirror{{%
   \pstVerb{%
      /m@width \psk@optexp@mirror@width\space def
   }
   \ifPst@optexp@variable
      \psarc[linewidth=0.8\pslinewidth,arrowinset=0,arrowscale=0.8]{<->}
            (! m@width 2 div 0.4 sub 0){0.6}{-20}{20}
      \psarc[linewidth=0.8\pslinewidth,arrowinset=0,arrowscale=0.8]{<->}
            (! m@width 2 div 0.4 sub neg 0){0.6}{160}{200}
     \fi
     \psline[linewidth=\psk@optexp@mirror@linewidth](! m@width -2 div 0)(! m@width 2 div 0)
%
% piezo
     \ifx\psk@optexp@mirror@type\pst@string@mirror@type@piezo%
        \psframe[style=PiezoMirror](! m@width 8 div 0)(! m@width -8 div m@width 5 div)
        \psbezier(! 0 m@width 5 div)%
                 (! 0 m@width 3 div)%
                 (! m@width 4 div m@width 4 div)%
                 (! m@width 8 div m@width 2 div)%
     \fi
     \ifx\psk@optexp@mirror@type\pst@string@mirror@type@extended%
       \psframe[style=ExtendedMirror]%
          (! m@width -2 div \psk@optexp@mirror@depth\space )%
          (! m@width 2 div 0)%
     \fi
%
% labelnode
     \pnode(0,0){tempNode@Label}
}\ignorespaces}%
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% LENS
%
\def\pst@draw@lens{{%
%
  \pstVerb{%
    /lens@h \psk@optexp@lens@height\space 2.0 div def
  }%
  % 
  \ifnum\psk@optexp@lens@type<3
  %
  % CONVEX
  % 
  % Use only parameters 'lenswidth' and 'lensheight' to draw the lens, if 'lensradius'
  % is not set
  % 
  \ifx\psk@optexp@lens@radius\@empty
    \pstVerb{%
      /lens@a  \psk@optexp@lens@width\space 2.0 div def
      /lens@r lens@a 2.0 div lens@h lens@h mul 2.0 lens@a mul div add def
    }%
    % 
    % otherwise use 'lensradius' and 'lensheight'
    % 
  \else
    \pstVerb{%
      /lens@r \psk@optexp@lens@radius\space def
      /lens@a lens@r lens@r 2 exp lens@h 2 exp sub sqrt sub def
    }%
  \fi%
  % 
  % draw the lens
  % 
  \pstVerb{%
    /lens@d lens@r lens@a sub def
    /lens@alpha lens@h lens@d atan def
    /lens@yshift lens@d def
  }%    
  \else
  %
  % CONCAVE
  %
  % All three parameters 'lensheight', 'lenswidth' and 'lensradius' are needed
  \pstVerb{%
    /lens@a \psk@optexp@lens@width\space 2.0 div def
  }%
  \ifx\psk@optexp@lens@radius\@empty
    \pstVerb{%
      /lens@r lens@h 1.5 mul def
    }%
  \else
    \pstVerb{%
      /lens@r \psk@optexp@lens@radius\space def
    }%
  \fi%
  %
  %
  %
  \pstVerb{%
    /lens@d lens@r dup mul lens@h dup mul sub sqrt def
    /lens@alpha lens@h lens@d atan def
    /lens@yshift lens@r lens@a add def
  }%
  \fi%
  % 
  %
  \def\temp@LeftPlot{%
     \parametricplot[plotstyle=curve,arrows=c-c]{-1}{1}{%   
        lens@r lens@alpha t mul 180 add cos mul lens@yshift add lens@r lens@alpha t mul 180 add sin mul}%
  }%
  \def\temp@RightPlot{%
     \parametricplot[plotstyle=curve,arrows=c-c]{-1}{1}{%  
        lens@r lens@alpha t mul cos mul lens@yshift sub lens@r lens@alpha t mul sin mul}%
  }%      
  %
  %
  \pscustom{%
  \ifcase\psk@optexp@lens@type
  % plainconvex
    \temp@RightPlot%
    \closepath%
  \or%
  % convexplain
    \temp@LeftPlot%
    \closepath%
  \or%
  % biconvex
    \temp@LeftPlot%
    \temp@RightPlot%
  \or%
  % plainconcave
  \temp@LeftPlot%
  \psline{c-c}(! 0 lens@h neg)%
         (! 0 lens@h)%
         (! lens@r lens@d sub lens@a add lens@h)%
  \or%
  % concaveplain
  \temp@RightPlot%
  \psline{c-c}(! 0 lens@h)%
         (! 0 lens@h neg)%
         (! lens@r lens@d sub lens@a add neg lens@h neg)%
  \or%
  % biconcave
  \temp@RightPlot%
  \psline{c-c}(! lens@r lens@d sub lens@a add lens@h)%
  \temp@LeftPlot%
  \psline{c-c}(! lens@r lens@d sub lens@a add neg lens@h neg)%
  \fi%
  }
%
% labelnode
  \pnode(0,0){tempNode@Label}
}\ignorespaces}%
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% PINHOLE
%
\def\pst@draw@pinhole{{%
  \psline[linewidth=\psk@optexp@pinhole@linewidth]%
         (! 0 \psk@optexp@pinhole@owidth\space 2 div)%
         (! 0 \psk@optexp@pinhole@iwidth\space 2 div)%
  \psline[linewidth=\psk@optexp@pinhole@linewidth]%
         (! 0 \psk@optexp@pinhole@owidth\space -2 div)%
         (! 0 \psk@optexp@pinhole@iwidth\space -2 div)%
%
% labelnode
  \pnode(0,0){tempNode@Label}
}\ignorespaces}
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% BEAMSPLITTER
%
\def\pst@draw@beamsplitter{{%
   \pstVerb{%
      /bs@width \psk@optexp@bswidth\space 2.0 div def
   }%
   \psline{cc-cc}(! bs@width neg 2 sqrt mul 0)%
                 (! bs@width 2 sqrt mul 0)
   \rput[c]{45}(0,0){\psframe(! bs@width neg bs@width neg)(! bs@width bs@width)}
%
% labelnode
  \pnode(0,0){tempNode@Label}
}\ignorespaces}%
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% CRYSTAL
%
\def\pst@draw@crystal{{%
  \rput[c]{\psk@optexp@angle}(0,0){%
     \pstVerb{%
        /c@width \psk@optexp@crystal@width\space 2 div def 
        /c@height \psk@optexp@crystal@height\space 2 div def
        /c@caxisL \psk@optexp@crystal@caxislength\space 2 div def}%
     \psframe(! c@width neg c@height neg)(! c@width c@height)
     \ifPst@optexp@crystal@voltage%
        \psline(! c@width 4 div 3 mul neg c@height)%
               (! c@width 4 div 3 mul neg c@height 0.2 add)
        \pscircle[fillstyle=solid,%
                  fillcolor=white](! c@width 4 div 3 mul neg c@height 0.2 add){0.04}
        \psline(! c@width 4 div 3 mul neg c@height neg)%
               (! c@width 4 div 3 mul neg c@height neg 0.2 sub)%
        \psline(! c@width 4 div 3 mul neg 0.15 sub c@height neg 0.2 sub)%
               (! c@width 4 div 3 mul neg 0.15 add c@height neg 0.2 sub)%
     \fi
%
     \ifPst@optexp@crystal@lamp
        \rput{180}(! c@width c@height 1.4 \psk@optexp@lamp@scale\space mul add){\lamp}%
     \fi
     \ifPst@optexp@crystal@caxisinv
        \psline[linestyle=dashed,%
                dash=2pt 2pt,%
                linewidth=0.7\pslinewidth,%
                arrowinset=0]{->}%
               (! 0 c@height neg)(! 0 c@height c@caxisL add)%
     \else
        \psline[linestyle=dashed,%
                dash=2pt 2pt,%
                linewidth=0.7\pslinewidth,%
                arrowinset=0]{->}%
           (! 0 c@height)(! 0 c@height neg c@caxisL sub)%
     \fi
  }%
%
% labelnode
  \pnode(0,0){tempNode@Label}
}\ignorespaces}%
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% POLARISATION
%
%
\def\pst@draw@polarisation{{%
%
  \ifx\psk@optexp@pol\pst@string@pol@polparallel
     \psline[linestyle=solid,linewidth=\psk@optexp@polarisation@linewidth,arrowscale=0.8]{<->}%
        (! 0 \psk@optexp@polarisation@width\space 2 div neg)%
        (! 0 \psk@optexp@polarisation@width\space 2 div)%
  \fi
  \ifx\psk@optexp@pol\pst@string@pol@polperp
     \psdot[dotsize=0.05](0,0)%
     \pscircle[fillstyle=none,linestyle=solid,linewidth=\psk@optexp@polarisation@linewidth](0,0){0.12}%
  \fi
  \ifx\psk@optexp@pol\pst@string@pol@polmisc
     \psline[linestyle=solid,linewidth=\psk@optexp@polarisation@linewidth,arrowscale=0.8]{<->}%
        (! 0 \psk@optexp@polarisation@width\space 2 div neg)%
        (! 0 \psk@optexp@polarisation@width\space 2 div)%
     \psdot[dotsize=0.05](0,0)%
     \pscircle[fillstyle=none,linestyle=solid,linewidth=0.7\pslinewidth](0,0){0.12}
  \fi
  \ifx\psk@optexp@pol\pst@string@pol@polrcirc
     \psellipticarc[linewidth=\psk@optexp@polarisation@linewidth]{->}(0,0)(!
     \psk@optexp@polarisation@width\space 4 div
     \psk@optexp@polarisation@width\space 2 div)%
     {20}{-20}
  \fi
  \ifx\psk@optexp@pol\pst@string@pol@pollcirc
     \psellipticarc[linewidth=\psk@optexp@polarisation@linewidth]{<-}(0,0)(!
     \psk@optexp@polarisation@width\space 4 div
     \psk@optexp@polarisation@width\space 2 div)%
     {20}{-20}
  \fi
}\ignorespaces}%
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% OPTICAL GRID
%
\def\pst@draw@optgrid{{%
  \pstVerb{%
     /g@count \psk@optexp@optgrid@count\space def
     /g@width \psk@optexp@optgrid@width\space 2 div def
     /g@height \psk@optexp@optgrid@height\space def
     /g@depth \psk@optexp@optgrid@depth\space def
     /g@step g@width 2 mul g@count div def}%
  \ifPst@optexp@reverse%
     \pscustom[linewidth=\psk@optexp@optgrid@linewidth]{%
        \psline(! g@width g@depth)(! g@width g@height)%
               (! g@width neg g@height)(! g@width neg g@depth)
        \multido{\i=0+1}{\psk@optexp@optgrid@count}{%
           \psline{cc-cc}(! g@width neg \i\space g@step mul add g@depth)%
                         (! g@width neg \i\space g@step mul add 0)%
                         (! g@width neg \i\space 1 add g@step mul add g@depth)%
        }
     }%
  \else%   
     \pscustom[linewidth=\psk@optexp@optgrid@linewidth]{%
        \psline(! g@width g@depth)(! g@width g@height)%
               (! g@width neg g@height)(! g@width neg g@depth)
        \multido{\i=0+1}{\psk@optexp@optgrid@count}{%
           \psline{cc-cc}(! g@width neg \i\space g@step mul add g@depth)%
                         (! g@width neg \i\space 1 add g@step mul add 0)%
                         (! g@width neg \i\space 1 add g@step mul add g@depth)%
        }
     }%
  \fi%
%
% labelnode
  \pnode(0,0){tempNode@Label}
}\ignorespaces}%
%
% OPTBOX
%
\def\pst@draw@optbox{{%
    \ifPst@optexp@endbox
    \pnode(!%
        /box@width \psk@optexp@optbox@width\space def
        /box@height \psk@optexp@optbox@height\space def
        box@width 2 div 0){tempNode@Label}%
    \psframe(! 0 box@height 2 div neg)%
            (! box@width box@height 2 div)%
    \else
        \pnode(!%
        /box@width \psk@optexp@optbox@width\space def
        /box@height \psk@optexp@optbox@height\space def
        0 0){tempNode@Label}%
    \rput{\psk@optexp@angle}(0,0){%
        \psframe(! box@width 2 div neg box@height 2 div neg)%
                (! box@width 2 div box@height 2 div)%
    }%
    \fi
}\ignorespaces}%
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% OPTPLATE
%
\def\pst@draw@optplate{{%
  \psline[linewidth=\psk@optexp@plate@linewidth]%
        (! 0 \psk@optexp@plate@height\space 2 div neg)%
        (! 0 \psk@optexp@plate@height\space 2 div)
%
% labelnode
  \pnode(0,0){tempNode@Label}
}\ignorespaces}%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% DETECTOR
%
\def\pst@draw@detector{{%
    \pnode(! \psk@optexp@detector@size\space 3 div 0){tempNode@Label}%
    \pswedge(0,0){\psk@optexp@detector@size}{-90}{90}
}\ignorespaces}%
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% OPTRETPLATE
%
\def\pst@draw@optretplate{{%
   \pstVerb{%
     /orp@height \psk@optexp@plate@height\space 2.0 div def
     /orp@width \psk@optexp@plate@width\space 2.0 div def
   }%
   \psframe(! orp@width neg orp@height neg)(! orp@width orp@height)
   \psline{cc-cc}(! orp@width neg orp@height)%
                 (! orp@width orp@height neg)
%
% labelnode
  \pnode(0,0){tempNode@Label}
}\ignorespaces}%
%
%
%
\def\lamp{{%
  \psset{linewidth=0.6\pslinewidth}
  \pstVerb{/l@s \psk@optexp@lamp@scale\space def}
%
  \pscurve[fillstyle=none](! -0.05 l@s mul 0)%
          (! -0.1 l@s mul 0.15 l@s mul)%
          (! -0.2 l@s mul 0.25 l@s mul)%
          (! -0.25 l@s mul 0.5 l@s mul)%
          (! 0 0.7 l@s mul)%
          (! 0.25 l@s mul 0.5 l@s mul)%
          (! 0.2 l@s mul 0.25 l@s mul)%
          (! 0.1 l@s mul 0.15 l@s mul)%
          (! 0.05 l@s mul 0)
  \multido{\i=-210+40}{7}{%
    \rput{\i}(! 0 0.45 l@s mul){\psline(! -0.35 l@s mul 0)(! -0.6 l@s mul 0)}
  }
}\ignorespaces}
%
%
\endinput
%
