Example: Polarization state of light

Published 2009-08-04 | Author: Jeff Hein

This demonstrates the use of the fixed point calculation package fp.sty to process user-defined parameters while rendering a TikZ picture. In this example, a ellipse is rendered, representing the polarization state of light for an arbitrary x-amplitude y-amplitude, and relative phase. See http://en.wikipedia.org/wiki/Polarization for background information on polarization states of light.

In this example, a relatively simple command is called from within a tikzpicture environment:

\begin{tikzpicture}
    %usage:  \polellipse{ E_{0x} }{ E_{0y} }{ phase }
    \polellipse{3}{2}{45}
\end{tikzpicture}

The contents of the \polellipse command is rather lengthy, but can be broken down into two main parts. The first part performs the necessary math to convert the user-defined parameters E_{0x}, E_{0y}, and phase into values which are useful to the drawing process. The second part uses the calculated numbers to draw a coordinate axis, the ellipse, and appropriate annotation.

This example can be helpful when preparing a document describing various polarization states of light. The document can contain an arbitrary number of \polellipse commands, each with an arbitrary configuration of parameters. Each rendered figure is based on the same code, so a desired change to the style can update all figures.

This general technique can be applied to any TikZ figure, where the document calls any number of commands with some passed parameters, and some computation is be performed to render the diagrams.

Download as: [PDF] [TEX]  •  [Open in Overleaf]

Polarization state of light

Do you have a question regarding this example, TikZ or LaTeX in general? Just ask in the LaTeX Forum.
Oder frag auf Deutsch auf TeXwelt.de. En français: TeXnique.fr.

% Polarization state of light
% Author: Jeff Hein
\documentclass{article}

%========
%packages
%========
\usepackage{tikz}          %tikz graphics package for drawing with pgf
\usepackage{fp}            %for fixed point math
\usepackage{ifthen}      %for \ifthenelse{}{}{} conditional statements

%===================
%Style configuration
%===================
\pagestyle{empty}
\PreviewEnvironment{tikzpicture}
\setlength\PreviewBorder{2mm}

\usetikzlibrary{calc}

%line thickness styles:  ultra thin, very thin, (thin), semithick, thick, very thick, ultra thick
%line dash styles: loosely dashed, densely dashed, loosely dotted, densely dotted
\tikzset{bkgd_line/.style={very thin,color=gray}}
\tikzset{dashed_bkgd_line/.style={thin, dashed,color=gray}}

\tikzset{dimension_line/.style={very thin,color=gray}}
\tikzset{axis_line/.style={thin}}
\tikzset{object_line/.style={thick}}
\tikzset{textlabel/.style={color=red}}


%===================
%Command Definitions
%===================

%Command: polellipse
%
%parameters:
%
%1: x-axis magnitude
%2: y-axis magnitude
%3: phase between x-y components:  \phase = \delta_y - \delta_x
%
\newcommand{\polellipse}[3]{%
%
%NOTE:see http://spie.org/x32373.xml for some background on the math behind this calculation.
%
    \coordinate(origin) at (0,0);

%constants
\FPset{\LABELOFFSET}{.1}

%input parameters
%================

%\Eoy:  Electric field magnitude in the y-direction, (Eoy \geq 0)
\FPset{\Eoy}{#2}

%\Eox:  Electric field magnitude in the x-direction, (Eoy \geq 0)
\FPset{\Eox}{#1}

%\phase:  phase difference between E_y and E_x, in degrees   (\phase \leq 0 < 360)
\FPset{\phase}{#3}

\FPiflt{\phase}{0}
    \FPadd{\phase}{\phase}{360}
\else \fi


%\convert phase to radians
\FPmul{\phase}{\phase}{\FPpi}      %\phase = \phase * \PI
\FPdiv{\phase}{\phase}{180}        %\phase = \phase / 180

%Begin calculations, and reality check
%=====================================
\ifthenelse{\equal{\Eox}{0}}{%
    %error case: \Eox = \Eoy = 0
    \FPifzero{\Eoy}
        \errmessage{ELLIPSE PLOT ERROR: Both Eox and Eoy cannot be zero!}
    \else \fi
    
    %special case: \Eox = 0
    \FPdiv{\alp}{\FPpi}{2}          %\alp = \pi/2
}
{%
    %normal case, \Eox \neq 0
    \FPdiv{\scratch}{\Eoy}{\Eox}    %\scratch = \Eoy/\Eox
    \FParctan{\alp}{\scratch}       %\alp = \arctan{\scratch}
}

%normalize magnitudes, used for plotting
%=======================================

\FPpow{\scratchy}{\Eoy}{2}            %\scratchy = \Eoy^2
\FPpow{\scratchx}{\Eox}{2}            %\scratchx = \Eox^2
\FPadd{\scratch}{\scratchy}{\scratchx}%\scratch = \scratchy + \scratchx
\FProot{\norm}{\scratch}{2}           %\norm = \sqrt{\scratch}

\FPdiv{\Eoynorm}{\Eoy}{\norm}         %\Eoynorm = \Eoy / \norm
\FPdiv{\Eoxnorm}{\Eox}{\norm}         %\Eoynorm = \Eox / \norm

%determine major and minor axes
%==============================

\FPmul{\scratch}{\alp}{2}             %\scratch = \alp* 2
\FPsin{\sintwoalp}{\scratch}          %\alp = \sin\scratch

%\sin2\chi = \sin2\alp \sin\phase
\FPsin{\scratch}{\phase}              %\scratch = \sin\phase
\FPmul{\sintwochi}{\scratch}{\sintwoalp} %\sintwochi = \scratch * \sintwoalp

%solve for \tan\chi
\FParcsin{\scratch}{\sintwochi}      %\scratch = \arcsin{\sintwochi}
\FPdiv{\scratch}{\scratch}{2}        %\scratch = \scratch / 2
\FPtan{\tanchi}{\scratch}            %\tanchi = \tan{\scratch}

%if \tanchi is less than zero, the proceeding power operation will fail.
\FPabs{\tanchi}{\tanchi}

%\b = -\frac{\tanchi}{\sqrt{ 1 + \tanchi^2}}
\FPpow{\scratch}{\tanchi}{2}         %\scratch = \tanchi^2

\FPadd{\scratch}{\scratch}{1}        %\scratch = \scratch + 1
\FProot{\scratch}{\scratch}{2}       %\scratch = \sqrt{\scratch}
\FPdiv{\b}{\tanchi}{\scratch}        %\b = \tanchi / \scratch

%\a = \sqrt{1 - \b^2}
\FPpow{\scratch}{\b}{2}            %\scratch = \b^2
\FPsub{\scratch}{1}{\scratch}      %\scratch = 1 - \scratch
\FProot{\a}{\scratch}{2}           %\a = \sqrt{\scratch}


%determine orientation angle
%===========================

%\tantwoalp = \tan{2\alp}
\FPmul{\twoalp}{\alp}{2}      %\scratch = \alp * 2

%check for infinite tan!
\FPmul{\scratch}{\twoalp}{180}
\FPdiv{\scratch}{\scratch}{\FPpi}
\FPround{\scratch}{\scratch}{3}
\ifthenelse{\equal{\scratch}{90.000}}{%
    %special case: if \twoalp is 90 degrees, \tantwoalp will be infinite

    \FPset{\orang}{\alp}                %force \orang to \alp
}
{
    %regular case
    \FPtan{\tantwoalp}{\twoalp}      %\tantwoalp = \tan\scratch

    %\tantwopsi = \tantwoalp \cos\phase
    \FPcos{\scratch}{\phase}        %\scratch = \cos\phase
    \FPmul{\tantwopsi}{\tantwoalp}{\scratch} %\tantwopsi = \tantwoalp * \scratch
    \FParctan{\scratch}{\tantwopsi}        %\scratch = \arctan{\tantwopsi}
    \FPdiv{\orang}{\scratch}{2}        %\orang = \scratch / 2

    %assign proper quadrant:  if the orientation angle is less than zero, increase by 90 degrees
    \FPiflt{\orang}{0}
        \FPdiv{\scratch}{\FPpi}{2}
        \FPadd{\orang}{\orang}{\scratch}
    \else \fi
}

%convert \phase to degrees
\FPmul{\phase}{\phase}{180}
\FPdiv{\phase}{\phase}{\FPpi}
\FPround{\phase}{\phase}{1}

%convert \orang to degrees
\FPmul{\orang}{\orang}{180}
\FPdiv{\orang}{\orang}{\FPpi}

%final check on proper quadrant:  if \phase is between 90 and 270, increase orientation by 90 degrees
\FPset{\scratch}{0}
\FPifgt{\phase}{90.0}
    %if the first test passes, then prime the increment amount
    \FPset{\scratch}{90}
\else \fi
\FPiflt{\phase}{270}
    %if the second test passes, then increment by amount.  This will be zero if the first test didn't pass, and so we have a makeshift AND operation here!
    \FPadd{\orang}{\orang}{\scratch}    %add \pi/2 to orientation angle
\else \fi

%if Eox was zero to start with, just set orientation to 90 degrees
\FPifzero{\Eox}
    %special case: \Eox = 0
    \FPset{\orang}{90}          %\orang = 90 degrees
\else \fi

%determine perpendicular axis direction for rendering minor axis

%print output for testing
%\draw (0,-2in) node{\FPprint{\scratch}};
%\draw (0,-2in) node{$a$:\FPprint{\a}\quad\quad $b$:\FPprint{\b}\quad\quad orientation angle:\FPprint{\orang}};

    %define points for labels
    \begin{scope}[rotate around={\orang:(origin)}]
        \coordinate (a) at ($ (\a in, 0) + (\LABELOFFSET in,0) $);
        \coordinate (b) at ($ (0, \b in) + (0,\LABELOFFSET in)$);

        %determine arrow position and direction
        \coordinate (arrow1front) at ($ (0, \b in) $);
        \coordinate (arrow2front) at ($ (0, -\b in) $);
        \FPifgt{\phase}{180}
            \coordinate (arrow1back) at ($ (0, \b in) - .001*(\a in,0) $);
            \coordinate (arrow2back) at ($ (0, -\b in) + .001*(\a in,0) $);
        \else 
            \coordinate (arrow1back) at ($ (0, \b in) + .001*(\a in,0) $);
            \coordinate (arrow2back) at ($ (0, -\b in) - .001*(\a in,0) $);
        \fi
    \end{scope}

    %points for labels Eox, Eoy, \delta
    \coordinate (e) at ($ .5*(\Eoxnorm in,0) + (0,-\Eoynorm in) $);
    \coordinate (f) at ($ .5*(0,-\Eoynorm in) + (\Eoxnorm in,0) $);
    \coordinate (g) at ($ (-.2in,0) + (0,\Eoynorm in) $);

    %draw the x-y plane
    \draw[axis_line, ->] (-1.25in,0) -- (1.25in,0) node[textlabel,anchor=west]{$x$};
    \draw[axis_line, ->] (0,-1.25in) -- (0,1.25in) node[textlabel,anchor=south]{$y$};
    
    %draw the major and minor axis lines
    \draw[dimension_line,rotate=\orang] (-\a in,0) -- (\a in,0);
    \draw[dimension_line,rotate=\orang] (0, -\b in) -- (0, \b in);

    %draw the x-y amplitude bounding box
    \draw[dimension_line] (-\Eoxnorm in,-\Eoynorm in) rectangle (\Eoxnorm in,\Eoynorm in);

    %draw the ellipse and arrows showing the sense of rotation
    \draw[object_line,rotate=\orang,->] (0,0) ellipse (\a in and \b in);
    \draw[object_line,->] (arrow1back) -- (arrow1front);
    \draw[object_line,->] (arrow2back) -- (arrow2front);

    %label major-minor axes
    \FPifgt{\b}{.1}    %threshold for displaying major-minor axis labels
        \draw (a) node[textlabel]{$a$}; %=\a);  %uncomment and merge if you want to display the major axis size.  Maybe do a \FPround{\a}{\a}{1} beforehand!
        \draw (b) node[textlabel]{$b$}; %=\b);  %uncomment and merge if you want to display the minor axis size.  Maybe do a \FPround{\b}{\b}{1} beforehand!
    \else \fi

    %label the x-y components and delta
    \draw (e) node[textlabel,anchor=north]{$E_{0x} = \Eox$};
    \draw (f) node[textlabel,anchor=north west]{$E_{0y} = \Eoy$};
    \draw (g) node[textlabel,anchor=south east]{$\delta = \phase^\circ$};

    %label orinetation angle
    \FPifgt{\orang}{1}    %threshold for displaying orientation angle
        \draw[dimension_line] (.3in, 0) arc (0:\orang:.3in);
        \FPdiv{\scratch}{\orang}{2}    %scratch = ema/2
        \draw[rotate=\scratch] (.5in,0) node[textlabel]{$\psi$};
    \else \fi
}
%end ellipse command


%=============
%main document
%=============

\begin{document}

%\section*{Background}  %to render this, remove the preview environment
%
%\subsubsection*{Electric Field Vectors}
%
%\begin{align}\begin{split}
%  E_x(t) &= E_{0x}\cos(\omega t)\\
%  E_y(t) &= E_{0y}\cos(\omega t + \delta)\\
%  \vec{E}(t) &= E_x(t)\hat{x} + E_y(t)\hat{y}
%\end{split}\end{align}

%For further information about polarization states of light and calculating the polarization ellipse, see your favorite optics book!

\begin{tikzpicture}
    %usage:  \polellipse{ E0x }{ E0y }{ phase }
    \polellipse{3}{2}{45}
\end{tikzpicture}

%alternative example:
%uncomment the following block and remove the preview environment from the beginning of the document

%polarization ellipse figures
%  \foreach \i in {1,3,5,9}
%  {
%    \foreach \j in {-40,-20,0,30,60,140}
%    {
%      \begin{tikzpicture}[scale=.25]
%        %\polellipse{ E_{0x} }{ E_{0y} }{ \delta }
%        \polellipse{4}{\i}{\j}
%      \end{tikzpicture} 
%    }
    %newline for proper formatting!
%  \\
%  }


\end{document}

Comments

  • #1 AML, August 5, 2009 at 7:48 p.m.

    Good work.

    Being rather ignorant of the technical aspects, was there a specific reason to use FP instead of PGFmath?

  • #2 Jeff Hein, August 5, 2009 at 9:14 p.m.

    Actually, I had only recently heard of the fixed point math capabilities withing pgf, and will be looking the possibility of rebuilding this example using the internal library.

  • #3 Kjell Magne Fauske, August 5, 2009 at 9:28 p.m.

    Could you have used the mathematical engine already bundled with PGF 2.0, or is it not accurate enough?

  • #4 Brandy, January 21, 2013 at 5 p.m.

    Thanks for the marvelous posting! I actually enjoyed reading it, you are a great author.I will remember to bookmark your blog and definitely will come back sometime soon. I want to encourage one to continue your great job, have a nice afternoon!

Adding comments is currently not enabled.