<html><head><meta name="color-scheme" content="light dark"></head><body><pre style="word-wrap: break-word; white-space: pre-wrap;">% \iffalse meta-comment
%
% Copyright (C) 2015 Daan Leijen
% -------------------------------------------------------
% 
% This file may be distributed and/or modified under the
% conditions of the LaTeX Project Public License, either version 1.2
% of this license or (at your option) any later version.
% The latest version of this license is in:
%
%    http://www.latex-project.org/lppl.txt
%
% and version 1.2 or later is part of all distributions of LaTeX 
% version 1999/12/01 or later.
%
% \fi
%
% \iffalse
%&lt;*driver&gt;
\ProvidesFile{ellipse.dtx}
%&lt;/driver&gt;
%&lt;package&gt;\NeedsTeXFormat{LaTeX2e}[1999/12/01]
%&lt;package&gt;\ProvidesPackage{ellipse}
%&lt;*package&gt;
    [2004/11/05 v1.0 .dtx ellipse file]
%&lt;/package&gt;
%&lt;package&gt;\RequirePackage{pict2e}
%
%&lt;*driver&gt;
\documentclass{ltxdoc}
\usepackage{graphicx}
\usepackage{ellipse}[2004/11/05]
\usepackage{amsmath}
\usepackage{amssymb}
\usepackage{hyperref}
\usepackage{lmodern}
\usepackage{xcolor}
\usepackage{wrapfig}
\newcommand\kk[1]{\iota_{#1}}
\newcommand\sk[1]{\rho_{#1}}
\newcommand\sint[1]{\textit{sint}_{#1}}
\newcommand\cost[1]{\textit{cost}_{#1}}
\newcommand\sign[1]{\pm_{#1}}
\newcommand\csqrt{\textit{csqrt}}
\renewcommand\cos{\textit{cos}}\renewcommand\sin{\textit{sin}}
\renewcommand\arctan{\textit{arctan}}\renewcommand\tan{\textit{tan}}
\renewcommand\max{\textit{max}}\renewcommand\sin{\textit{sin}}
\providecolor{teal}{HTML}{008080}
\providecolor{purple}{HTML}{800080}
\providecolor{navy}{HTML}{000080}
\providecolor{maroon}{HTML}{800000}
\providecolor{floralwhite}{HTML}{FFFAF0}
\providecolor{ivory}{HTML}{FFFFF0}
\providecolor{white}{HTML}{FFFFFF}
\providecolor{transparent}{named}{white}
\providecolor{gainsboro}{HTML}{DCDCDC}
\hypersetup{colorlinks=true,citecolor=navy,linkcolor=navy,urlcolor=navy,filecolor=navy,bookmarksdepth=3,bookmarksopenlevel=1}
\makeatletter
\DeclareRobustCommand*\package[2][]{%
  \def\@tempa{#1}%
  \ifx\@tempa\@empty
    \textsf{#2}%
  \else
    \href{http://mirrors.ctan.org/macros/latex/#1}{\textsf{#2}}%
  \fi
}%
\DeclareRobustCommand*\pkgpicte{\package[contrib/pict2e/pict2e.pdf]{pict2e}}
\newsavebox{\@ebox}
\newcommand*\@unit[1]{\strip@pt\dimexpr#1\relax}%
\newcommand*\ellipbox[1]{%
  \begingroup
  \savebox{\@ebox}{#1}%
  \setlength{\unitlength}{1pt}%
  \hspace*{0.8ex}%
  \begin{picture}(0,0)%
   \put(\@unit{0.5\wd\@ebox},\@unit{0.5\ht\@ebox - 0.5\dp\@ebox}){%
     \ellipse{\@unit{0.8ex + 0.5\wd\@ebox}}{\@unit{0.8ex + 0.5\ht\@ebox}}%
  }%
  \end{picture}%
  \usebox{\@ebox}%
  \hspace{0.8ex}%
  \endgroup%
}
\makeatother
\EnableCrossrefs         
\CodelineIndex
\RecordChanges
\begin{document}
  \setlength\emergencystretch{3em}  
  \DocInput{ellipse.dtx}
  \PrintChanges
  \setcounter{IndexColumns}{2}%
  \PrintIndex
\end{document}
%&lt;/driver&gt;
% \fi
%
% \CheckSum{0}
%
% \CharacterTable
%  {Upper-case    \A\B\C\D\E\F\G\H\I\J\K\L\M\N\O\P\Q\R\S\T\U\V\W\X\Y\Z
%   Lower-case    \a\b\c\d\e\f\g\h\i\j\k\l\m\n\o\p\q\r\s\t\u\v\w\x\y\z
%   Digits        \0\1\2\3\4\5\6\7\8\9
%   Exclamation   \!     Double quote  \"     Hash (number) \#
%   Dollar        \$     Percent       \%     Ampersand     \&amp;
%   Acute accent  \'     Left paren    \(     Right paren   \)
%   Asterisk      \*     Plus          \+     Comma         \,
%   Minus         \-     Point         \.     Solidus       \/
%   Colon         \:     Semicolon     \;     Less than     \&lt;
%   Equals        \=     Greater than  \&gt;     Question mark \?
%   Commercial at \@     Left bracket  \[     Backslash     \\
%   Right bracket \]     Circumflex    \^     Underscore    \_
%   Grave accent  \`     Left brace    \{     Vertical bar  \|
%   Right brace   \}     Tilde         \~}
%
%
% \changes{v1.0}{2015/03/24}{Initial version}
%
% \GetFileInfo{ellipse.dtx}
%
% \DoNotIndex{\newcommand,\renewcommand,\newenvironment,\renewenvironment}
% \DoNotIndex{\providecommand,\def,\edef,\let,\gdef,\xdef,\global,\newtoks}
% \DoNotIndex{\RequirePackage,\DeclareOption,\ProcessOptions,\ExecuteOptions}
% \DoNotIndex{\input,\InputIfFileExists}
% \DoNotIndex{\@ifdefinable,\@ifundefined,\@percentchar}
% \DoNotIndex{\AtBeginDocument,\AtEndOfPackage}
% \DoNotIndex{\PackageError,\PackageWarning,\PackageWarningNoLine,\PackageInfo}
% \DoNotIndex{\MessageBreak,\typeout}
%
% \DoNotIndex{\z@,\z@skip,\p@,\@ne,\tw@,\thr@@,\@iv,\two@fourteen,\strip@pt}
% \DoNotIndex{\the,\if,\else,\or,\fi,\ifnum,\ifdim,\ifcase,\ifodd}
% \DoNotIndex{\advance,\multiply,\divide}
% \DoNotIndex{\@tfor,\do}
% \DoNotIndex{\csname,\endcsname,\begingroup,\endgroup}
% \DoNotIndex{\expandafter,\afterassignment,\noexpand}
% \DoNotIndex{\@ovxx,\@ovyy,\@ovdx,\@ovdy}
% \DoNotIndex{\undefined,\dimexpr,\relax,\space,\protect,\begin}
% \DoNotIndex{\@tempdima,\@tempdimb,\@tempdimc,\@tempdimd,\dimen@,\@tempa}
% \DoNotIndex{\@tempswafalse,\@tempswatrue,\if@tempswa,\iffalse,\ifx,\ignorespaces}
%
% \title{The {\linethickness{0.6pt}\ellipbox{\textsf{ellipse}}} package}
% \author{Daan Leijen \\ \texttt{daan@microsoft.com}}
%
% \maketitle
%  
% \newcommand\pictexample[1]{%
%   \setlength{\unitlength}{10pt}%
%   \raisebox{-30pt}{\begin{picture}(6,8)%
%   \linethickness{0.4pt}\roundjoin%
%   \color{gainsboro}%
%   \put(0,0){\multiput(0,0)(1,0){9}{\line(0,1){6}}%
%    \multiput(0,0)(0,1){7}{\line(1,0){8}}%  
%   }%
%   \put(0,0){\color{gray}%
%     {\vector(1,0){8}}\put(-0.5,6.5){$y$}%
%     {\vector(0,1){6}}\put(8.5,-0.5){$x$}%
%   }%
%   \color{black}%
%   \linethickness{0.8pt}%
%   #1\end{picture}}%
% } 
% 
% \section{Introduction}
%
% \LaTeX{} has many advanced graphics packages now, the most extensive are 
% \href{https://www.ctan.org/pkg/pgf}{\textsf{tikz}}
% and \href{https://www.ctan.org/pkg/pstricks-base}{\textsf{pstricks}}.
% However, these are also large packages that take long to load and
% may not always work on all drivers. The standard \pkgpicte{} package removes many of the previous
% limitations of the `old' \LaTeX{} |picture| environment and makes it a \emph{lean
% and portable} alternative to the more full featured packages. However, even though it can
% draw circles and circle arcs well, it lacks the ability to draw ellipses and elliptical
% arcs. This package adds these functions on top of the standard \pkgpicte{} primitives 
% (i.e. the |\cbezier| command).
%
% \section{Drawing ellipses}
%
% \noindent
% \DescribeMacro\ellipse
% \DescribeMacro{\ellipse*}
% \marg{x-radius}\marg{y-radius}\\
% \strut\\
% These commands draw an ellipse with the specified radi\"\i. The |\ellipse| command draws
% a stroked ellipse with the current |\linethickness| while |\ellipse*| draws a filled
% ellipse with the current |\color|. For example:
%
% \noindent\begin{minipage}{0.7\linewidth}%
% \begin{verbatim}
% \setlength{\unitlength}{10pt}%
% \begin{picture}(6,8)
%   \linethickness{0.8pt}%
%   \put(6,3){\color{teal}\ellipse*{2}{3}}%
%   \put(3,3){\color{blue}\ellipse{3}{2}}%
% \end{picture}
% \end{verbatim}\end{minipage}
% \pictexample{%
%   \put(6,3){\color{teal}\ellipse*{2}{3}}%
%   \put(3,3){\color{blue}\ellipse{3}{2}}%
% }\\[2ex]
%
% \noindent
% \DescribeMacro\earc
% \DescribeMacro{\earc*}
% \oarg{start-angle$\rangle$|,|$\langle$end-angle}\marg{x-radius}\marg{y-radius}\\
% \strut\\
% These commands draw part of an ellipse with the specified radi\"\i. 
% The |\earc| command draws
% a stroked elliptical arc with the current |\linethickness| while |\earc*| draws a filled
% elliptical `pie slice' with the current |\color|. The optional argument specifies a start and 
% end-angle in degrees which must be between $-720$ and $720$ (but can be fractional).
% The endings of the arcs are determined by the \emph{cap} setting: |\buttcap| (default),
% |\roundcap| (add half disc), or |\squarecap| (add half square).
%
% \noindent\begin{minipage}{0.7\linewidth}%
% \begin{verbatim}
% \put(3,3){%
%   \color{blue}\roundcap\earc[135,330]{3}{2}}%
% \put(6,3){%
%   \color{teal}\earc*[-45,90]{2}{3}}%
% \end{verbatim}
% \end{minipage}
% \pictexample{%
%   \put(3,3){\color{blue}\roundcap\earc[135,330]{3}{2}}%
%   \put(6,3){\color{teal}\earc*[-45,90]{2}{3}}%
% }\\[2ex]
%
% \noindent
% \DescribeMacro\elliparc
% \oarg{initial}\marg{center-x}\marg{center-y}\marg{x-rad}\marg{y-rad}\marg{start-angle}\marg{end-angle}\\
%
% \noindent The core elliptical arc routine. These are to be used with path commands, like
% |\lineto|, |\moveto|, |\strokepath|, etc, and can draw an elliptical arc at any center point. 
% The optional argument specifies the initial drawing
% action: the default is $0$ (|\lineto|) which draws a line to the arc starting point,
% the value $1$
% (|\moveto|) just moves to the starting point, and $2$ does nothing as an initial action. 
% If the start angle is larger than the end angle, the arc is drawn clockwise, and otherwise
% anti-clockwise.\\[1ex]
%
% \noindent\begin{minipage}{0.7\linewidth}%
% \begin{verbatim}
% \elliparc[1]{3}{3}{3}{2}{90}{270}%
% \elliparc{5}{3}{2}{2}{-90}{90}%
% \closepath\strokepath
% \color{teal}%
% \moveto(1,3)
% \elliparc{3}{3}{2}{1}{-135}{135}%
% \closepath
% \fillpath
% \end{verbatim}\end{minipage}
% \pictexample{%
%   \elliparc[1]{3}{3}{3}{2}{90}{270}%
%   \elliparc{5}{3}{2}{2}{-90}{90}%
%   \closepath\strokepath
%   \color{teal}%
%   \moveto(1,3)
%   \elliparc{3}{3}{2}{1}{-135}{135}%
%   \closepath
%   \fillpath
% }\\[2ex]
%
% \noindent Note how the two initial arcs are automatically connected by a line
% segment from $(3,1)$ to $(5,1)$ (due to the default optional argument of $0$ that
% uses a |\lineto| command to the starting point of the arc). Similarly, we use
% such initial line segment and a |\closepath| to draw the triangular side of the
% inner ellipse.
%
% \subsection{Rotated ellipses}
%
% There is no direct command to rotate an ellipse but you can use the
% standard |\rotatebox| command from the \package[required/graphics/grfguide.pdf]{graphicx} package. For example:
%
% \noindent\begin{minipage}{0.7\linewidth}%
% \begin{verbatim}
% \put(3,3){%
%   \rotatebox[origin=c]{45}{\ellipse{3}{2}}%
% }%
% \end{verbatim}\end{minipage}
% \pictexample{%
% \put(3,3){\rotatebox[origin=c]{45}{\ellipse{3}{2}}%
% }%
% }\\[2ex]
%
% \subsection{Using the picture environment inline}
%
% The standard \LaTeX{} |picture| environment is nowadays quite
% powerful and convenient. Read the latest \pkgpicte{} documentation
% and ``The unknown \emph{picture} environment'' \cite{picture} for more information. 
% One particularly nice feature is that we
% can create a picture as |\begin{picture}(0,0)| to give it zero
% space. This can be used for example to define an |\ellipbox| command
% like:\\[1ex]
%
% \noindent\begin{minipage}{0.6\linewidth}%
% \begin{verbatim}
% Boxed numbers: 
%   \ellipbox{1}, \ellipbox{123}.  
% \end{verbatim}
% \end{minipage}
% \begin{minipage}{0.38\linewidth}%
% Boxed numbers: \ellipbox{1}, \ellipbox{123}.
% \end{minipage}\\[1ex]
%
% \noindent We also used this command to draw the ellipse in the title
% of this article, and it is defined as:
% \begin{verbatim}
%\newsavebox{\@ebox}
%\newcommand*\@unit[1]{\strip@pt\dimexpr#1\relax}%
%\newcommand*\ellipbox[1]{%
%  \begingroup
%  \savebox{\@ebox}{#1}%
%  \setlength{\unitlength}{1pt}%
%  \hspace*{0.8ex}%
%  \begin{picture}(0,0)%
%   \put(\@unit{0.5\wd\@ebox},\@unit{0.5\ht\@ebox - 0.5\dp\@ebox}){%
%     \ellipse{\@unit{0.8ex + 0.5\wd\@ebox}}{\@unit{0.8ex + 0.5\ht\@ebox}}%
%  }%
%  \end{picture}%
%  \usebox{\@ebox}\hspace{0.25ex}\endgroup}
% \end{verbatim}
% \noindent This is not the best code possible but it hopefully gives you a good
% idea on how to implement your own boxes. Note the use of the |\@unit| macro
% to convert dimensions to units, which is also why we need to set the |\unitlength|
% to |1pt| here.
%
% \StopEventually{}
%
% \begin{thebibliography}{9}
% \raggedright
%
% \bibitem{abst} M.~Abramowitz and I.A.~Stegun: \textit{Handbook of Mathematical Functions},
%  \url{people.math.sfu.ca/~cbm/aands}, 1964
%
% \bibitem{picture} Claudio Beccari: \emph{The unknown \emph{picture} environment},
%   TUGBoat, vol. 33(1), 2012. \url{tug.org/TUGboat/tb33-1/tb103becc-picture.pdf}
%
% \bibitem{ellipse} Luc Maisonobe: \textit{Drawing an elliptical arc using polylines, quadratic or cubic B\'ezier lines.}
%    \url{www.spaceroots.org/documents/ellipse/elliptical-arc.pdf}, 2003
%
% \bibitem{rajan:atan} S.~Rajan, Sichun Wang, R.~Inkol, and A.~Joyal: \textit{Efficient approximations for the arctangent function}. 
%  In Signal Processing Magazine, vol. 23(3), pages 108--111, May 2006
%
% \end{thebibliography}
%
% \clearpage
%
% \newcommand\abs[1]{\lvert #1\rvert}
% \newcommand\rarg[1]{$\langle$\textit{#1}$\rangle$}
% \newcommand\xellipse{\mathcal{E}}
%
% \section{Elliptical arcs as B\'ezier curves}
% \begin{figure}\begin{center}
% \setlength\unitlength{18pt}
% \begin{picture}(12,9)(-1.5,-0.5)%
%   \linethickness{0.4pt}\roundjoin%
%   \iffalse
%    \color{gainsboro}%
%    \put(0,0){%
%      \multiput(-2,-1)(1,0){13}{\line(0,1){9}}%
%      \multiput(-2,-1)(0,1){10}{\line(1,0){12}}%
%    }%
%   \fi
%   \color{black}%
%   \put(0,0){%
%     \put(0,-0.5){\vector(0,1){8}}\put(8.5,-0.5){$x$}%
%     \put(-1.5,0){\vector(1,0){11}}\put(-0.5,6.5){$y$}%
%   }%
%   \put(4,3.3){\color{navy}\earc{5}{3}
%     \put(3,-2){$\xellipse$}%%  
%     \color{teal}%
%     \put(-5.5,0){\line(1,0){11}}%
%     \put(0,-3.5){\line(0,1){8}}%
%     \put(3,0){\vector(-1,0){3}\vector(1,0){2}\raisebox{0.3ex}{$a$}}%
%     \put(0,-1.5){\vector(0,1){1.5}\vector(0,-1){1.5}$\,b$}%
%     \color{maroon}%
%     \put(0,0){\moveto(0,0)\elliparc{0}{0}{5}{3}{30}{120}\closepath\strokepath}%
%     {\linethickness{2pt}\earc[30,120]{5}{3}}%
%     \put(3.7,2.2){$p_1$}\put(-2,3.1){$p_2$}%
%     \put(2.25,2.92){\moveto(0,0)\lineto(1.35,-0.84)\strokepath\circle*{0.1}$\;q_1$}%
%     \put(-0.075,3.22){\moveto(0,0)\lineto(-1.56,-0.39)\strokepath\circle*{0.1}$\,q_2$}%
%     \color{black}
%     \linethickness{0.2pt}\arc[0,30]{1}\arc[0,120]{2}%
%     \put(1,0.2){$\alpha_1$}\put(1,1.8){$\alpha_2$}%
%   }%
%   \color{navy}\put(4,-0.3){$\,c_x$}\put(0,2.9){$\,c_y$}%
%   %
% \end{picture}\end{center}
% \caption{Approximating an elliptical arc with a cubic B\'ezier curve. The center of the ellipse
%  is at $(c_x,c_y)$ with a horizontal radius of $a$ and a vertical one $b$. The elliptical arc goes
%  from $\alpha_1$ to $\alpha_2$ and is approximated with a thick red cubic B\'ezier curve. The curve
%  starts at $p_1$ and ends in $p_2$ with two control points $q_1$ and $q_2$. The curve was drawn
%  using the command \texttt{\textbackslash{}elliparc\{4\}\{3.3\}\{5\}\{3\}\{30\}\{120\}}.}
% \label{fig:ellipse}
% \end{figure}
% \begin{figure}
% \setlength\unitlength{20pt}\begin{center}
% \begin{picture}(12,8)(-1.5,-0.5)%
%   \linethickness{0.4pt}\roundjoin%
%   \iffalse
%   \put(0,0){\color{gainsboro}%
%     \multiput(-2,-1)(1,0){13}{\line(0,1){8}}%
%     \multiput(-2,-1)(0,1){9}{\line(1,0){12}}%
%   }%
%   \fi
%   \put(4,3){\color{navy}\earc{5}{3}\put(-4,1){$\xellipse$}\color{teal}%
%     \put(-5.5,0){\line(1,0){11}}%
%     \put(0,-3.5){\line(0,1){7}}%
%     \put(-2,0){\vector(-1,0){3}\vector(1,0){2}\raisebox{0.3ex}{$a$}}%
%     \put(0,-1.5){\vector(0,1){1.5}\vector(0,-1){1.5}$\,b$}%
%     \color{black}%
%     \put(0,0){\circle{6}}%
%     \put(0,0){\vector(3.6,2.08){3.6}\vector(2.16,2.08){2.16}}%
%     \put(0,0){\color{maroon}%
%      \put(3.6,0){\line(0,1){2.08}\circle*{0.1}}%
%      \put(3.2,-0.5){$a\cos(t_1)$}%
%      \put(2.16,0){\line(0,1){2.08}\circle*{0.1}}%
%      \put(1.3,-0.5){$\cos(t_1)$}%
%     }%
%     \linethickness{0.2pt}\arc[0,30]{1}\arc[0,43.9]{2}%
%     \put(1,0.2){$\alpha_1$}\put(1.65,1.25){$t_1$}%
%   }%
%   %
% \end{picture}\end{center}
% \caption{The relation between the parametric angle $t_1$ and the angle $\alpha_1$ to the point on the ellipse.
%   All points on the ellipse are defined by the parametric equation $\xellipse(t) = (c_x + a\cdot\cos(t), c_y + b\cdot\sin(t))$}
% \label{fig:parametric}
% \end{figure}
% %
% %
% Drawing an ellipse or part of an ellipse (\emph{elliptical arc}) using B\'ezier
% curves requires some math to determine the right control points of the B\'ezier curve.
% Figure~\ref{fig:ellipse} establishes some notation. We do not consider rotated
% ellipses here and always use $a$ for the $x$-radius and $b$ for the $y$-radius.
% We are interested in finding the B\'ezier curve between the $\alpha_1$ and
% $\alpha_2$ angles, which implies finding the starting 
% point $p_1$, the end point $p_2$ and the control points $q_1$ and $q_2$. 
%
% Each point on an ellipse is determined by the following parametric equation:
% \[ \xellipse(t) = (c_x + a\cdot\cos(t), c_y + b\cdot\sin(t)) \]
% where $t$ is the
% parametric angle. The parametric angle $t$ is just a property of the ellipse and has no
% `real' counterpart. Figure~\ref{fig:parametric} gives some helpful intuition how
% the $\alpha$ angles and $t$ angles are related: we can imagine drawing a unit circle inside
% an ellipse where for every $t$ angle on the unit circle we have a corresponding point
% and angle $\alpha$ on the ellipse. From the definition of $\xellipse$ it 
% is straightforward to derive a parametric angle $t_i$ for some $\alpha_i$: 
% \[ t_i = \arctan_2(\frac{\sin(\alpha_i)}{b},\frac{\cos(\alpha_i)}{a}) \]
%
% \noindent Given this relation, the start and end points of our curve are simply:
% \begin{align*}
% p_1 &amp;= \xellipse(t_1)\\
% p_2 &amp;= \xellipse(t_2)
% \end{align*}
%
% \noindent To be able to calculate optimal control points $q$ we need to also determine the 
% tangent of each point on the ellipse, which is given by the derivative of $\xellipse$:
% \[ \xellipse'(t) = (-a\cdot\sin(t), b\cdot\cos(t)) \]
% 
% \noindent 
% The derivation of the optimal B\'ezier control points for an ellipse is quite involved, 
% see~\cite{ellipse} for a nice overview. 
% For a quadratic B\'ezier curve, it turns out the optimal control points are determined as:
% \begin{align*}
% q_1 &amp;= p_1 + \tan(\frac{t_2 - t_1}{2})\cdot\xellipse'(t_1)\\
%     &amp;= p_2 - \tan(\frac{t_2 - t_1}{2})\cdot\xellipse'(t_2)
% \end{align*}
% %
% \noindent while for a cubic B\'ezier curve, one solution for optimal control points is:
% %
% \begin{align*}
% q_1 &amp;= p_1 + \kappa\cdot\xellipse'(t_1)\\
% q_2 &amp;= p_2 - \kappa\cdot\xellipse'(t_2)\\
% \kappa &amp;= \sin(t_2 - t_1)\frac{\sqrt{4 + 3\tan^2(\frac{t_2 - t_1}{2})}-1}{3}
% \end{align*}
% \noindent We will use cubic bezier curves since they look best. However, a na\"\i{}ve implementation
% may be too expensive in \LaTeX: if we count the expensive operations, we need about 11 $\cos$/$\sin$ 
% operations, plus a $\sqrt{}$ and 2 $\arctan$ operations.
% %
% \subsection{Optimizing elliptic arc equations} 
% Fortunately, we can improve upon this. First we note:
% \begin{flalign*}
% t_i &amp;= \arctan_2(\frac{\sin(\alpha_i)}{b},\frac{\cos(\alpha_i)}{a}) &amp; \hfill\\ 
%     &amp;= \arctan(\frac{a}{b}\tan(\alpha_i)) \\
%     &amp;= \arctan(\kk{i}) &amp; \mbox{(introducing $\kk{i}$ for $\frac{a}{b}\tan(\alpha_i)$)}
% \end{flalign*}
% \noindent where we write $\kk{i}$ for $\frac{a}{b}\tan(\alpha_i)$. Now, 
% \begin{flalign*}
% \cost{i} &amp;= \cos(t_i)\\
%           &amp;= \cos(\arctan(\kk{i})) &amp; \mbox{(geometry and pythagorean theorem)}\\
%           &amp;= \sign{i}\frac{1}{\sqrt{1 + \kk{i}^2}} \\
% \mbox{with}\\
% \sign{i} &amp;= \textsf{if}\; \cos(\alpha_i) &lt; 0\; \textsf{then}\; -\; \textsf{else}\; + 
% \end{flalign*}
% Later we will see how we can efficiently calculate the square root term, but first 
% do the same derivation for the $\sin$ function:
% \begin{flalign*}
% \sint{i}&amp;= \sin(t_i) \\
%         &amp;= \sin(\arctan(\frac{a}{b}\tan(\alpha_i))) &amp; \\
%           &amp;= \sin(\arctan(\kk{i})) \\
%           &amp;= \sign{i}\frac{\kk{i}}{\sqrt{1 + \kk{i}^2}}  
% \end{flalign*}
% \noindent Note that the interaction between the $\sin$ and $\kk{i}$ term (whose sign is determined by $\tan(\alpha_i)$) allows us to reuse the sign function used for $\cost{i}$. 
% %
% Using the previous equalities we can restate the parametric equations in terms of $\sint{i}$
% and $\cost{i}$:
% \begin{flalign*}
% \xellipse_i &amp;= (c_x + a\cdot\cost{i}), c_y + b\cdot\sint{i}) \\
% \xellipse'_i &amp;= (-a\cdot\sint{i}, b\cdot\cost{i})
% \end{flalign*}
% %
% \noindent This takes care of $p_1$ and $p_2$. The control points $q$ still need $\sin(t_2 - t_1)$ and $\tan(\frac{t_2 - t_1}{2})$.
% The halving rule on $\tan$ gives us:
% \[
% \tan(\frac{t_2 - t_1}{2}) = \frac{1 - \cos(t_2 - t_1)}{\sin(t_2 - t_1)} \mbox{\quad(\cite[page 71, 4.3.20]{abst})}
% \]
% \noindent So that leaves $\sin(t_2 - t_1)$ and $\cos(t_2 - t_1)$. Using the addition laws it follows:
% \begin{flalign*}
% \sin(t_2 - t_1) = \sint2\cost1 - \cost2\sint1 &amp; \mbox{\quad(\cite[page 72, 4.3.16]{abst})}\\
% \cos(t_2 - t_1) = \cost2\cost1 + \sint2\sint1 &amp; \mbox{\quad(\cite[page 72, 4.3.17]{abst})}
% \end{flalign*}
%
% \subsection{Circular square roots}
% \noindent Now, we only need two $\tan$ operations to calculate the initial $\kk{1}$ and $\kk{2}$ terms but we still have
% three square roots: $\sqrt{1 + \kk{i}^2}$ and $\sqrt{4 + 3\tan^2(\frac{t_2 - t_1}{2})}$. 
% Fortunately, both have the form $\sqrt{x^2 + y^2}$. For this form, we can make a very good 
% \begin{wrapfigure}[10]{o}{0.3\textwidth}
% \setlength\unitlength{3pt}
% \begin{picture}(30,30)(-15,-15)%
%   \linethickness{0.4pt}\roundjoin%
%   \iffalse
%   \put(0,0){\color{gainsboro}%
%     \multiput(-15,-15)(1,0){31}{\line(0,1){30}}%
%     \multiput(-15,-15)(0,1){31}{\line(1,0){30}}%
%   }%
%   \fi
%   \color{gainsboro}%
%   \put(0,0){\put(0,-15){\line(0,1){30}}%
%     \put(-15,0){\line(1,0){30}}%
%   }%
%   \color{black}%
%   \put(0,0){\circle{20}\put(-9,3){$\,x^2 + y^2$}%
%     \color{maroon}\moveto(14.14,0)\lineto(0,14.14)\lineto(-14.14,0)\lineto(0,-14.14)
%     \closepath\strokepath
%     \put(3,13){$\frac{1}{\sqrt{2}}(x+y)$}%
%     \color{navy}\moveto(10,10)\lineto(-10,10)\lineto(-10,-10)\lineto(10,-10)
%     \closepath\strokepath
%     \put(6,-12){$\,\max(x,y)$}%
%   }
%   %
% \end{picture}\iffalse\caption{Estimating an initial value for $\sqrt{x^2+y^2}$}\fi
% \end{wrapfigure}
% initial guess for the square root, since this is the parametric equation for a circle.
% The two good initial guesses form a `square' and `diamond' around this circle, namely
% $\max(\abs{x},\abs{y})$ and $\frac{1}{\sqrt{2}}\abs{x+y}$. Each one can be superior depending if $x$ and $y$
% are close or not, but it can be shown that the best choice is always the largest of these.
% Using this guess as an initial seed, we can do a standard Newton-Raphson iteration to 
% find a the square root where we only need 2 or 3 steps to achieve the desired precision. 
% Let's define a `circular square root' function $\csqrt$ such that
% $\csqrt(x,y) \approx \sqrt{x^2 + y^2}$ as:
% \begin{align*}
% \csqrt(x,y) = &amp;\textsf{let} &amp; sqr &amp; = x^2 + y^2 &amp; \hfill \\
%             &amp;               &amp; x_0 &amp; = \max(\abs{x},\abs{y},\frac{1}{\sqrt{2}}\abs{x+y}) &amp; \\
%             &amp;               &amp; x_1 &amp; = (x_0 + \frac{sqr}{x_0})/2 &amp; \hspace{\textwidth}\\
%             &amp;               &amp; x_2 &amp; = (x_1 + \frac{sqr}{x_1})/2 &amp;\\
%             &amp;  \textsf{in} &amp; x_2 &amp; 
% \end{align*}
% 
% \subsection{The optimized elliptical B\'ezier equations}
% \noindent Taking it all together, we get the following equations for a cubic B\'ezier curve approximation of an elliptical arc,
% where we assume as input the center point $(c_x,c_y)$, the $x$- and $y$-radius $(a,b)$, and a start and end angle
% $\alpha_1$ and $\alpha_2$. % It is assumed that $\alpha_1 \ne \alpha_2$ and $a \ge 0, b \ge 0$. Of course,
% with bezier curves one should build a full ellipse of parts where for each part $\rvert\alpha_1 - \alpha_2\lvert \le 90$.
% Given these parameters, the start and end point $p_1$ and $p_2$, and the control points $q_1$ and $q_2$ are
% defined as:
% \begin{flalign*}
% p_1 &amp;= \xellipse_1 &amp; \\
% p_2 &amp;= \xellipse_2\\
% q_1 &amp;= p_1 + \kappa\cdot\xellipse'_1\\
% q_2 &amp;= p_2 - \kappa\cdot\xellipse'_2\\
% \xellipse_i &amp;= (c_x + a\cdot\cost{i}, c_y + b\cdot\sint{i})\\
% \xellipse'_i &amp;= (-a\cdot\sint{i}, b\cdot\cost{i})
% \end{flalign*}
% The $\cost{i}$ and $\sint{i}$ are calculated as:
% \begin{flalign*}
% \sint{i} &amp; = \sign{i}\frac{\kk{i}}{\sk{i}} &amp; \\
% \cost{i} &amp; = \sign{i}\frac{1}{\sk{i}} 
% \end{flalign*}
% with
% \begin{flalign*}
% \kk{i} &amp;= \frac{a}{b}\tan(\alpha_i) &amp; \\
% \sk{i} &amp;= \csqrt(1,\kk{i}) \;\;(\approx \sqrt{1 + \kk{i}^2}) \\
% \sign{i} &amp;= \textsf{if}\; \cos(\alpha_i) &lt; 0\; \textsf{then}\; -\; \textsf{else}\; + 
% \end{flalign*}
% And finally, the $\kappa$ term can be defined as:
% \begin{flalign*}
% \kappa    &amp;= \sint{21}\frac{\kappa_{sqrt}-1}{3} &amp; 
% \end{flalign*}
% with
% \begin{flalign*}
% \sint{21} &amp; = \sint2\cost1 - \cost2\sint1 \;\;(=\sin(t_2 - t_1)) &amp; \\
% \cost{21} &amp; = \cost2\cost1 + \sint2\sint1 \;\;(=\cos(t_2 - t_1))\\
% \kappa_{tan} &amp;= \frac{1 - \cost{21}}{\sint{21}} \;\;\mbox{(note: divides by zero if $\alpha_1 = \alpha_2$)}\\
% \kappa_{sqrt} &amp;= \csqrt(\sqrt{4},\sqrt{3}\cdot\kappa_{tan}) \;\;(\approx \sqrt{4 + 3\kappa_{tan}^2})
% \end{flalign*}
%
%\section{Implementation}
%
% Generally, we use e-\TeX{} division to divide dimensions, where we 
% divide \rarg{dim$_1$} by \rarg{dim$_2$} using:
% |\dimexpr 1pt * |\rarg{dim$_1$}|/|\rarg{dim$_2$}|\relax| 
% since it keeps a 64-bit intermediate result for such `scaling' expressions. 
% Note that both \rarg{dim}
% expressions occur in an integer context and \TeX{} will convert
% them to numbers automatically (i.e. in |sp| units).
%

% \subsection{Generic math and trigonometry routines}
%
% \begin{macro}{\pIIe@csedef}
% \marg{csname}\textit{pattern}\marg{body}\\
% Define a macro by a \textit{csname}. Just like the |\csedef| function 
% from  \textsf{etoolbox} package 
%    \begin{macrocode}
\providecommand*\pIIe@csedef[1]{\expandafter\edef\csname #1\endcsname}
%    \end{macrocode}
% \end{macro}
%
%\begin{macro}{\pIIe@ellip@csqrt}
% \marg{dimen$_x$}\marg{dimen$_y$}\marg{dimreg$_{res}$}\\
% Calculates $res \approx \sqrt{x^2 + y^2}$ and caches previous results
% for efficiency.
%
% Overwrites |\@ovxx|,|\@ovyy|,|\@ovdx|,|\@ovdy|,|\@tempa|, and |\dimen@|.
%    \begin{macrocode}
\newcommand*\pIIe@ellip@csqrt[3]{%
  \@ovxx=#1\relax
  \ifdim\@ovxx&lt;\z@\@ovxx-\@ovxx\fi
  \@ovyy=#2\relax
  \ifdim\@ovyy&lt;\z@\@ovyy-\@ovyy\fi
  \edef\pIIe@csname{@csqrt(\number\@ovxx,\number\@ovyy)}%
  \expandafter\ifx\csname\pIIe@csname\endcsname\relax
    \pIIe@ellip@csqrt@%    
    \pIIe@csedef{\pIIe@csname}{\the\dimen@}%
    #3\dimen@
  \else
    #3\dimexpr\csname\pIIe@csname\endcsname\relax
  \fi
}
%    \end{macrocode}
%\end{macro}
%\begin{macro}{\pIIe@ellip@csqrt@}
% Internal routine: calculates |\dimen@| $\approx \sqrt{x^2 + y^2}$.
% where $x \ge 0$ and $y \ge 0$, and |\@ovxx| $=x$ and |\@ovyy| $=y$.
% 
% Overwrites |\@ovdx|,|\@ovdy|, and |\@tempa|.
%    \begin{macrocode}
\newcommand*\pIIe@ellip@csqrt@{%
%    \end{macrocode}
% First determine $\max(x,y,\frac{1}{\sqrt{2}}(x+y))$ in |\dimen@|.
% Put the sum $x+y$ in |\@ovdx|.
%    \begin{macrocode}  
  \@ovdx\@ovxx
  \advance\@ovdx by \@ovyy
%    \end{macrocode}
% Put initial guess in |\dimen@| $=\max(\abs{x},\abs{y},\frac{1}{\sqrt{2}}(x+y))$.
%    \begin{macrocode}  
  \dimen@0.7071067\@ovdx
  \ifdim\dimen@&lt;\@ovyy\dimen@\@ovyy\fi
  \ifdim\dimen@&lt;\@ovxx\dimen@\@ovxx\fi
%    \end{macrocode}
% To prevent overflowing \TeX{} dimensions we only do
% a further Newton-Raphson approximation if the sum $x+y$ is less than 128pt.
% Otherwise, for our application, the initial guess is still very precise since $x \ll y$ in that case.
%    \begin{macrocode}  
  \ifdim\@ovdx&lt;128\p@    
%    \end{macrocode}
% Set |\@ovxx| to $x^2 + y^2$
%    \begin{macrocode}  
    \edef\@tempa{\strip@pt\@ovxx}%
    \@ovxx\@tempa\@ovxx
    \edef\@tempa{\strip@pt\@ovyy}%
    \@ovyy\@tempa\@ovyy
    \advance\@ovxx by \@ovyy
%    \end{macrocode}
% Do two steps of Newton-Raphson (should we do three?)
%    \begin{macrocode}    
    \advance\dimen@ by \dimexpr1pt * \@ovxx/\dimen@\relax
    \divide\dimen@ by 2%
    \advance\dimen@ by \dimexpr1pt * \@ovxx/\dimen@\relax
    \divide\dimen@ by 2%
  \fi
%    \end{macrocode}
% Result is |\dimen@|.
%    \begin{macrocode}    
}
%    \end{macrocode}
% \end{macro}
%


% \begin{macro}{\pIIe@atan@}
%
% Approximate the $\arctan$ using 
% \[x\cdot\frac{\pi}{4} - x \cdot (\abs{x} - 1) \cdot (0.2447 + 0.0663\cdot\abs{x})\]
% This approximation was described by Rajan et al.~\cite{rajan:atan}.
%
% The \cmd{pIIe@atan@} computes the arctan of |\dimen@| which must be between $-1$ and $1$, and stores it in |\dimen@| again.
% Overwrites |\@tempdim|(|a|,|b|,|c|,|d|),|\@tempa|, and |\dimen@|.
%    \begin{macrocode}
\newcommand*\pIIe@atan@{%
%    \end{macrocode}
% |\dimen@| contains $x$.
%    \begin{macrocode}  
  \@tempdima\dimen@
%    \end{macrocode}
% Set |\@dimtmpb| to $\abs{x}$
%    \begin{macrocode}  
  \@tempdimb\@tempdima
  \ifdim\@tempdimb&lt;\z@\@tempdimb-\@tempdimb\fi
  \dimen@0.0663\@tempdimb
  \advance\dimen@ 0.2447pt\relax
  \advance\@tempdimb -1pt\relax
  \edef\@tempa{\strip@pt\@tempdimb}%
  \dimen@\@tempa\dimen@
  \edef\@tempa{\strip@pt\@tempdima}%
  \dimen@\@tempa\dimen@
  \dimen@-\dimen@
%    \end{macrocode}
% Add $x\cdot\frac{\pi}{4}$ ($\approx 0.7853\cdot x$).
%    \begin{macrocode}   
  \advance\dimen@ 0.7853\@tempdima
}
%    \end{macrocode}
% \end{macro}

% \begin{macro}{\pIIe@atantwo}
% \marg{dimen$_y$}\marg{dimen$_x$}\marg{dimreg$_{res}$}\\
% Calculate \rarg{res} $= \arctan_2(y,x)$ and caches the result for later use.
%
% Overwrites |\@tempdim|(|a|,|b|,|c|,|d|),|\@tempa|, and |\dimen@|.
% Both $y$ and $x$ must be dimensions.
%    \begin{macrocode}
\newcommand*\pIIe@atantwo[3]{%
  \edef\pIIe@csname{@atan2(\number\dimexpr#1\relax,\number\dimexpr#2\relax)}%
  \expandafter\ifx\csname\pIIe@csname\endcsname\relax
    \pIIe@atantwo@{#1}{#2}{#3}%    
    \pIIe@csedef{\pIIe@csname}{\the\dimexpr#3\relax}%
  \else
    #3\dimexpr\csname\pIIe@csname\endcsname\relax
  \fi
}
%    \end{macrocode}
% \end{macro}

% \begin{macro}{\pIIe@atantwo@}
% \marg{dimen$_y$}\marg{dimen$_x$}\marg{dimreg$_{res}$}\\
% Calculate \rarg{res} $= \arctan_2(y,x)$.
% Overwrites |\@tempdim|(|a|,|b|,|c|,|d|),|\@tempa|, and |\dimen@|.
% Both $y$ and $x$ must be dimensions.
%    \begin{macrocode}
\newcommand*\pIIe@atantwo@[3]{%
  \@tempdima\dimexpr#2\relax
  \@tempdimb\dimexpr#1\relax
%    \end{macrocode}
% Handle extremes
%    \begin{macrocode}  
  \ifdim\@tempdima=\z@\relax
    \ifdim\@tempdimb&gt;\z@\relax\dimen@90\p@
    \else\ifdim\@tempdimb&lt;\z@\relax\dimen@-90\p@
    \else\dimen@0\p@
    \fi\fi
  \else
%    \end{macrocode}
% Save angle adjustment term in |\@tempdimd|.
%    \begin{macrocode}  
    \@tempdimd\z@
    \ifdim\@tempdima&lt;\z@\relax
      \ifdim\@tempdimb&lt;\z@\relax\@tempdimd-180\p@
      \else\@tempdimd180\p@
      \fi
    \fi
%    \end{macrocode}
% Divide $\frac{y}{x}$ and check if $-1 \le \frac{y}{x} \le 1$.
%    \begin{macrocode}  
    \dimen@\dimexpr1pt * \@tempdimb/\@tempdima\relax
    \@tempdimc\dimen@
    \ifdim\@tempdimc&lt;\z@\relax\@tempdimc-\@tempdimc\fi
    \ifdim\@tempdimc&gt;\p@\relax
%    \end{macrocode}
% Use the equality $\arctan(x) = \pm\frac{1}{2}\pi - \arctan(\frac{1}{x})$ 
% to stay within the valid domain of |\pIIe@atan@|. The sign $\pm$ is
% positive when $x \ge 0$ and negative otherwise.
%    \begin{macrocode}
      \dimen@\dimexpr1pt * \@tempdima/\@tempdimb\relax
      \ifdim\dimen@&lt;\z@\relax\def\@tempsign{-}\else\def\@tempsign{}\fi
      \pIIe@atan@
      \dimen@-\dimen@
      \advance\dimen@ by \@tempsign1.5707pt\relax
    \else
      \pIIe@atan@
    \fi
%    \end{macrocode}
% And convert back to degrees ($\frac{180}{\pi} \approx 57.29578$)
%    \begin{macrocode}
    \dimen@57.29578\dimen@
%    \end{macrocode}
% Apply angle adjustment 
%    \begin{macrocode}    
    \advance\dimen@ by \@tempdimd
  \fi
  #3\dimen@%
}
%    \end{macrocode}
% \end{macro}

% \subsection{Sub routines for drawing an elliptical arc}
%
%
% \begin{macro}{\pIIe@noneto}
% \marg{dimen$_x$}\marg{dimen$_y$}\\
% Ignores its arguments. Used as a no-op instead of |\pIIe@lineto| or |pIIe@moveto|.
%    \begin{macrocode}
\newcommand*\pIIe@noneto[2]{}
%    \end{macrocode}
% \end{macro}
%
%\begin{macro}{\pIIe@ellip@sincost@}
% \marg{$\alpha_i$}\marg{$i$ = |one| or |two|}\\
% Calculate $\sint{i}$ and $\cost{i}$ into the |\@ellip|(|sin|/|cos|)$i$.
% Assumes |\@ellipratio| $=\frac{a}{b}$.
%    \begin{macrocode}
\newcommand*\pIIe@ellip@sincost@[2]{%
%    \end{macrocode}
% Put the $\sin(\alpha_i)$ and $\cos(\alpha_i)$ into |\@tempdima| and |\@tempdimb|.
%    \begin{macrocode}    
  \CalculateSin{#1}%
  \CalculateCos{#1}% 
  \@tempdima\UseSin{#1}\p@   
  \@tempdimb\UseCos{#1}\p@
%    \end{macrocode}
% Check for extremes where $\tan = \pm\infty$.
%    \begin{macrocode}    
  \ifdim\@tempdima=\p@\relax
    \pIIe@csedef{@ellipsin#2}{1}%
    \pIIe@csedef{@ellipcos#2}{0}%
  \else\ifdim\@tempdima=-\p@\relax
    \pIIe@csedef{@ellipsin#2}{-1}%
    \pIIe@csedef{@ellipcos#2}{0}%
  \else
%    \end{macrocode}
% Calculate $\kk{i}$ in |\@tempdimc| and $\sqrt{1 + \kk{i}^2}$ in |\@tempdimd|, 
% and derive $\sint{i}$ and $\cost{i}$.
%    \begin{macrocode}    
    \@tempdimc\@ellipratio\dimexpr1pt * \@tempdima/\@tempdimb\relax
    %\typeout{ i#2=\the\@tempdimc, sin(#1)=\the\@tempdima}%
    \pIIe@ellip@csqrt{\p@}{\@tempdimc}\@tempdimd
    \ifdim\@tempdimb&lt;\z@\relax\@tempdimd-\@tempdimd\fi
    \pIIe@csedef{@ellipsin#2}{\strip@pt\dimexpr1pt * \@tempdimc/\@tempdimd\relax}%
    \pIIe@csedef{@ellipcos#2}{\strip@pt\dimexpr1pt * \p@/\@tempdimd\relax}%
  \fi\fi
}
%    \end{macrocode}
% \end{macro}

%\begin{macro}{\pIIe@ellip@sincost}
% \marg{$\alpha_1$}\marg{$\alpha_2$}\\
% Calculate $\sint{i}$ and $\cost{i}$ into the |\@ellip|(|sin|/|cos|)(|one|/|two|).
% Assumes |\@ovro|$=a$ and |\@ovri|$=b$ with $b \ne 0$.
%    \begin{macrocode}
\newcommand*\pIIe@ellip@sincost[2]{%
%    \end{macrocode}
% Set |\@ellipratio| to the ratio $\frac{a}{b}$.
%    \begin{macrocode}    
  %\typeout{ calc sin cos: angles (#1,#2), radii: (\the\@ovro,\the\@ovri)}%
  \edef\@ellipratio{\strip@pt\dimexpr1pt * \@ovro/\@ovri\relax}%
%    \end{macrocode}
% And calculate $\sint{i}$ and $\cost{i}$
%    \begin{macrocode} 
  \pIIe@ellip@sincost@{#1}{one}%
  \pIIe@ellip@sincost@{#2}{two}%
  %\typeout{ sincos(a=#1)=(\@ellipsinone,\@ellipcosone), sincos(a=#2)=(\@ellipsintwo,\@ellipcostwo), }%
}
%    \end{macrocode}
% \end{macro}
%
%
%\begin{macro}{\pIIe@omega}
% \marg{$i$ = |one| or |two|}\\
% Calculates $\xellipse_i$ into |\@tempdima| and |\@tempdimb|.
% Assumes |\@ovro|$=a$ and |\@ovri|$=b$.
%    \begin{macrocode}
\newcommand*\pIIe@omega[3]{%
  \@tempdima\csname @ellipcos#3\endcsname\@ovro
  \advance\@tempdima by #1\relax
  \@tempdimb\csname @ellipsin#3\endcsname\@ovri
  \advance\@tempdimb by #2\relax
}
%    \end{macrocode}
% \end{macro}

%\begin{macro}{\pIIe@omegai}
% \marg{$i$ = |one| or |two|}\\
% Calculates $\xellipse'_i$ into |\@tempdimc| and |\@tempdimd|.
% Assumes |\@ovro|$=a$ and |\@ovri|$=b$.
%    \begin{macrocode}
\newcommand*\pIIe@omegai[1]{%
  \@tempdimc\csname @ellipsin#1\endcsname\@ovro
  \@tempdimc-\@tempdimc
  \@tempdimd\csname @ellipcos#1\endcsname\@ovri
}
%    \end{macrocode}
% \end{macro}

%\begin{macro}{\pIIe@ellip@kappa}
% Calculates $\kappa$, expects |\@ellip|(|sin|/|cos|)(|one|/|two|) to be defined.
%    \begin{macrocode}
\newcommand*\pIIe@ellip@kappa{%
%    \end{macrocode}
% Calculate $\sint{21}$ and $\cost{21}$ in |\@tempdima| and |\@tempdimb|.
%    \begin{macrocode}  
  \@ovyy\@ellipsinone\p@
  \@ovxx\@ellipcosone\p@
  \@tempdima\@ellipcostwo\@ovyy
  \@tempdima-\@tempdima
  \advance\@tempdima by \@ellipsintwo\@ovxx
  \@tempdimb\@ellipcostwo\@ovxx
  \advance\@tempdimb by \@ellipsintwo\@ovyy
%    \end{macrocode}
% First test if $\sint{21} = 0$ to prevent division by zero. In that
% case, it must have been that $\alpha_1 = \alpha_2$ and we set $\kappa$ to zero
% so it the control points become equal to the start and end point.
%    \begin{macrocode}  
  \ifdim\@tempdima=\z@\relax
    \edef\@ellipkappa{0}%
  \else
%    \end{macrocode}
% Calculate $\kappa_{tan}$ in |\dimen@|
%    \begin{macrocode}  
    \dimen@\dimexpr1pt - \@tempdimb\relax
    \dimen@\dimexpr1pt * \dimen@/\@tempdima\relax
%    \end{macrocode}
% Calculate $\kappa_{sqrt}$ in |\dimen@|
%    \begin{macrocode}  
    \pIIe@ellip@csqrt{2\p@}{1.73205\dimen@}{\dimen@}%
%    \end{macrocode}
% Calculate $\kappa$ in |\dimen@|
%    \begin{macrocode}  
    \advance\dimen@ by -\p@
    \divide\dimen@ by 3%
    \edef\@tempa{\strip@pt\@tempdima}%
    \dimen@\@tempa\dimen@
    \edef\@ellipkappa{\strip@pt\dimen@}%
  \fi
  %\typeout{ calculated kappa: \@ellipkappa}%
}
%    \end{macrocode}
% \end{macro}

% \subsection{Core routines for drawing elliptical arcs}
%
%\begin{macro}{\pIIe@elliparc@}
% \oarg{start}\marg{$c_x$}\marg{$c_y$}\marg{$\alpha_1$}\marg{$\alpha_2$}\\
% Assumes that the radii are set as |\@ovro|$=a$ and |\@ovri|$=b$.
% This is the main routine for drawing an elliptic arc, where $\abs{\alpha_2 - \alpha_1}\,\le 90$.
%    \begin{macrocode}
\newcommand*\pIIe@elliparc@[5]{%
  %\typeout{elliparc: #1, center: (#2, #3), radius (\the\@ovro, \the\@ovri),angle (#4, #5)}%
%    \end{macrocode}
% Define initial action: 0 (lineto), 1(moveto), or 2 (nothing)
%    \begin{macrocode}    
  \ifcase #1\relax
      \let\@ellip@startto\pIIe@lineto
  \or \let\@ellip@startto\pIIe@moveto
  \or \let\@ellip@startto\pIIe@noneto%
  \else\PackageWarning{ellipse}{Illegal initial action in \protect\elliparc: %
          must be one of 0 (lineto), 1 (moveto) or 2 (do nothing) but I got: #1}%
  \fi
%    \end{macrocode}
% Perform just the start action if the radii are zero
%    \begin{macrocode}    
  \ifdim\@ovro=\z@\relax\@ovri\z@\fi
  \ifdim\@ovri=\z@\relax
    \@ellip@startto{#2}{#3}%
  \else
%    \end{macrocode}
% Calculate $\sint{i}$ and $\cost{i}$ first into the |\@ellip|(|sin|/|cos|)(|one|/|two|) registers.
%    \begin{macrocode}    
    \pIIe@ellip@sincost{#4}{#5}%
%    \end{macrocode}
% And draw..
%    \begin{macrocode}
    \pIIe@elliparc@draw{#2}{#3}%
  \fi
}
%    \end{macrocode}
% \end{macro}
%
%\begin{macro}{\pIIe@elliparc@t}
% \oarg{start}\marg{$c_x$}\marg{$c_y$}\marg{$t_1$}\marg{$t_2$}\\
% Assumes that the radii are set as |\@ovro|$=a$ and |\@ovri|$=b$.
% Moreover, this routine take $t_1$ and $t_2$ as the angles of the ellipse equation (instead of real angles $\alpha_i$).
% This routine is mainly for other libraries that may already have computed the $t$ angles
% and need a bit more efficiency.
%    \begin{macrocode}
\newcommand*\pIIe@elliparc@t[5]{%
%    \end{macrocode}
% Define initial action: 0 (lineto), 1(moveto), or 2 (nothing)
%    \begin{macrocode}    
  \ifcase #1\relax
      \let\@ellip@startto\pIIe@lineto
  \or \let\@ellip@startto\pIIe@moveto
  \or \let\@ellip@startto\pIIe@noneto%
  \else\PackageWarning{ellipse}{Illegal initial action in \protect\elliparc: %
          must be one of 0 (lineto), 1 (moveto) or 2 (do nothing) but I got: #1}%
  \fi
%    \end{macrocode}
% Perform just the start action if the radii are zero
%    \begin{macrocode}    
  \ifdim\@ovro=\z@\relax\@ovri\z@\fi
  \ifdim\@ovri=\z@\relax
    \@ellip@startto{#2}{#3}%
  \else
%    \end{macrocode}
% Calculate $\sint{i}$ and $\cost{i}$ first into the |\@ellip|(|sin|/|cos|)(|one|/|two|) registers.
%    \begin{macrocode}    
    \CalculateSin{#4}\CalculateCos{#4}%
    \edef\@ellipsinone{\UseSin{#4}}%
    \edef\@ellipcosone{\UseCos{#4}}%
    \CalculateSin{#5}\CalculateCos{#5}%
    \edef\@ellipsintwo{\UseSin{#5}}%
    \edef\@ellipcostwo{\UseCos{#5}}%
%    \end{macrocode}
% And draw..
%    \begin{macrocode}
    \pIIe@elliparc@draw{#2}{#3}%
  \fi
}
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{pIIe@elliparc@draw}
% \marg{$c_x$}\marg{$c_y$}\\
% Expects $a =$|\@ovro|, $b$ = |\@ovri|, and  |\@ellip|(|sin|/|cos|)(|one|/|two|) defined.
% |\@ellipstarto| should contain the initial drawing action and is called with an initial
% $x$ and $y$ coordinate (usually equal to |\pIIe@lineto|,|\pIIe@moveto|, or |pIIe@noneto|).
%    \begin{macrocode}
\newcommand*\pIIe@elliparc@draw[2]{%
% Calculate $\kappa$.
%    \begin{macrocode}    
  \pIIe@ellip@kappa%
%    \end{macrocode}
% Now we are ready to compute the control points. First $p_1$.
%    \begin{macrocode}
  \pIIe@omega{#1}{#2}{one}%
  %\typeout{ point one: (\the\@tempdima,\the\@tempdimb)}%
%    \end{macrocode}
% The coordinates are added to the path if and how necessary:
%    \begin{macrocode}
  \@ellip@startto\@tempdima\@tempdimb
%    \end{macrocode}
% Add control point $q_1$
%    \begin{macrocode}
  \pIIe@omegai{one}%
  \advance\@tempdima by \@ellipkappa\@tempdimc
  \advance\@tempdimb by \@ellipkappa\@tempdimd
  \pIIe@add@nums\@tempdima\@tempdimb
  %\typeout{ control one: (\the\@tempdima,\the\@tempdimb)}%
%    \end{macrocode}
% Calculate $p_2$
%    \begin{macrocode}
  \pIIe@omega{#1}{#2}{two}%
%    \end{macrocode}
% Add control point $q_1$
%    \begin{macrocode}
  \pIIe@omegai{two}%
  \@tempdimc\@ellipkappa\@tempdimc
  \@tempdimd\@ellipkappa\@tempdimd
  \@tempdimc-\@tempdimc
  \@tempdimd-\@tempdimd
  \advance\@tempdimc by \@tempdima
  \advance\@tempdimd by \@tempdimb
  \pIIe@add@nums\@tempdimc\@tempdimd
  %\typeout{ control two: (\the\@tempdimc,\the\@tempdimd)}%
%    \end{macrocode}
% And finally add $p_2$ to the path
%    \begin{macrocode}
  \pIIe@add@CP\@tempdima\@tempdimb
  %\typeout{ point two: (\the\@tempdima,\the\@tempdimb)}%
  \pIIe@addtoGraph\pIIe@curveto@op
}
%    \end{macrocode}
% \end{macro}
%
%
% \subsection{Normalizing elliptical arcs}
%
% \begin{macro}{pIIe@elliparc}
% \begin{macro}{pIIe@@elliparc}
% \oarg{start}\marg{$c_x$}\marg{$c_y$}\marg{a}\marg{b}\marg{$\alpha_1$}\marg{$\alpha_2$}\\
% \strut\\
% These two macros check the arguments and normalize the angles.
%    \begin{macrocode}
\newcommand*\pIIe@elliparc[7][0]{%
%    \end{macrocode}
% Store the radii in registers, where |\@ovro|$=a$ and |\@ovri|$=b$.
%    \begin{macrocode}  
  \@ovro #4\relax
  \@ovri #5\relax
  \iffalse%dim\@ovro=\@ovri
%    \end{macrocode}
% Call the circular arc routine if the x- and y-radius are equal
%    \begin{macrocode}  
    \pIIe@arc[#1]{#2}{#3}{#4}{#6}{#7}
  \else
%    \end{macrocode}
% Normalize angles such that the arc angle $\abs{\alpha_2 - \alpha_1}\,\le 720$.
% Store the arc angle in |\@arclen|.
%    \begin{macrocode}  
    \ifdim \@ovro&lt;\z@ \pIIe@badcircarg\else
      \ifdim \@ovri&lt;\z@ \pIIe@badcircarg\else
        \@arclen #7\p@ \advance\@arclen -#6\p@
        \ifdim \@arclen&lt;\z@ \def\@tempsign{-}\else\def\@tempsign{}\fi
        \ifdim \@tempsign\@arclen&gt;720\p@
          \PackageWarning {ellipse}{The arc angle is reduced to -720..720}%
          \@whiledim \@tempsign\@arclen&gt;720\p@ \do {\advance\@arclen-\@tempsign360\p@}%
          \@tempdima #6\p@ \advance\@tempdima \@arclen
          \edef\@angleend{\strip@pt\@tempdima}%
          \pIIe@@elliparc{#1}{#2}{#3}{#6}{\@angleend}%
        \else
          \pIIe@@elliparc{#1}{#2}{#3}{#6}{#7}%
        \fi
      \fi
    \fi
  \fi
}
%    \end{macrocode}
% |\pIIe@@elliparc| divides the total angle in parts of at most $90$ degrees.
% Assumes |\@ovro|$=a$ and |\@ovri|$=b$, and |\@arclen| the arc angle, with |\@tempsign| 
% sign of the arc angle.
%    \begin{macrocode}  
\newcommand*\pIIe@@elliparc[5]{%
  \begingroup
  \ifdim \@tempsign\@arclen&gt;90\p@
%    \end{macrocode}
% If the arc angle is too large, the arc is recursively
% divided into 2 parts until the arc angle is at most 90~degrees.
%    \begin{macrocode}
    \divide\@arclen 2%
    \@tempdima #4\p@\advance\@tempdima by \@arclen
    \edef\@anglemid{\strip@pt\@tempdima}%
    \def\@tempa{\pIIe@@elliparc{#1}{#2}{#3}{#4}}%
    \expandafter\@tempa\expandafter{\@anglemid}%
    \def\@tempa{\pIIe@@elliparc{2}{#2}{#3}}%
    \expandafter\@tempa\expandafter{\@anglemid}{#5}%
  \else
%    \end{macrocode}
% The arc angle is smaller than 90 degrees.
%    \begin{macrocode}
    \pIIe@elliparc@{#1}{#2}{#3}{#4}{#5}%
  \fi
  \endgroup
}%
%    \end{macrocode}
% \end{macro}
%\end{macro}

% \subsection{Drawing elliptical arcs}
%
%\begin{macro}{\elliparc}
%\begin{macro}{\pIIeelliparc}
% \oarg{start}\marg{center-x}\marg{center-y}\marg{radius-x}\marg{radius-y}\marg{start-angle}\marg{end-angle}\\
% \strut\\
% The main elliptical arc drawing routine. We start with |\pIIeelliparc| to avoid conflicts with
% other packages.
%    \begin{macrocode}
\newcommand*\pIIeelliparc[7][0]{%
  \@killglue
  \pIIe@elliparc[#1]{#2\unitlength}{#3\unitlength}{#4\unitlength}{#5\unitlength}{#6}{#7}%
  \ignorespaces%
}
\ifx\undefined\elliparc\else
  \PackageWarning{ellipse}{\protect\elliparc\space is redefined}%
\fi
\let\elliparc\pIIeelliparc
%    \end{macrocode}
% \end{macro}
% \end{macro}

% \begin{macro}{\earc}
% \begin{macro}{\earc*}
% |[|\rarg{$\alpha_0$}|,|\rarg{$\alpha_1$}|]|\marg{radius-x}\marg{radius-y}\\
% \strut\\
% The \cmd{\earc} command generalizes the standard \cmd{\arc} with both
% a $x$- and $y$-radius. The |\earc*| version draws a filled elliptical arc while
% |\earc| only strokes the elliptical arc. Both take an optional comma separated pair of 
% angles which specify the initial and final angle ($0$ and $360$ by default). 
% We start with \cmd{\pIIeearc} to avoid conflicts with otherpackages.
%    \begin{macrocode}
\newcommand*\pIIeearc
  {\@ifstar{\@tempswatrue\pIIe@earc@}{\@tempswafalse\pIIe@earc@}}
\newcommand*\pIIe@earc@[3][0,360]{\pIIe@earc@@(#1){#2}{#3}}
\def\pIIe@earc@@(#1,#2)#3#4{%
  \if@tempswa
    \pIIe@moveto\z@\z@
    \pIIe@elliparc{\z@}{\z@}{#3\unitlength}{#4\unitlength}{#1}{#2}%
    \pIIe@closepath\pIIe@fillGraph
  \else
    \pIIe@elliparc[1]{\z@}{\z@}{#3\unitlength}{#4\unitlength}{#1}{#2}%
    \pIIe@strokeGraph
  \fi}
\ifx\undefined\earc\else
  \PackageWarning{ellipse}{\protect\earc\space is redefined}%
\fi
\let\earc\pIIeearc
%    \end{macrocode}
% \end{macro}
% \end{macro}

% \begin{macro}{\ellipse}
% \begin{macro}{\ellipse*}
% \marg{radius-x}\marg{radius-y}\\
% \strut\\
% The \cmd{\ellipse} draws an ellipse with the specified $x$- and $y$-radius. 
% The |\ellipse*| version draws a filled ellipse. 
% We start with \cmd{\pIIeellipse} to avoid conflicts with other packages.
% The implementation redirects immediately to |earc| which generalized this command.
%    \begin{macrocode}
\newcommand*\pIIeellipse
  {\@ifstar{\@tempswatrue\pIIe@earc@}{\@tempswafalse\pIIe@earc@}}
\let\ellipse\pIIeellipse
%    \end{macrocode}
% \end{macro}
% \end{macro}

%
% \Finale
\endinput
  </pre></body></html>