From e0c6872cf40896c7be36b11dcc744620f10adf1d Mon Sep 17 00:00:00 2001 From: Norbert Preining Date: Mon, 2 Sep 2019 13:46:59 +0900 Subject: Initial commit --- macros/latex/contrib/ebezier/ebezier.dtx | 1875 ++++++++++++++++++++++++++++++ macros/latex/contrib/ebezier/ebezier.ins | 32 + macros/latex/contrib/ebezier/ebezier.pdf | Bin 0 -> 332417 bytes 3 files changed, 1907 insertions(+) create mode 100644 macros/latex/contrib/ebezier/ebezier.dtx create mode 100644 macros/latex/contrib/ebezier/ebezier.ins create mode 100644 macros/latex/contrib/ebezier/ebezier.pdf (limited to 'macros/latex/contrib/ebezier') diff --git a/macros/latex/contrib/ebezier/ebezier.dtx b/macros/latex/contrib/ebezier/ebezier.dtx new file mode 100644 index 0000000000..267dbd7d6c --- /dev/null +++ b/macros/latex/contrib/ebezier/ebezier.dtx @@ -0,0 +1,1875 @@ +% \iffalse meta comment +% +% Copyright (c) Gerhard A. Bachmaier 2001-2005 +% +% This program can be redistributed and/or modified under the terms +% of the LaTeX Project Public License Distributed from CTAN +% archives in directory macros/latex/base/ as file lppl.txt; either +% version 1 of the License, or (at your option) any later version. +% +% Gerhard A. Bachmaier +% Institute for Medical Informatics, Statistics, and Documentation +% Medical University of Graz +% send bugs to: gerhard.bachmaier@meduni-graz.at +% +% \fi +% +% \iffalse +% +%<*driver> +\ProvidesFile{ebezier.drv} +% +%\ProvidesPackage{ebezier} + [2005/03/01 v4] +% +%<*driver> +\documentclass{article} +\usepackage{ebezier} +\usepackage{calc} +\usepackage{doc} +\EnableCrossrefs +\CodelineIndex +%\DisableCrossrefs +\begin{document} + \DocInput{ebezier.dtx} +\end{document} +% +% \fi +% +% \CheckSum{1955} +% +% \DoNotIndex{\@X,\@Xa,\@Xb,\@Xc,\@Y,\@Ya,\@Yb,\@Yc} +% \DoNotIndex{\@Z,\@Za,\@Zb,\@Zc,\@Zd,\@Ze,\@Zf,\@Zg,\@Zh,\@Zi,\@Zj} +% \DoNotIndex{\@clnht,\@clnwd,\@dashdim,\@ifnextchar,\@killglue,\@ne} +% \DoNotIndex{\@ovdx,\@ovdy,\@ovri,\@ovro,\@ovxx,\@ovyy} +% \DoNotIndex{\@tempdima,\@tempdimb,\@tempdimc,\@tfor,\@und@fined} +% \DoNotIndex{\@whilenum,\@xdim,\@ydim,\advance,\approx,\bullet} +% \DoNotIndex{\c@@cnta,\c@@cntb,\c@@cntc,\c@@cntd,\chardef,\copy} +% \DoNotIndex{\csname,\def,\dimen,\divide,\do,\dp,\else,\endcsname,\fi} +% \DoNotIndex{\gdef,\hb@xt@,\hbox,\hskip,\hss,\ht,\ifdim,\ifnum,\ifx} +% \DoNotIndex{\ignorespaces,\kern,\let,\long,\loop,\lower,\Lpack} +% \DoNotIndex{\magstep,\magstephalf} +% \DoNotIndex{\multiply,\myname,\NeedsTeXFormat,\newcommand,\newcounter} +% \DoNotIndex{\newfont,\newif,\newlength,\newsavebox,\oval,\pi,\put} +% \DoNotIndex{\raise,\ratio,\realname,\relax,\repeat,\RequirePackage} +% \DoNotIndex{\reserved@a,\setbox,\setcounter,\setlength,\space,\sqrt} +% \DoNotIndex{\the,\thr@@,\tw@,\unhcopy,\unitlength,\value,\vrule,\wd,\z@} +% +% \title{Using ebezier} +% \author{Gerhard A. Bachmaier} +% \date{March 1, 2005} +% +% \renewcommand{\topfraction}{.6} +% \renewcommand{\bottomfraction}{.6} +% \setcounter{totalnumber}{5} +% \renewcommand{\textfraction}{.1} +% \setlength{\unitlength}{1pt} +% \setlength{\parskip}{3pt} +% \font \logo=logo10 scaled \magstep1 +% \newcommand{\formstrut}{\rule{0mm}{2mm}} +% \providecommand{\Metafont}{% +% {\logo META}\discretionary{}{-}{}{\logo FONT}} +% \renewcommand{\thefootnote}{\fnsymbol{footnote}} +% \renewcommand{\arraystretch}{1.2} +% \newcommand\SB[2]{\setbox1=\hbox{#1#2}} +% \newcommand*{\Lpack}[1]{\textsf {#1}} +% +% \maketitle +% +% \begin{abstract} +% The package \Lpack{ebezier} is an extension of the (old) +% \Lpack{bezier.sty} which is now part of \LaTeXe. It defines +% linear and cubic Bernste\u\i{}n polynomials together with some +% plotting macros for arcs. +% +% With the aid of the \Lpack{calc} package also the calculation of +% square roots and henceforward lengths is supplied. +% \end{abstract} +% +% +% \StopEventually{} +% +% \section*{Preamble} +% +% If you want to draw complicated and/or lots of pictures, you should use +% \textsc{PostScript} for generating your plots and \Lpack{dvips} to include +% them in \TeX\ documents. \textsc{PostScript} can plot lines with arbitrary +% slope and unlimited length and circles with arbitrary radius just by using +% one command. See also the \LaTeX\ Graphics Companion\cite{T1} for further +% possibilities. There is also a new package \Lpack{pict2e}\cite{pict2e} a\-vail\-able +% which is preferrable for PDF and \textsc{PostScript}. +% +% This package will support also lines with arbitrary slopes and unlimited +% length, but each line has to be generated as a sample of points. Each +% point reduces \TeX's memory and you will very likely have to overcome some +% \texttt{TeX capacity excxeeded...} messages. +% +% Exact circles would involve trigonometric functions or square roots +% to be evaluated by \TeX. +% Even with some tricks for reducing the effort of the calculation algorithm +% there would be hundreds of calculations for each point.\footnote{% +% To use \TeX\ for complex computations is as satisfactory as using your desk +% calculator for writing tasks. But if you really want to do it e.g.\ the digits 7353 +% can be read (rotating by $180^0$) as +% \texttt{ESEL}, the german word for ``donkey''.} +% But they may be quite +% well approximated by cubic bezier curves, also supplied in this package +% (The quality of interpolation is discussed in some detail in the Section +% \textit{Fitting Arcs}.) In fact, the small circles in the \LaTeX-\texttt{lcircle} fonts +% are also generated by the same method. +% +% For draft papers use all kind of bezier curves with small number of points, +% just for the final run increase the numbers. \TeX\ memory can be set free +% again with {\verb+\clearpage+} at the end of complicated pictures. It's +% also a good idea to have them at an extra page (option \verb+[p]+ for +% \texttt{figure} environments). +% +% For optical constructions the software LaTeXPiX\cite{PiX} may be a starting point. +% This software supports cubic bezier curves defined in this package or from +% \Lpack{bez123}\cite{T5}. +% +% \section{Mathematical Definitions} +% +% A Bernste\u\i{}n polynomial of degree $n-1\: (n\ge 2)$ is defined by +% $n$ points $z_1, z_2,\ldots,z_n$ +% +% \[ \mathcal{B}_{n-1} [t] = \sum_{i=0}^{n-1} {n-1\choose i} +% (1-t)^{n-1-i} t^i z_{i+1}\quad t\in[0,1].\footnotemark\]% +% \footnotetext{There are also +% variants of this definitions with all coefficients $\equiv 1$.} +% +% The points $z_i, \: i\in\lbrace1,\ldots,n\rbrace$, may be considered as +% real numbers, then $\mathcal{B}$ is really a polynomial in $t$. Or they +% denote points in a plane, which notation we will use further. In this case +% both \emph{components} are polynominials and the graph for $\mathcal{B}$ +% is---part of---an algebraic curve. +% +% \bigskip +% +% All these graphs have in common: +% \begin{itemize} +% \item The graph is contained in the convex hull of the defining points. +% \item The graph starts at $z_1$ and stops at $z_n$. +% \item At the endpoints the tangents coincident with +% the directions $z_1-z_2$ and $z_{n-1}-z_n$ correspondingly. +% \end{itemize} +% +% For $n=2$ the Bernste\u\i{}n polynomial $\mathcal{B}_1$ reduces to the +% linear form spanned by $z_1$ and $z_2$. The parametrization in $t$ +% +% \[ \mathcal{B}_1 [t] =(1-t) z_1 + t z_2=: t[z_1,z_2]\] +% +% is also known as \emph{convex coordinates} for the segment +% $\overline{\formstrut z_1z_2}$. +% +% \begin{figure}[htb] +% \begin{center} +% \begin{picture}(100,60) +% \put(-25,-10){\framebox(155,70){}} +% \put(20,10){\line(2,1){60}} +% \put(20,10){\makebox(0,0){$\bullet$}} +% \put(80,40){\makebox(0,0){$\bullet$}} +% \put(40,20){\makebox(0,0){$\bullet$}} +% \put(-17,15){$z_1 (t=0)$} +% \put(75,47){$z_2 (t=1)$} +% \put(40,10){$t=1/3$} +% \end{picture} +% \end{center} +% \caption{Line defined by two points} +% \end{figure} +% +% \bigskip +% +% For $n=3$ the result is a (quadratic) parabola which can also +% be constructed as the convex hull of all tangents in the +% triangle $\Delta\,z_1 z_2 z_3$ (examplified in Fig.\ 2b). +% +% \begin{figure}[hbt] +% \begin{center} +% \begin{picture}(250,120) +% \put(-15,-10){\framebox(280,130){}} +% \Qbezier[300](0,0)(50,100)(100,0) +% \put(0,0){\makebox(0,0){$\bullet$}} +% \put(100,0){\makebox(0,0){$\bullet$}} +% \put(50,100){\makebox(0,0){$\bullet$}} +% \put(-6,10){$z_1$} +% \put(50,105){$z_2$} +% \put(99,10){$z_3$} +% \put(0,0){\line(1,2){50}} +% \put(100,0){\line(-1,2){50}} +%% +% \put(150,0){\makebox(0,0){$\bullet$}} +% \put(250,0){\makebox(0,0){$\bullet$}} +% \put(200,100){\makebox(0,0){$\bullet$}} +% \put(144,10){$z_1$} +% \put(200,105){$z_2$} +% \put(249,10){$z_3$} +% \put(150,0){\line(1,2){50}} +% \put(250,0){\line(-1,2){50}} +% \lbezier[50](160,20)(210,80) +% \lbezier[30](170,40)(220,60) +% \lbezier[30](180,60)(230,40) +% \lbezier[50](190,80)(240,20) +% \lbezier[50](155,10)(205,90) +% \lbezier[50](165,30)(215,70) +% \lbezier[30](175,50)(225,50) +% \lbezier[50](185,70)(235,30) +% \lbezier[50](195,90)(245,10) +% \end{picture} +% \end{center} +% \caption{Quadratic parabola (a) as Bernste\u\i{}n polynom of degree 2 +% and (b) as hull of tangents} +% \end{figure} +% +% For $n=4$ finally we arrive at the cubic curves used e.g.\ in the \Metafont\ +% book\cite{T3}. +% +% \begin{figure}[hbt] +% \begin{center} +% \begin{picture}(100,100) +% \put(-10,-10){\framebox(130,110){}} +% \Cbezier[500](0,0)(10,80)(70,40)(100,0) +% \put(5,0){$z_1$} +% \put(10,85){$z_2$} +% \put(70,50){$z_3$} +% \put(105,0){$z_4$} +% \end{picture} +% \end{center} +% \caption{A simple cubic parabola.} +% \end{figure} +% +% +% We will not use more complicated polynomials for several reasons: +% +% \begin{itemize} +% \item Higher degree polynomials require more operations to calculate +% just one point of the graph. +% \item For sketches (and \textbf{not} exact graphs!) cubic splines are +% sufficient to scope with all kind of different curvature requirements. +% \item \TeX\ can handle integers up to $2^{28}$, and ``real number'' lengths +% are transformed to integers (multiples of scaled points: 1\,pt=$2^{16}$ sp) \cite{T2}. To stay +% within this restricted range even for cubic beziers we have to do calculations +% in the right order. Changing the order of multiplication and divisions will +% result very soon in arithmetic overflows. Also multiplication with these pseudo-real +% numbers is not an associative operation (due to the range limits!). +% \item The maximum number of arguments for commands in \TeX\ is limited to nine, +% which is just enough for four points and a number. +% \end{itemize} +% +% +% % +% \section{The Plotting Macros} +% +% \subsection{Simple Beziers} +% +% There are two first level plot commands to be used in a +% \LaTeXe\ \texttt{picture} environment: +% +% \begin{verbatim} +% \lbezier[n](x1,y1)(x2,y2) +% \cbezier[n](x1,y1)(x2,y2)(x3,y3)(x4,y4) +% \end{verbatim} +% +% The arguments in square brackets are optional! If they are omitted or $n=0$ an adequate number +% will be calculated (cf. Section 8). +% +% \DescribeMacro{\qbezier} +% \verb+\lbezier+ draws line segments from point $(x_1,y_1)$ +% to $(x_2,y_2)$, or more exactly, $n+1$ intermediate points, while +% \verb+\cbezier+ is an implementation of the cubic variant. Just for +% completeness let me remind you that the quadratic +% variant---\verb+\qbezier[n](x1,y1)(x2,y2)(x3,y3)+---is part of \LaTeXe. +% +% \DescribeMacro{\qbeziermax} +% $n$ is always limited by the number \verb+\qbeziermax+ (=500). +% +% You may change \verb+\qbeziermax+ by a command like (it is not a counter!) +% \verb+\renewcommand{\qbeziermax}{1000}+. +% +% \subsubsection{lbezier} +% \DescribeMacro{\lbezier} +% \verb+\lbezier+ is straightforward defined as +% linear polynomial. It produces equally spaced points. +% +% \begin{verbatim} +% ... +% \put(0,25){\line(1,0){90}} +% \lbezier[20](0,10)(90,10) +% \lbezier[200](0,-5)(90,-5) +% ... +% \end{verbatim} +% +% \begin{figure}[hbt] +% \begin{center} +% \begin{picture}(150,30) +% \put(-20,-15){\framebox(230,50){}} +% \put(0,25){\line(1,0){90}} +% \put(95,25){\makebox(100,0){\protect\LaTeXe\ \protect\texttt{line}}} +% \lbezier[20](0,10)(90,10) +% \put(95,10){\makebox(100,0){\protect\texttt{lbezier} (21 points)}} +% \lbezier[200](0,-5)(90,-5) +% \put(95,-5){\makebox(100,-5){\protect\texttt{lbezier} (201 points)}} +% \end{picture} +% \end{center} +% \caption{Different line commands} +% \end{figure} +% +% Use \verb+\lbezier+ only in cases where the line you want to plot is not within +% the scope of the \verb+\line+ command, i.e. the slope is not a small rational number +% and/or the length is too small. +% +% \subsubsection{cbezier} +% +% \DescribeMacro{\cbezier} +% Just like the \verb+\lbezier+ macro \verb+\cbezier+ uses no tricks to generate +% the third order polynomial. The examples are from the \Metafont\ book +% (pp. 13)\cite{T3}, where the influence of changing the order of the +% controlling points ($z_1$ up to $z_4$) is also demonstrated. +% +% \begin{verbatim} +% ... +% % z1=(0,16) z2=(40,84) z3=(136,96) z4=(250,0) +% % z12=(20,50) z23=(88,90) z34=(193,48) z123=(54,70) +% % z234=(140.5,69) +% \cbezier[400](0,16)(40,84)(136,96)(250,0) +% \lbezier[30](0,16)(40,84) +% \lbezier[30](40,84)(136,96) +% \lbezier[30](136,96)(250,0) +% \lbezier[30](20,50)(88,90) +% \lbezier[30](88,90)(193,48) +% \lbezier[30](54,70)(140.5,69) +% ... +% \end{verbatim} +% \begin{figure}[hbt] +% \begin{center} +% \begin{picture}(250,100) +% \put(-10,-10){\framebox(270,115){}} +% \cbezier[400](0,16)(40,84)(136,96)(250,0) +% \lbezier[30](0,16)(40,84) +% \lbezier[30](40,84)(136,96) +% \lbezier[30](136,96)(250,0) +% \lbezier[30](20,50)(88,90) +% \lbezier[30](88,90)(193,48) +% \lbezier[30](54,70)(140.5,69) +% \end{picture} +% \end{center} +% \caption{Iteration scheme for one point} +% \end{figure} +% +% +% \DescribeMacro{\Cbezier} +% The variant \verb+\Cbezier+ draws also dots and lines for the controlling points (see +% Fig.\ 6)\footnote{It resets also the plot symbol to the standard one; cf. Section 7}. +% +% +% \begin{figure}[hbt] +% \begin{center} +% \begin{picture}(184,100) +% \put(-10,-10){\framebox(204,100){}} +% \Cbezier[200](0,50)(12,72)(43,78)(84,50) +% \Cbezier[200](100,50)(143,78)(112,72)(184,50) +% \Cbezier[200](12,22)(0,0)(43,28)(84,0) +% \Cbezier[200](100,0)(184,0)(112,22)(143,28) +% \end{picture} +% \end{center} +% \caption{Examples for cubic curves with varying the order of the controlling points} +% \end{figure} +% +% \subsection{Circles and Arcs} +% +% All complex plotting commands in this package +% use a variant of \verb+\cbezier+ as building block. As +% in the \Metafont\ book circles and arcs may be represented by +% \verb+\cbezier+. +% +% To illustrate the procedure of the macro +% we do one calculation explicitely. +% +% E.g. we want to draw the upper right quarter of a circle with end points $z_1=(0,r)$ +% and $z_4=(r,0)$. $z_2$ and $z_3$ determine the tangents. So we may introduce +% them as $z_2=(h,r)$ and $z_3=(r,h)$ with a---so far unspecified---parameter +% $h$. +% +% \begin{figure}[hbt] +% \begin{center} +% \begin{picture}(50,50) +% \put(20,10){\line(1,0){30}} +% \put(20,10){\line(0,1){30}} +% \put(20,40){\line(1,0){10}} +% \put(50,10){\line(0,1){10}} +% \put(30,40){\line(1,-1){20}} +% \put(20,40){\makebox(0,0){$\bullet$}} +% \put(50,20){\makebox(0,0){$\bullet$}} +% \put(30,40){\makebox(0,0){$\bullet$}} +% \put(50,10){\makebox(0,0){$\bullet$}} +% \put(5,35){$z_1$} +% \put(45,0){$z_4$} +% \put(52,18){$z_3$} +% \put(25,45){$z_2$} +% \put(-5,-10){\framebox(70,70){}} +% \end{picture} +% \end{center} +% \caption{Sketch for the geometrical configuration} +% \end{figure} +% +% If we substitute all points in the formula for the Bernste\u\i{}n +% polynomial for both components, we end at (for $t=1/2$) +% \[ x[\frac{1}{2}]=y[\frac{1}{2}]=\frac{r}{2}+\frac{3h}{8}\] +% These values should be $r/\sqrt{2}$ for a circle. +% So we arrive at +% \[ h=\frac{4}{3}\left(\sqrt{2}-1\right).\] +% +% \DescribeMacro{\cArc} +% \DescribeMacro{\cCircle} +% The plot commands are: +% \begin{verbatim} +% \cArc[n](xm,ym)(x1,y1) +% \cCircle[n](xm,ym){r}[loc] +% \end{verbatim} +% +% The optional qualifier $n$ determines the number +% of plotted points (There are as before $n+1$ plotted points for arcs; for circles the +% number depends on the specifier \textit{loc} and may be $n+1$, $2n+2$, or $4n+4$.). +% +% \verb+\cArc+ plots a half circle with centre $(x_m,y_m)$ and $x$-axis through +% $(x_1,y_1)$ counterclockwise. +% +% $r$ is the radius of the circle, specified as decimal constant in terms of +% \verb+\unitlength+. +% +% \verb+\cCircle+ plots full, halves and quarters of circles by specifying +% \textit{loc} (see the corresponding table). +% +% \begin{table}[hbtp] +% \caption{Location specifiers for \texttt{cCircle}s} +% \begin{center} +% \begin{tabular}{|l|l|} +% \hline +% \textit{loc} & specifies \dots\\ +% \hline +% \texttt{f} & full circle\\ +% \texttt{l} & left half circle\\ +% \texttt{r} & right half circle\\ +% \texttt{b} & bottom half circle\\ +% \texttt{t} & top half circle\\ +% \texttt{lb} or \texttt{bl} & left bottom quarter of the circle\\ +% \texttt{lt} or \texttt{tl} & left top quarter of the circle\\ +% \texttt{rb} or \texttt{br} & right bottom quarter of the circle\\ +% \texttt{rt} or \texttt{tr} & right top quarter of the circle\\ +% \hline +% \end{tabular} +% \end{center} +% \end{table} +% +% \begin{figure}[hbtp] +% \begin{center} +% \begin{picture}(300,100) +% \cCircle[1600](150,50){50}[f] +% \cCircle[150](100,0){50}[tr] +% \cCircle[150](100,100){50}[br] +% \cCircle[150](200,0){50}[tl] +% \cCircle[150](200,100){50}[bl] +% \cCircle[200](50,90){45}[b] +% \cCircle[200](50,0){45}[t] +% \cCircle[200](5,45){45}[r] +% \cCircle[200](95,45){45}[l] +% \cArc[200](250,70)(280,50) +% \cArc[200](250,60)(280,50) +% \cArc[200](250,50)(280,50) +% \cArc[200](250,40)(280,50) +% \cArc[200](250,30)(280,50) +% \put(-10,-10){\framebox(320,120){}} +% \end{picture} +% \end{center} +% \caption{Examples for \texttt{cCircle} and \texttt{cArc}} +% \end{figure} +% % +% +% \section{Fitting Arcs} +% +% The quality of representating arcs by cubic bezier curves is quite +% satisfactory. The differences between circles and beziers may be +% estimated in two ways. +% +% \begin{enumerate} +% \item If we test the overall fit the area enclosed by +% the curves is a good metric: The area of \texttt{Carc} for the quarter circle +% is $1/30 (-33+40\sqrt{2})r^2$ to be conferred with $\pi/4\:r^2$. This is an overshot +% by just 0.028\%! +% \item The pointwise fit is measured by the radial difference. +% The maximum is $\cong 0.00025\,r$ (at odd multiples of $\pi/8$), +% it is zero for all multiples of $\pi/4$. +% \end{enumerate} +% +% \section{Some \TeX{}nical Notes} +% +% For the macros therein a lot of counters and lengths have to +% be declared.\footnote{Although I reuse some internal lengths I had to +% declare some more to be used in function calls.} +% Counters represent integer numbers, lengths are +% ``real'' numbers (actually they are just integer multiples of +% $1/65536=2^{-16}$). \TeX\ has just a limited number of these +% stacks and therefore I use the same counters/lengths in all the macros. +% +% One cannot store a real number for further use in these internal stacks just a +% multiplication of a \textit{decimal constant} with a length is possible (counters +% may be multiplied also with real numbers but just the integer part of the decimal +% constant is used!) +% +% The package \Lpack{calc} introduced in the \LaTeX\ Companion\cite{T4} adds a +% new possiblity for multiplying lengths with the ratio of two lengths. This feature will be +% utilized furthermore. +% +% \section{Calculating Lengths} +% +% If I define lengths with respect to some \verb+\unitlength+ I can now define a +% product or fraction of two lengths: +% +% \verb+\lengthc = \lengtha*\ratio{\lengthb}{\unitlength}+ +% +% and +% +% \verb+\lengthc = \unitlenght*\ratio{\lengtha}{\lengthb}+ +% +% The dimension of \verb+\lengthc+ \textit{in terms of} \verb+\unitlength+ (!) is the +% product, or factor respectively, of the two other lengths. +% +% With these operations it is even possible to +% calculate square roots. Simply use the iteration scheme ($m$ integer) +% \[ \xi_{m+1}=\frac{1}{2}\left( \xi_m + \frac{a}{\xi_m} \right) \] +% which will converge fast (with accuracy \verb+\eps+=1\,sp) to $\sqrt a$ (starting with +% $\xi_0=a>0$). +% +% +% Lengths (in a \texttt{picture} environment) are easily calculated too, one just has to +% care for the upper limits (the maximum length for \TeX\ is roughly 16384\,pt!). +% +% \DescribeMacro{\LenMult} +% \DescribeMacro{\LenDiv} +% \DescribeMacro{\AbsLen} +% \DescribeMacro{\LenSqrt} +% \DescribeMacro{\Length} +% \DescribeMacro{\LenNorm} +% The macros are: +% \begin{itemize} +% \item \verb+\LenMult#1#2#3+ and \verb+\LenDiv#1#2#3+ with two input and one output length +% (\verb+#3+). +% \item \verb+\AbsLen#1+ which returns the input length as positive length +% (\TeX\ lengths can be negative!). +% \item \verb+\LenSqrt#1#2+ returns in the length \verb+#2+ the square root of length \verb+#1+ +% (to say it again: measured in terms of \verb+\unitlength+). +% \item \verb+\Length(#1,#2)(#3,#4)#5+ stores in \verb+#5+ the length of the line +% segment between points \verb+(#1,#2)+ and \verb+(#3,#4)+ (coordinates may be decimal +% constants as in the \texttt{picture} commands). +% \item \verb+\LenNorm#1#2#3+ returns in \verb+#3+ the length of the hypothenuse of the +% rectangular triangle with catheti \verb+#1+ and \verb+#2+. +% \end{itemize} +% +% \DescribeMacro{\eps} +% \textbf{All calculations} can be only exact up to the smallest length in \TeX\ which is +% \verb+\eps+=1\,sp=$2^{-16}$\,pt=0.000015\,pt. +% +% Examples (\verb+\unitlength+=1\,pt): +% \begin{verbatim} +% Mult: \LenMult{3pt}{4.333333pt}{\PathLength}\the\PathLength +% Div: \LenDiv{3pt}{4.3333333pt}{\PathLength}\the\PathLength +% Abs: \setlength{\PathLength}{-10pt}\the\PathLength\ +% \AbsLen{\PathLength}\the\PathLength +% Sqrt: \LenSqrt{16pt}{\PathLength}\the\PathLength\ +% \LenSqrt{2pt}{\PathLength}\the\PathLength\ +% \Length(1.5,4.3)(2.7,5){\PathLength}\the\PathLength\ +% \LenNorm{3pt}{4pt}{\PathLength}\the\PathLength +% \end{verbatim} +% +% Mult: \LenMult{3pt}{4.333333pt}{\PathLength}\the\PathLength\ (exact: 13\,pt) +% +% Div: \LenDiv{3pt}{4.333333pt}{\PathLength}\the\PathLength\ (exact: 0.692308\,pt) +% +% Abs: \setlength{\PathLength}{-10pt}\the\PathLength\ +% \AbsLen{\PathLength}\the\PathLength +% +% Sqrt: \LenSqrt{16pt}{\PathLength}\the\PathLength\ (exact: 4\,pt)\ +% \LenSqrt{2pt}{\PathLength}\the\PathLength\ (exact: 1.414213\,pt) +% +% \hspace*{10mm} \Length(1.5,4.3)(2.7,5){\PathLength}\the\PathLength\ (exact: 1.389244\,pt) +% \LenNorm{3pt}{4pt}{\PathLength}\the\PathLength (exact: 5\,pt) +% +% \DescribeMacro{\PathLengthQ} +% \DescribeMacro{\PathLengthC} +% \DescribeMacro{\PathLength} +% \DescribeMacro{\pathmax} +% Furthermore you can use these macros to evaluate the length of linear interpolations +% of the curves displayed by \verb+\qbezier+ and \verb+\cbezier+. The syntax is +% \verb+\PathLengthQ[n](x1,y1)(x2,y2)(x3,y3)+ and\\ +% \verb+\PathLengthC[n](x1,y1)(x2,y2)(x3,y3)(x4,y4)+ respectively. $n$ is the +% number of interpolation points which is bounded by \verb+\pathmax+=50. The length +% is stored in the% +% ---already defined and used---length \verb+\PathLength+. Note: $n$ is \emph{not} optional +% for these two macros. +% +% Example: For the cubic spline\\ +% \verb+\cbezier[200](0,0)(50,100)(50,0)(100,100)+ +% shown in Fig.~9 the results of the \verb+\PathLength+ \\ +% for $n$=2,5,10,20,30,40,50 +% are displayed below. You may increase the value of \verb+\pathmax+ as for +% \verb+\qbeziermax+ but the result will due to the internal calculation problems +% not become sigificant better. +% +% \begin{figure}[hbt] +% \begin{center} +% \begin{picture}(100,80) +% \put(0,0){\framebox(100,100){}} +% \cbezier[300](0,0)(50,100)(50,0)(100,100) +% \end{picture} +% \end{center} +% \caption{A nice cubic curve} +% \end{figure} +% +% The results are: \PathLengthC[2](0,0)(50,100)(50,0)(100,100)\the\PathLength, +% \PathLengthC[5](0,0)(50,100)(50,0)(100,100)\the\PathLength, +% \PathLengthC[10](0,0)(50,100)(50,0)(100,100)\the\PathLength, +% \PathLengthC[20](0,0)(50,100)(50,0)(100,100)\the\PathLength, +% \PathLengthC[30](0,0)(50,100)(50,0)(100,100)\the\PathLength, +% \PathLengthC[40](0,0)(50,100)(50,0)(100,100)\the\PathLength, +% \PathLengthC[50](0,0)(50,100)(50,0)(100,100)\the\PathLength. +% (An good numercial integration program will yield more accurate 149.999.) +% +% \section{More general arcs} +% +% \DescribeMacro{\cArcs} +% Finally you can plot an arc (i.e.\ a cubic approximation to the circle arc) between +% two points with given centre of the circle:\\ +% \verb+\cArcs[n](xm,ym)(x1,y1)(x2,y2)+\\ +% with $n+1$ number of points (limited by +% \verb+\qbeziermax+ again) and centre $(x_m,y_m)$. +% +% \begin{figure}[hbt] +% \begin{center} +% \begin{picture}(200,200) +% \put(0,0){\framebox(200,200){}} +% \put(100,100){\makebox(0,0){$\bullet$}} +% \cArcs[300](100,100)(120,130)(130,120) +% \cArcs[100](100,100)(150,110)(110,150) +% \cArcs[300](100,100)(130,180)(130,20) +% \cArcs[300](100,100)(120,170)(80,170) +% \cArcs[300](100,100)(60,150)(60,50) +% \cArcs[100](100,100)(90,90)(110,90) +% \cArcs[200](100,100)(60,70)(130,60) +% \end{picture} +% \end{center} +% \caption{Some examples for arcs; the centre is marked by $\bullet$} +% \end{figure} +% +% Limitations: +% \begin{itemize} +% \item The arc should be smaller than the half of a circle (The limit is +% handled by \verb+\cArc+ and is built-in again in \verb+\cArcs+.) Otherwise the shape +% will become ``elliptic'' and ly in the wrong half plane. +% \item There is no check for consistency if $r_1^2=(x_1-x_m)^2+(y_1-y_m)^2$ and +% $r_2^2=(x_2-x_m)^2+(y_2-y_m)^2$ are really equal. The graph will contain in any case +% both points as border points. +% \end{itemize} +% I will shortly derive the formulas used in the code. The code is even more tricky +% due to the fact that I had just a limited number of lengths and the code reuses +% some lengths explicitely and implicitely by calling routines. +% +% \begin{figure}[hbt] +% \begin{center} +% \begin{picture}(200,200) +% \put(0,0){\framebox(200,200){}} +% \put(80,20){\makebox(0,0){$\bullet$}} +% \put(50,120){\makebox(0,0){$\bullet$}} +% \put(171.65,70){\makebox(0,0){$\bullet$}} +% \put(100,135){\makebox(0,0){$\bullet$}} +% \put(146.65,115.825){\makebox(0,0){$\bullet$}} +% \put(120.3,115.6){\makebox(0,0){$\bullet$}} +% \lbezier[150](80,20)(50,120) +% \lbezier[150](80,20)(171.65,70) +% \cArcs[200](80,20)(50,120)(171.65,70) +% \lbezier[150](50,120)(150,150) +% \lbezier[150](171.65,70)(121.65,161.65) +% \lbezier[30](80,20)(141.65,170) +% \put(66,21){$M$} +% \put(41,115){4} +% \put(174,65){1} +% \put(90,135){3} +% \put(150,112){2} +% \put(116,120){5} +% \end{picture} +% \end{center} +% \caption{Sketch for the geometric situation} +% \end{figure} +% +% We know the coordinates for the points $M$, 1, and 4. The tangents $\overline{43}$ and +% $\overline{12}$ are normals to the radius in the corresponding points. The distances +% $\overline{43}$ and $\overline{12}$ should be equal. 5 lies on the symmetry axis (dotted +% line) with distance $r$ from $M$. +% +% \noindent Normal vectors: $\vec n_1=(y_m-y_1,x_1-x_m)$ and $\vec n_2=(y_4-y_m,x_m-x_4)$ +% +% \noindent Coordinate vectors: $\vec 2 = \vec 1 + \lambda \vec n_1$ and +% $\vec 3 = \vec 4 + \lambda \vec n_2$ ($\lambda$ is the same because both normal +% vectors have length $r$) +% +% \noindent Furthermore $\vec 5={\cal B}_4 [1/2]$ (the cubic spline +% should also be symmetric and contain 5) +% +% Now we have: +% \begin{eqnarray} +% x[ t] & = & (1-t)^3 x_1 + 3 t (1-t)^2 x_2 + 3 t^2 (1-t) x_3 +t^3 x_4\\ +% y[ t] & = & (1-t)^3 y_1 + 3 t (1-t)^2 y_2 + 3 t^2 (1-t) y_3 +t^3 y_4 +% \end{eqnarray} +% +% Substituting for $x_2$, $y_2$, $x_3$, and $y_3$ and $t\to1/2$: +% \begin{eqnarray} +% x_5=x\left[ \frac{1}{2}\right] & = & \frac{1}{2} +% (x_1 +x_4) + \frac{3}{8} \lambda(y_4-y_1) \\ +% y_5=y\left[ \frac{1}{2}\right] & = & \frac{1}{2} +% (y_1 +y_4) + \frac{3}{8} \lambda(x_1-x_4 ) +% \end{eqnarray} +% +% We could now calculate the norm of this point and set it equal to the radius $r^2= +% (x_m-x_1)^2+(y_m-y_1)^2$. This gives a quadratic equation for +% $\lambda$. But the result is a rather complex term with respect to our input parameters. +% +% A nicer term can be found if we define +% \begin{equation} +% x_5=x_m+\kappa (x_1+x_4-2x_m) \quad y_5=y_m+\kappa (y_1+y_4-2y_m) +% \end{equation} +% with aid of the symmetry vector. $\kappa$ is simply $r$ divided by the norm of the +% symmetry vector. +% +% The resulting $\lambda$ is now (using just the $x$-equation) +% \begin{equation} +% \lambda=\frac{4}{3} (-1+2 \kappa)\frac{x_1+x_4-2x_m}{y_4-y_1} +% \end{equation} +% +% Special cases: +% \begin{itemize} +% \item The symmetry vector is the null vector if $\overline{14}$ is a diameter of the +% circle. But this case is already solved by \verb+\cArc+. +% \item For $y_4=y_1$ one needs the equation for the $y$-component, i.e.\ we have as factor +% $(y_1+y_4-2y_m)/(x_1-x_4)$ in $\lambda$. +% \end{itemize} +% +% +% \section{Varying the line thickness} +% +% There is another package, \Lpack{bez123}\cite{T5}, which introduces also linear and cubic +% bezier curves, even variants which plot exactly all kind of conic curves (ellipses, +% parabolas, and hyperbolas). There are two features in \Lpack{bez123}, which I added in the +% third version of \Lpack{ebezier}: +% +% \DescribeMacro{\thinlines} +% \DescribeMacro{\thicklines} +% \DescribeMacro{\linethickness} +% \DescribeMacro{\qbeziermax} +% \begin{enumerate} +% \item Changing the size of the plot squares by the \LaTeX\ commands\\ +% \verb+\thinlines+, \verb+\thicklines+, and/or \verb+\linethickness+. +% \item Calulation of an optimal number of plot points if $n$=0 instead of using the +% maximum \verb+\qbeziermax+ (see next section). +% \end{enumerate} +% +% If you look close to lines you will note some peculiarity. For instance the original +% \LaTeX\ \verb+\line+ is in horizontal/vertical mode a simple \verb+\ruler+. +% +% \begin{figure}[htbp] +% \begin{center} +% \begin{picture}(100,100) +% \thinlines +% \put(-5,-5){\framebox(110,110){}} +% \setlength{\linethickness}{0.1pt} +% \put(0,10){\line(1,0){100}} +% \put(10,0){\line(0,1){100}} +% \setlength{\linethickness}{10pt} +% \put(10,10){\line(1,0){60}} +% \put(10,10){\line(0,1){60}} +% \end{picture} +% \end{center} +% \caption{Axes with standard lines} +% \end{figure} +% +% Remark: The \textit{line} is exactly as long as specified. +% +% \DescribeMacro{\@wholewidth} +% But the plot point used by \verb+\qbezier+, \Lpack{bez123} and \Lpack{ebezier} +% (until version 2!) is a small square which is not centered at the control points +% (dimension \verb+\@wholewidth+) +% +% \begin{figure}[htbp] +% \begin{center} +% \begin{picture}(50,50) +% \thinlines +% \put(-5,-5){\framebox(60,60){}} +% \setlength{\linethickness}{0.1pt} +% \put(0,25){\line(1,0){50}} +% \put(15,0){\line(0,1){50}} +% \DefOldPlotSymbol +% \setlength{\linethickness}{10pt} +% \lbezier[1](15,25)(15,25) +% \end{picture} +% \end{center} +% \caption{Old plot symbol} +% \end{figure} +% +% which results in a shifted $y$-axis and \textit{lines} which are actually longer +% by an amount of one square (i.e. \verb+\@wholewidth+) +% +% \begin{figure}[htbp] +% \begin{center} +% \begin{picture}(100,100) +% \thinlines +% \put(-5,-5){\framebox(110,110){}} +% \setlength{\linethickness}{0.1pt} +% \put(0,10){\line(1,0){100}} +% \put(10,0){\line(0,1){100}} +% \setlength{\linethickness}{10pt} +% \DefOldPlotSymbol +% \setlength{\linethickness}{10pt} +% \lbezier[10](10,10)(80,10) +% \lbezier[10](10,10)(10,80) +% \end{picture} +% \end{center} +% \caption{Axes with old plot symbol} +% \end{figure} +% +% or with hollow squares ($\bullet$ references to the end points). +% +% \begin{figure}[htbp] +% \begin{center} +% \begin{picture}(100,100) +% \thinlines +% \put(-5,-5){\framebox(110,110){}} +% \setlength{\linethickness}{0.1pt} +% \put(0,10){\line(1,0){100}} +% \put(10,0){\line(0,1){100}} +% \thinlines +% \put(10,5){\framebox(70,10){}} +% \put(10,5){\framebox(10,70){}} +% \put(10,5){\framebox(10,10){}} +% \put(70,5){\framebox(10,10){}} +% \put(10,65){\framebox(10,10){}} +% \put(10,10){\makebox(0,0){$\bullet$}} +% \put(70,10){\makebox(0,0){$\bullet$}} +% \put(10,70){\makebox(0,0){$\bullet$}} +% \end{picture} +% \end{center} +% \caption{Axes with old plot symbol (hollow)} +% \end{figure} +% +% +% This version uses centered plot symbols (standard is again a square) +% +% \begin{figure}[htbp] +% \begin{center} +% \begin{picture}(50,50) +% \put(-5,-5){\framebox(60,60){}} +% \setlength{\linethickness}{0.1pt} +% \put(0,25){\line(1,0){50}} +% \put(25,0){\line(0,1){50}} +% \DefStandardPlotSymbol +% \setlength{\linethickness}{10pt} +% \lbezier[1](25,25,)(25,25) +% \end{picture} +% \end{center} +% \caption{New standard plot symbol} +% \end{figure} +% +% which corrects the shift of the $y$-axis. The line is again longer but this +% time the excess is symmetrically on both ends +% +% \begin{figure}[htbp] +% \begin{center} +% \begin{picture}(100,100) +% \thinlines +% \put(-5,-5){\framebox(110,110){}} +% \setlength{\linethickness}{0.1pt} +% \put(0,10){\line(1,0){100}} +% \put(10,0){\line(0,1){100}} +% \setlength{\linethickness}{10pt} +% \lbezier[10](10,10)(80,10) +% \lbezier[10](10,10)(10,80) +% \end{picture} +% \end{center} +% \caption{Axes with new standard plot symbol} +% \end{figure} +% +% or again with hollow squares. +% +% \begin{figure}[htbp] +% \begin{center} +% \begin{picture}(100,100) +% \thinlines +% \put(-5,-5){\framebox(110,110){}} +% \setlength{\linethickness}{0.1pt} +% \put(0,10){\line(1,0){100}} +% \put(10,0){\line(0,1){100}} +% \thinlines +% \put(5,5){\framebox(70,10){}} +% \put(5,5){\framebox(10,70){}} +% \put(5,5){\framebox(10,10){}} +% \put(65,5){\framebox(10,10){}} +% \put(5,65){\framebox(10,10){}} +% \put(10,10){\makebox(0,0){$\bullet$}} +% \put(70,10){\makebox(0,0){$\bullet$}} +% \put(10,70){\makebox(0,0){$\bullet$}} +% \end{picture} +% \end{center} +% \caption{Axes with new standard plot symbol (hollow)} +% \end{figure} +% +% \DescribeMacro{\DefOldPlotSymbol} +% \DescribeMacro{\Qbezier} +% To be consistent with the old version the command \verb+\DefOldPlotSymbol+ +% is supplied which uses the old form. Also a variant \verb+\Qbezier+ for +% \verb+\qbezier+ is +% defined which can use the new plot symbol.\footnote{This command is just for convenience. +% A quadratic bezier can be plotted as cubic bezier as follows. If you want to plot +% $\backslash$\texttt{qbezier[100](z1)(zm)(z4)} with $(z)=(x,y)$ you may calulate points +% $z_2=2/3[z_m,z_1]$ and $z_3=2/3[z_m,z_4]$. The cubic bezier $\backslash$% +% \texttt{cbezier[100](z1)(z2)(z3)(z4)} is exactly the same as the quadratic one!}% +% \footnote{It can also use the other new symbols defined later.} +% +% The next point of consideration is the handling of slanted lines. +% In the ordinary \LaTeX-\texttt{picture} environment +% \verb+\linethickness+ has no effect on slanted lines. Now the change applies +% but a new problem occurs. If you plot a slanted line (slope angle $\varphi$) +% with squares +% +% \begin{figure}[htb] +% \begin{center} +% \begin{picture}(100,80) +% \thinlines +% \put(-5,-5){\framebox(110,90){}} +% \put(5,5){\framebox(30,30){}} +% \put(25,15){\framebox(30,30){}} +% \put(45,25){\framebox(30,30){}} +% \put(65,35){\framebox(30,30){}} +% \put(35,5){\line(2,1){70}} +% \put(5,35){\line(2,1){70}} +% \put(60,5){\vector(-1,2){5}} +% \put(55,15){\line(-1,2){23}} +% \put(32.5,60){\vector(1,-2){5}} +% \put(61,22){$\scriptscriptstyle\varphi$} +% \put(32,47){$\scriptscriptstyle\varphi$} +% \put(65,10){$d$} +% \end{picture} +% \end{center} +% \caption{Effective thickness for slanted lines} +% \end{figure} +% +% your line gets effective thicker! The factor of enlargement is $\sin \varphi +% +\cos \varphi$ which has its maximum $\sqrt 2$ with slope $\varphi_0=45^0$. +% +% +% There are two possiblities to correct the thickness +% \begin{itemize} +% \item correct the line thickness of each line or +% \item use other plot symbols which behave better. +% \end{itemize} +% +% \DescribeMacro{\Lbezier} +% The first possibilitiy can be realized just for \verb+\lbezier+ and not +% \verb+\cbezier+ because the slope changes from point to point in the latter case. +% The solution is established by internally changing the \verb+\linethickness+ +% by the factor $\ell/(\Delta x+\Delta y)$ where $\ell$ denotes the length of the +% line ($=\sqrt{\Delta^2 x +\Delta^2 y}$) +% and $\Delta x$ is the horizontal difference of the the points +% ($\Delta y$ respectivelly for the vertical difference). +% +% To use this line type call \verb+\Lbezier[n](x1,y1)(x2,y2)+. +% +% The second chance is to change the plot symbol to a disc. The smallest disk +% available is the character ``.'' at 5pt. Unfortunately this method will +% implicitely restrict the \verb+\linethickness+ to some definite values (see the +% following table for the numbers in question). +% +% \begin{table}[hbtp] +% \caption{Dimensions for various plot symbols} +% \begin{center} +% \begin{tabular}{|ll|rr|l|} +% \hline +% Font&Size for (10pt) & Width & Heigth & Rule \\ +% \hline +% \verb+\vrm+ &tiny& \SB{\vrm}{.}\the\wd1 & \SB{\vrm}{.}\the\ht1 & +% \SB{\vrm}{.}\rule{1 cm}{\ht1} \copy1\\ +% \verb+\virm+ &tiny for 11/12pt& \SB{\virm}{.}\the\wd1 & \SB{\virm}{.}\the\ht1 & +% \SB{\virm}{.}\rule{1 cm}{\ht1} \copy1\\ +% \verb+\viirm+ & scriptsize &\SB{\viirm}{.}\the\wd1 & \SB{\viirm}{.}\the\ht1 & +% \SB{\viirm}{.}\rule{1 cm}{\ht1} \copy1\\ +% \verb+\viiirm+ & footnotesize & \SB{\viiirm}{.}\the\wd1 & \SB{\viiirm}{.}\the\ht1 & +% \SB{\viiirm}{.}\rule{1 cm}{\ht1} \copy1\\ +% \verb+\ixrm+ & small &\SB{\ixrm}{.}\the\wd1 & \SB{\ixrm}{.}\the\ht1 & +% \SB{\ixrm}{.}\rule{1 cm}{\ht1} \copy1\\ +% \verb+\xrm+ & normalsize &\SB{\xrm}{.}\the\wd1 & \SB{\xrm}{.}\the\ht1 & +% \SB{\xrm}{.}\rule{1 cm}{\ht1} \copy1\\ +% \verb+\xirm+ & normalsize 11pt& \SB{\xirm}{.}\the\wd1 & \SB{\xirm}{.}\the\ht1 & +% \SB{\xirm}{.}\rule{1 cm}{\ht1} \copy1\\ +% \verb+\xiirm+ & large &\SB{\xiirm}{.}\the\wd1 & \SB{\xiirm}{.}\the\ht1 & +% \SB{\xiirm}{.}\rule{1 cm}{\ht1} \copy1\\ +% \verb+\xivrm+ & Large & \SB{\xivrm}{.}\the\wd1 & \SB{\xivrm}{.}\the\ht1 & +% \SB{\xivrm}{.}\rule{1 cm}{\ht1} \copy1\\ +% \verb+\xviirm+ & LARGE &\SB{\xviirm}{.}\the\wd1 & \SB{\xviirm}{.}\the\ht1 & +% \SB{\xviirm}{.}\rule{1 cm}{\ht1} \copy1\\ +% \verb+\xxrm+ & huge &\SB{\xxrm}{.}\the\wd1 & \SB{\xxrm}{.}\the\ht1 & +% \SB{\xxrm}{.}\rule{1 cm}{\ht1} \copy1\\ +% \verb+\xxvrm+ & Huge &\SB{\xxvrm}{.}\the\wd1 & \SB{\xxvrm}{.}\the\ht1 & +% \SB{\xxvrm}{.}\rule{1 cm}{\ht1} \copy1\\ +% \verb+$\bullet$+ & &\SB{$\bullet$}{}\the\wd1 &\SB{$\bullet$}{}\the\ht1& +% \SB{$\bullet$}{}\rule{1cm}{\ht1} \copy1\\ +% \hline +% \end{tabular} +% \end{center} +% \end{table} +% +% \DescribeMacro{\DefPlotSymbol} +% With the aim of the command \verb+\DefPlotSymbol{item}+ you may define any +% \textit{item} as your plot symbol\footnote{A similar approach with centered +% symbols can be found in the packages +% \Lpack{epic}\cite{epic} and PiC\TeX\cite{pictex}.}. +% It will be centered as the default plot square +% (otherwise an even larger shift of the $y$-axis would occur). Use explicit font +% selection with the names supplied in the table to ensure style independence +% (otherwise e.g.\ +% \verb+\DefPlotSymbol{\tiny .}+ would be different in 10pt and 11pt context). +% +% \DescribeMacro{\DefShiftedPlotSymbol} +% This works +% for all \textit{items} which have a vertical symmetry axis with respect to their +% defining bounding box (defined by \Metafont) and which ly on the baseline +% (or beyond if they have some defined depth). It will not work otherwise. For example the +% circles from the circle font have heigth and depth zero and their reference point is +% already the centre (i.e. the symbol extends backward). Or consider the ``*''-sign. +% It does not ly on the baseline. For these cases a generalized command is supplied:\\ +% \verb+\DefShiftedPlotSymbol{item}{x-shift}{y-shift}{height}+. +% +% The shifts are applied +% to the left and downward. The supplied heigth will only have effect if you specify +% $n=0$ for the number of plotting points. +% +% Examples: +% \begin{verbatim} +% \DefShiftedPlotSymbol{\tencirc n}{0pt}{0pt}{1pt} +% \DefShiftedPlotSymbol{\tencirc \char'176}{0pt}{0pt}{15pt} +% \DefShiftedPlotSymbol{\fbox{\Huge *}}{0pt}{0pt}{25pt} +% %with bounding box +% \setbox0=\hbox{*} +% \DefShiftedPlotSymbol{*}{.5\wd0}{.7\ht0}{.6\ht0} +% \lbezier[1](100,30)(100,30) +% \lbezier[0](0,20)(125,20) +% \DefShiftedPlotSymbol{*}{.5\wd0}{.7\ht0}{10\ht0} +% \lbezier[0](0,10)(125,10) +% \end{verbatim} +% +% \setlength{\fboxsep}{0pt} +% \setlength{\fboxrule}{0.1pt} +% +% \begin{figure}[hbtp] +% \begin{center} +% \begin{picture}(125,50) +% \put(-5,-5){\framebox(135,60){}} +% \setlength{\linethickness}{0.1pt} +% \put(0,30){\line(1,0){125}} +% \multiput(25,20)(25,0){4}{\line(0,1){20}} +% \DefShiftedPlotSymbol{\tencirc n}{0pt}{0pt}{1pt} +% \lbezier[1](25,30)(25,30) +% \DefShiftedPlotSymbol{\tencirc \char'176}{0pt}{0pt}{15pt} +% \lbezier[1](50,30)(50,30) +% \DefShiftedPlotSymbol{\fbox{\Huge *}}{0pt}{0pt}{25pt} +% \lbezier[1](75,30)(75,30) +% \setbox0=\hbox{*} +% \DefShiftedPlotSymbol{*}{.5\wd0}{.7\ht0}{.6\ht0} +% \lbezier[1](100,30)(100,30) +% \lbezier[0](0,20)(125,20) +% \DefShiftedPlotSymbol{*}{.5\wd0}{.7\ht0}{10\ht0} +% \lbezier[0](0,10)(125,10) +% \end{picture} +% \end{center} +% \caption{Examples for other plot symbols} +% \end{figure} +% +% \emph{Caution:} The commands for changing the line thickness have +% implicit effects for plot symbols +% defined with \verb+\DefPlotSymbol{item}+ or \\ +% \verb+\DefShiftedPlotSymbol+. The implicit or +% explicit defined height is redefined. But the effect is only visible in case $n=0$. +% +% +% \DescribeMacro{\DefStandardPlotSymbol} +% In any case you may restore \textbf{default values} by stating +% \begin{verbatim} +% \DefStandardPlotSymbol +% \thinlines +% \end{verbatim} +% +% \section{Estimation for the number of plotting points} +% +% As mentioned in the last section all plotting macros will calculate the number +% of plotting points if the value $n=0$ is active. All calculations will +% use the actual length of the object which can +% be calculated with the aim of the calculation macros in Section \textit{Calculating Lengths}. +% For all these calculations \verb+\eps+ is temporarily increased by a factor of 10 and +% for higher bezier curves just 5 intermediate points will be used. If the calculated number +% exceeds the specified maximum \verb+\qbeziermax+ an info in the log-file will be generated. +% +% All macros for circles and arcs will use a simpler estimate due to their construction +% by an intrinsic call of the cubic bezier. It uses the length of the chord and +% the maximal deviation factor $\pi/2$ from the arc length. +% +% +% \section{Joining linear beziers} +% +% \DescribeMacro{\ljoin} +% A further command has been supplied to ease the drawing of polygon paths. Instead of +% writing a sequence of \verb+\lbezier+s with common vertices you can write compactly +% \verb+\ljoin[n](x1,y1)(x2,y2)(x3,y3)...(xm,ym)+ +% +% Caution: There should be no spaces in the command, so break lines with \% if +% necessary. There should be at least 2 points. The parameter $n$ is optional, internally +% \verb-\lbezier[n](xk,yk)(xk+1,yk+1)- will be executed. +% +% \DescribeMacro{\Ljoin} +% There is also a variant \verb+\Ljoin+ which uses \verb+\Lbezier+. +% +% \renewcommand{\qbeziermax}{1200} +% \begin{figure} +% \begin{center} +% \begin{picture}(200,100) +% \put(-5,-5){\framebox(210,110){}} +% \begin{picture}(100,100) +% \ljoin(0,0)(20,100)(20,0)(40,50)(40,0)(60,25)(60,0)(80,12.5)(80,0)(100,6.25)(100,0) +% \end{picture} +% \begin{picture}(100,100) +% \Ljoin(0,0)(20,100)(20,0)(40,50)(40,0)(60,25)(60,0)% +% (80,12.5)(80,0)(100,6.25)(100,0) +% \end{picture} +% \end{picture} +% \end{center} +% \caption{$\backslash$\texttt{ljoin} versus $\backslash$\texttt{Ljoin}} +% \end{figure} +% +% \changes{Version 1}{2000/07/28}{original version} +% \changes{Version 2}{2001/12/04}{major bug fix for cCircle} +% \changes{Version 3}{2002/10/23}{major changes} +% \changes{Version 4}{2005/03/01}{minor changes} +% +% \section*{Versions} +% +% This is Version 4 from March 1, 2004. +% +% Changes with regard to version 3: +% \begin{itemize} +% \item Bug-address changed. +% \item Error in defining (first) equation corrected (thanks to \verb+jens.schwaiger@uni-graz.at+). +% \item Marginal corrections with regard to \Lpack{l2tabu} (v1.8). +% \item Documentaion as pdf supplied. +% \end{itemize} +% +% Changes with regard to version 2: +% \begin{itemize} +% \item Implementing line thickness (\verb+\thinlines+, \verb+\thicklines+, and\\ +% \verb+\setlength{\linethickness}{dimen}+. +% \item Different plot symbols. +% \item \verb+\Lbezier+ for equally thick lines in all directions. +% \item \verb+\Qbezier+ implementation to be used with new plot symbols. +% \item Calculation of an optimal number of plot symbols (as default number for case $n$=0). +% \item Parameter $n$ is for all \emph{plot} commands optional. +% \item New macro for polygon paths. +% \item Style supplied in dtx-format. +% \item Minor style changes regarding numbers and lengths. +% \end{itemize} +% +% Changes with regard to Version 1: +% \begin{itemize} +% \item \verb+\@tempa+ replaced by \verb+\@TempDim+. \verb+\@tempa+ was also +% used by other packages. +% \item Additionaly supplied \verb+\RequirePackage{calc}+. +% \item Bug fixed for circles. The original macros did actually not support changes in +% \verb+\unitlength+. +% \end{itemize} +% +% \begin{thebibliography}{9} +% \bibitem{T2} D.\ E.\ Knuth: \textit{The} \TeX\ \textit{Book}, Addison-Wesley, +% Reading MA, 1986. +% \bibitem{T3} D.\ E.\ Knuth: \textit{The} \Metafont\ \textit{Book}, Addison-Wesley, +% Reading MA, 1986. +% \bibitem{T4} M.\ Goossens, F.\ Mittelbach, A.\ Samarin: \textit{The} \LaTeX\ \textit{Companion}, +% Addison-Wesley, Reading MA, 1994. +% \bibitem{T1} M.\ Goossens, S.\ Rahtz, F.\ Mittelbach: \textit{The} \LaTeX\ +% \textit{Graphics Companion}, Addison-Wesley, Reading MA, 1997. +% \bibitem{T5} P.\ Wilson: \textit{The} \Lpack{bez123} \textit{and} \Lpack{multiply} +% \textit{packages}, 1998;\\ packages at CTAN/macros/latex/contrib/supported/bez123. +% \bibitem{epic} S.\ Podar: \textit{Enhancements to the Picture Environment +% in }\LaTeX, 1986;\\ package at CTAN/macros/latex/other/epic. +% \bibitem{pictex} M.\ J.\ Wichura: \textit{The PiC}\TeX\ \textit{Manual}, 1992;\\ +% package at CTAN/graphics/pictex. +% \bibitem{pict2e} R.\ Niepraschk, H.\ Gaesslein: The \Lpack{pict2e} Package, 2003;\\ +% package at CTAN/macros/latex/contrib/pict2e. +% \bibitem{PiX} N.\ J.\ H.\ M.\ van Beurden: A \LaTeX\ picture editor for Windows, 2003;\\ +% package at CTAN/systems/win32/latexpix. +% \end{thebibliography} +% +% \OnlyDescription +% +% \section{Implementation} +% +% The macros \verb+\lbezier+ and \verb+\cbezier+ are rather old, they existed since +% I realized the existence of \Lpack{bezier.sty} more then ten years ago. Therefore +% the macros are written rather in pure \TeX\ than in \LaTeX. Only the calculation +% macros demand for \LaTeX\ notation to use the package \Lpack{calc}. But with this +% version the macros interact more and some \LaTeX\ part occurrs also in the plot macros. +% +% \begin{macrocode} +%<*package> +\NeedsTeXFormat{LaTeX2e} +\RequirePackage{calc} +%% +% \end{macrocode} +% I define new font names because \texttt{cmr} may not be the standard font. They +% may be needed for plotting symbols. +% \begin{macrocode} +\newfont{\vrm}{cmr5} +\newfont{\virm}{cmr6} +\newfont{\viirm}{cmr7} +\newfont{\viiirm}{cmr8} +\newfont{\ixrm}{cmr9} +\newfont{\xrm}{cmr10} +\newfont{\xiirm}{cmr12} +\newfont{\xviirm}{cmr17} +\newfont{\xirm}{cmr10 scaled \magstephalf} +\newfont{\xivrm}{cmr10 scaled \magstep2} +\newfont{\xxrm}{cmr10 scaled \magstep4} +\newfont{\xxvrm}{cmr10 scaled \magstep5} +%% +% \end{macrocode} +% +% I need only three new counters, +% \begin{macrocode} +\newcounter{@cnta}\newcounter{@cntb}\newcounter{@cntc}\newcounter{@cntd} +%% +% \end{macrocode} +% but a lot of lengths. Packages like PiC\TeX\ have problems by defining too many +% lengths, so I try to use as many already defined lengths (defined for usage +% in a plotting context). +% \begin{macrocode} +%% \@TempDim#1#2#3{"count"|"dimen"|"box"|"skip"}{\myname}{\realname} +%% allocate new one or alias is defined, so use it +%% +\def\@TempDim#1#2#3{% + \ifx\@und@fined#3\csname new#1\endcsname#2% + \else\let#2#3\fi} +%% +\@TempDim{dimen}\@X\@ovxx +\@TempDim{dimen}\@Xa\@ovdx +\@TempDim{dimen}\@Xb\@ovyy +\@TempDim{dimen}\@Xc\@ovdy +\@TempDim{dimen}\@Y\@ovro +\@TempDim{dimen}\@Ya\@ovri +\@TempDim{dimen}\@Yb\@xdim +\@TempDim{dimen}\@Yc\@ydim +\@TempDim{dimen}\@Z\@clnht +\@TempDim{dimen}\@Za\@clnwd +\@TempDim{dimen}\@Zb\@dashdim +\@TempDim{dimen}\@Zc\@tempdima +\@TempDim{dimen}\@Zd\@tempdimb +\@TempDim{dimen}\@Ze\@tempdimc +%% +\newlength{\@Zf}\newlength{\@Zg}\newlength{\@Zh} +\newlength{\@Zi}\newlength{\@Zj} +% \end{macrocode} +% +% This special length will be used for the circle macros. The magic number is +% $0.55228474983=4/3 (\sqrt{2}-1)$. +% +% \begin{macrocode} +\newlength{\magicnum} +\newcommand\set@magic{% + \setlength{\magicnum}{0.55228474983\unitlength}} +%% +% \end{macrocode} +% +% Another special one is \verb+\eps+. It could be initialized by \verb+\eps\@ne+ +% but due to its context to the calculation part 1sp=1/65536pt is used. +% +% \begin{macrocode} +\newlength{\eps} +\setlength{\eps}{1sp} +%% +% \end{macrocode} +% +% The last one is \verb+\PathLength+. It stores lengths which the user may need for +% further use. +% +% \begin{macrocode} +\newlength{\PathLength} +%% +% \end{macrocode} +% +% This two constants are needed in calculations, but I did not want to waste +% any additional counter. \verb+\pathmax+ may be redefined to exceed 256, so it +% is not defined by \verb+\chardef+. +% +% \begin{macrocode} +\chardef\x@=10 +\newcommand{\pathmax}{50} +%% +% \end{macrocode} +% +% This fundamental box will keep the plotting symbol. +% +% \begin{macrocode} +\newsavebox{\@pt} +%% +% \end{macrocode} +% +% I have to distinguish three cases: standard plot symbol, old standard plot symbol, +% or any new one. For this purpose I need two logicals. +% +% \begin{macrocode} +\newif\if@other@symbol +\newif\if@standard@symbol +% \end{macrocode} +% +% All plot symbols may be defined by the most general one,\\ +% \verb+\DefShiftedPlotSymbol+, but this way may be faster. The +% other important macro is \verb+\set@width+ which redefines the plot +% box due to changes which may have occurred (line thickness). +% +% \begin{macrocode} +\newcommand{\DefStandardPlotSymbol}{% + \@other@symbolfalse\@standard@symboltrue + \setbox\@pt\hbox{\hskip -.5\wd0\vrule height\@halfwidth + depth\@halfwidth width\@wholewidth}} +\newcommand{\DefOldPlotSymbol}{% + \@other@symbolfalse\@standard@symbolfalse + \setbox\@pt\hbox{\vrule height\@halfwidth + depth\@halfwidth width\@wholewidth}} +\newcommand{\DefPlotSymbol}[1]{\setbox0=\hbox{#1}\@X\ht0\advance\@X-\dp0 + \@halfwidth.5\ht0\@wholewidth\ht0 + \@other@symboltrue\@standard@symbolfalse + \setbox\@pt\hbox{\hskip -.5\wd0\lower.5\@X\copy0}} +\newcommand{\DefShiftedPlotSymbol}[4]{\setbox0=\hbox{#1}\@X #2\@Y #3 + \@wholewidth #4\@halfwidth.5\@wholewidth + \@other@symboltrue\@standard@symbolfalse + \setbox\@pt\hbox{\hskip-\@X\lower\@Y\copy0}} +\newcommand{\set@width}{% + \if@other@symbol + \relax + \else + \if@standard@symbol + \@X-.5\@wholewidth + \else + \@X\z@ + \fi + \setbox\@pt\hbox{\hskip\@X\vrule height\@halfwidth + depth\@halfwidth width\@wholewidth}% + \fi} +%% +% \end{macrocode} +% +% The initialization is done here. Note that \verb+\thinlines+ +% is already default and needs not be specified here. +% +% \begin{macrocode} +\DefStandardPlotSymbol +%% +% \end{macrocode} +% +% All plot macros have an optional number. Therefore an additional internal macro +% is needed (it will have the same name with an extra @ in front of it. +% +% Here is the simpliest one, the linear case. +% +% \begin{macrocode} +\def\lbezier{\@ifnextchar [{\@lbezier}{\@lbezier[0]}} +\def\@lbezier[#1](#2,#3)(#4,#5){% + \c@@cntc#1\relax + \ifnum \c@@cntc<\@ne +% \end{macrocode} +% +% I decrease the precision locally to speed up calculations. We need just +% an estimate. +% +% \begin{macrocode} + \multiply\eps\x@ + \Length(#2,#3)(#4,#5){\PathLength}% + \divide\eps\x@ + \c@@cntc\PathLength + \@X.5\@halfwidth \divide\c@@cntc\@X + \ifnum \c@@cntc>\qbeziermax% + \PackageInfo{ebezier}{\the\c@@cntc\space points needed exceeding % + qbeziermax=\qbeziermax!}\fi + \fi + \ifnum \c@@cntc>\qbeziermax + \c@@cntc\qbeziermax\relax + \PackageWarning{ebezier}{Counter reset to qbeziermax=\qbeziermax!}\fi + \c@@cnta\c@@cntc\relax\advance\c@@cnta\@ne + \@Xa #4\unitlength \advance\@Xa-#2\unitlength \divide\@Xa\c@@cntc + \@Ya #5\unitlength \advance\@Ya-#3\unitlength \divide\@Ya\c@@cntc + \c@@cntb\z@\relax + \set@width + \put(#2,#3){\@whilenum{\c@@cntb<\c@@cnta}\do + {\@X\c@@cntb \@Xa\@Y \c@@cntb\@Ya + \raise\@Y\hbox to\z@{\hskip\@X\unhcopy\@pt\hss}% + \advance\c@@cntb\@ne}}} +%% +% \end{macrocode} +% +% \verb+\Lbezier+ changes the line thickness. It is stored in \verb+\@Xb+. +% +% \begin{macrocode} +\def\Lbezier{\@ifnextchar [{\@Lbezier}{\@Lbezier[0]}} +\def\@Lbezier[#1](#2,#3)(#4,#5){\c@@cntc#1\relax + \@Xb\@wholewidth + \@X #4\unitlength \advance\@X-#2\unitlength \AbsLen{\@X}% + \@Y #5\unitlength \advance\@Y-#3\unitlength \AbsLen{\@Y}% + \LenNorm{\@X}{\@Y}{\@Xc}\LenMult{\@Xc}{\@wholewidth}{\@Yb}% + \LenDiv{\@Yb}{\@X+\@Y}{\@wholewidth}\@halfwidth .5\@wholewidth + \ifnum \c@@cntc<\@ne + \multiply\eps\x@ + \Length(#2,#3)(#4,#5){\PathLength}% + \divide\eps\x@ + \c@@cntc\PathLength + \@X.5\@halfwidth \divide\c@@cntc\@X + \ifnum \c@@cntc>\qbeziermax% + \PackageInfo{ebezier}{\the\c@@cntc\space points needed exceeding % + qbeziermax=\qbeziermax!}\fi + \fi + \ifnum \c@@cntc>\qbeziermax + \c@@cntc\qbeziermax\relax + \PackageWarning{ebezier}{Counter reset to qbeziermax=\qbeziermax!}\fi + \c@@cnta\c@@cntc\relax \advance\c@@cnta\@ne + \@Xa #4\unitlength \advance\@Xa-#2\unitlength \divide\@Xa\c@@cntc + \@Ya #5\unitlength \advance\@Ya-#3\unitlength \divide\@Ya\c@@cntc + \c@@cntb\z@\relax + \set@width + \put(#2,#3){\@whilenum{\c@@cntb<\c@@cnta}\do + {\@X\c@@cntb \@Xa\@Y \c@@cntb\@Ya + \raise\@Y\hbox to\z@{\hskip\@X\unhcopy\@pt\hss}% + \advance\c@@cntb\@ne}} + \@wholewidth\@Xb \@halfwidth .5\@Xb} +%% +% \end{macrocode} +% +% The two joining macros need two internal steps to process an implicit list. +% +% \begin{macrocode} +\def\ljoin{\@ifnextchar [{\@ljoin}{\@ljoin[0]}} +\def\@ljoin[#1](#2,#3){\@ifnextchar ({\l@join[#1](#2,#3)}{\relax}} +\def\l@join[#1](#2,#3)(#4,#5){% + \lbezier[#1](#2,#3)(#4,#5)% + \ljoin[#1](#4,#5)} +%% +\def\Ljoin{\@ifnextchar [{\@Ljoin}{\@Ljoin[0]}} +\def\@Ljoin[#1](#2,#3){\@ifnextchar ({\L@join[#1](#2,#3)}{\relax}} +\def\L@join[#1](#2,#3)(#4,#5){% + \Lbezier[#1](#2,#3)(#4,#5)% + \Ljoin[#1](#4,#5)} +%% +% \end{macrocode} +% +% \verb+\Qbezier+ is defined, because \verb+\qbezier+ uses an other plot box. +% The original macro is a little bit more complicated to handle extra spaces +% but I hope this will suffice. +% +% \begin{macrocode} +\def\Qbezier{\@ifnextchar [{\@Qbezier}{\@Qbezier[0]}} +\def\@Qbezier[#1](#2,#3)(#4,#5)(#6,#7){\c@@cntc#1\relax + \ifnum \c@@cntc<\@ne + \multiply\eps\x@ + \PathLengthQ[5](#2,#3)(#4,#5)(#6,#7)% + \divide\eps\x@ + \c@@cntc\PathLength + \@X.5\@halfwidth \divide\c@@cntc\@X + \ifnum \c@@cntc>\qbeziermax% + \PackageInfo{ebezier}{\the\c@@cntc\space points needed exceeding % + qbeziermax=\qbeziermax!}\fi + \fi + \ifnum \c@@cntc>\qbeziermax + \c@@cntc\qbeziermax\relax + \PackageWarning{ebezier}{Counter reset to qbeziermax=\qbeziermax!}\fi + \c@@cnta\c@@cntc\relax \advance\c@@cnta\@ne + \@Xa #4\unitlength \advance\@Xa-#2\unitlength \multiply\@Xa\tw@ + \@Xb #6\unitlength \advance\@Xb-#2\unitlength + \advance\@Xb-\@Xa \divide\@Xb\c@@cntc + \@Ya #5\unitlength \advance\@Ya-#3\unitlength \multiply\@Ya\tw@ + \@Yb #7\unitlength \advance\@Yb-#3\unitlength + \advance\@Yb-\@Ya \divide\@Yb\c@@cntc + \c@@cntb\z@\relax + \set@width + \put(#2,#3){\@whilenum{\c@@cntb<\c@@cnta}\do + {\@X\c@@cntb \@Xb\@Y \c@@cntb\@Yb + \advance\@X\@Xa \advance\@Y\@Ya + \divide\@X\c@@cntc \divide\@Y\c@@cntc + \multiply\@X\c@@cntb \multiply\@Y\c@@cntb + \raise \@Y \hb@xt@\z@{\kern\@X\unhcopy\@pt\hss}% + \advance\c@@cntb\@ne}}} +%% +% \end{macrocode} +% +% \verb+\cbezier+ is the most complex command. All calculations have to be +% done in the correct order to minimize overflow conditions. +% +% \begin{macrocode} +\def\cbezier{\@ifnextchar [{\@cbezier}{\@cbezier[0]}} +\def\@cbezier[#1](#2,#3)(#4,#5)(#6,#7)(#8,#9){% + \c@@cntc#1\relax + \ifnum \c@@cntc<\@ne + \multiply\eps\x@ + \PathLengthC[5](#2,#3)(#4,#5)(#6,#7)(#8,#9)% + \divide\eps\x@ + \c@@cntc\PathLength + \@X = 0.5\@halfwidth + \divide\c@@cntc\@X + \ifnum \c@@cntc>\qbeziermax% + \PackageInfo{ebezier}{\the\c@@cntc\space points needed exceeding % + qbeziermax=\qbeziermax!}\fi + \fi + \ifnum \c@@cntc>\qbeziermax + \c@@cntc\qbeziermax\relax + \PackageWarning{ebezier}{Counter reset to qbeziermax=\qbeziermax!}\fi + \c@@cnta\c@@cntc\relax \advance\c@@cnta\@ne + \@Xa #4\unitlength \advance\@Xa-#2\unitlength \multiply\@Xa\thr@@ + \@Xb #6\unitlength \advance\@Xb-#2\unitlength \multiply\@Xb\thr@@ + \advance\@Xb -2\@Xa + \@Xc #8\unitlength \advance\@Xc-#2\unitlength + \advance\@Xc-\@Xa \advance\@Xc-\@Xb + \@Ya #5\unitlength \advance\@Ya-#3\unitlength \multiply\@Ya\thr@@ + \@Yb #7\unitlength \advance\@Yb-#3\unitlength \multiply\@Yb\thr@@ + \advance\@Yb-2\@Ya + \@Yc #9\unitlength \advance\@Yc-#3\unitlength + \advance\@Yc-\@Ya \advance\@Yc-\@Yb + \divide\@Xc\c@@cntc \divide\@Yc\c@@cntc + \c@@cntb\z@\relax + \set@width + \put(#2,#3){\@whilenum{\c@@cntb<\c@@cnta}\do + {\@X\c@@cntb \@Xc\@Y \c@@cntb\@Yc + \advance\@X\@Xb \advance\@Y\@Yb + \divide\@X\c@@cntc \divide\@Y\c@@cntc + \multiply\@X\c@@cntb \multiply\@Y\c@@cntb + \advance\@X\@Xa \advance\@Y\@Ya + \divide\@X\c@@cntc \divide\@Y\c@@cntc + \multiply\@X\c@@cntb \multiply\@Y\c@@cntb + \raise \@Y \hbox to \z@{\hskip \@X\unhcopy\@pt\hss}% + \advance\c@@cntb\@ne}}} +%% +% \end{macrocode} +% +% \verb+\Cbezier+ changes the plot symbol so a restore is needed. But it will +% not keep the original one! +% +% \begin{macrocode} +\def\Cbezier{\@ifnextchar [{\@Cbezier}{\@Cbezier[0]}} +\def\@Cbezier[#1](#2,#3)(#4,#5)(#6,#7)(#8,#9){% + \cbezier[#1](#2,#3)(#4,#5)(#6,#7)(#8,#9)% + \c@@cntc#1\relax\divide\c@@cntc\thr@@ + \lbezier[\c@@cntc](#2,#3)(#4,#5)% + \lbezier[\c@@cntc](#4,#5)(#6,#7)% + \lbezier[\c@@cntc](#6,#7)(#8,#9)% + \DefPlotSymbol{$\bullet$} + \lbezier[1](#2,#3)(#2,#3) + \lbezier[1](#4,#5)(#4,#5) + \lbezier[1](#6,#7)(#6,#7) + \lbezier[1](#8,#9)(#8,#9) + \DefStandardPlotSymbol + \thinlines} +%% +% \end{macrocode} +% +% \verb+\l@put+ is like \verb+\put+ but its arguments are lengths and not +% decimal constants. It will be used in \verb+\l@cbezier+ which also has +% lengths as arguments. All complex plotting commands use this form. +% Just for the calculation of plotting points four more lengths are needed. +% I use the ``scratch'' dimens from \TeX. +% +% \begin{macrocode} +\long\gdef\l@put(#1,#2)#3{% + \@killglue\raise#2\hb@xt@\z@{\kern#1#3\hss}\ignorespaces} +%% +\long\gdef\l@cbezier[#1](#2,#3)(#4,#5)(#6,#7)(#8,#9){% + \c@@cntc#1\relax + \dimen1#2\dimen3#3 +%% + \@Xa #4 \advance\@Xa-#2 \multiply\@Xa\thr@@ + \@Xb #6 \advance\@Xb-#2 \multiply\@Xb\thr@@ + \advance\@Xb-2\@Xa + \@Xc #8 \advance\@Xc-#2 + \advance\@Xc-\@Xa \advance\@Xc-\@Xb + \@Ya #5 \advance\@Ya-#3 \multiply\@Ya\thr@@ + \@Yb #7 \advance\@Yb-#3 \multiply\@Yb\thr@@ + \advance\@Yb-2\@Ya + \@Yc #9 \advance\@Yc-#3 + \advance\@Yc-\@Ya \advance\@Yc-\@Yb +%% +%% assume half arc +%% + \ifnum \c@@cntc <\@ne + \multiply\eps\x@ + \dimen5#2 \advance\dimen5-#8 \AbsLen{\dimen5}% + \dimen7#3 \advance\dimen7-#9 \AbsLen{\dimen7}% + \LenNorm{\dimen5}{\dimen7}{\PathLength}% + \divide\eps\x@ + \c@@cntc\PathLength + \dimen5.5\@halfwidth + \divide\c@@cntc\dimen5 +%% +%% 11/7 \approx \pi/2 +%% + \divide\c@@cntc 7 \multiply\c@@cntc 11 + \ifnum \c@@cntc>\qbeziermax + \PackageInfo{ebezier}{\the\c@@cntc\space points needed exceeding % + qbeziermax=\qbeziermax!}\fi + \fi + \ifnum\c@@cntc>\qbeziermax + \c@@cntc\qbeziermax\relax + \PackageWarning{ebezier}{Counter reset to qbeziermax=\qbeziermax!}\fi + \c@@cnta\c@@cntc\relax\advance\c@@cnta\@ne% + \divide\@Xc\c@@cntc \divide\@Yc\c@@cntc + \c@@cntb\z@\relax + \set@width + \l@put(\dimen1,\dimen3){\@whilenum{\c@@cntb<\c@@cnta}\do + {\@X\c@@cntb \@Xc\@Y \c@@cntb\@Yc + \advance\@X\@Xb \advance\@Y\@Yb + \divide\@X\c@@cntc \divide\@Y\c@@cntc + \multiply\@X\c@@cntb \multiply\@Y\c@@cntb + \advance\@X\@Xa \advance\@Y\@Ya + \divide\@X\c@@cntc \divide\@Y\c@@cntc + \multiply\@X\c@@cntb \multiply\@Y\c@@cntb + \raise\@Y\hbox to\z@{\hskip\@X\unhcopy\@pt\hss}% + \advance\c@@cntb\@ne}}} +%% +% \end{macrocode} +% +% The building blocks for the circles are the four quarters. Each is defined +% separately and will be combined by the \verb+\cCircle+ macro. +% +% \begin{macrocode} +\def\@circle@rt[#1](#2,#3)#4{% + \set@magic + \@Z #4\magicnum\@Za #2\unitlength\@Zb #3\unitlength + \@Zc #2\unitlength \advance\@Zc\@Z + \@Zd #3\unitlength \advance\@Zd\@Z + \@Ze #4\unitlength \advance\@Ze\@Za + \@Zf #4\unitlength \advance\@Zf\@Zb + \l@cbezier[#1](\@Ze,\@Zb)(\@Ze,\@Zd)(\@Zc,\@Zf)(\@Za,\@Zf)} +%% +\def\@circle@lt[#1](#2,#3)#4{% + \set@magic + \@Z #4\magicnum\@Za #2\unitlength\@Zb #3\unitlength + \@Zc #2\unitlength \advance\@Zc-\@Z + \@Zd #3\unitlength \advance\@Zd\@Z + \@Ze -#4\unitlength \advance\@Ze\@Za + \@Zf #4\unitlength \advance\@Zf\@Zb + \l@cbezier[#1](\@Za,\@Zf)(\@Zc,\@Zf)(\@Ze,\@Zd)(\@Ze,\@Zb)} +%% +\def\@circle@rb[#1](#2,#3)#4{% + \set@magic + \@Z #4\magicnum\@Za #2\unitlength\@Zb #3\unitlength + \@Zc #2\unitlength \advance\@Zc\@Z + \@Zd #3\unitlength \advance\@Zd-\@Z + \@Ze #4\unitlength \advance\@Ze\@Za + \@Zf -#4\unitlength \advance\@Zf\@Zb + \l@cbezier[#1](\@Za,\@Zf)(\@Zc,\@Zf)(\@Ze,\@Zd)(\@Ze,\@Zb)} +%% +\def\@circle@lb[#1](#2,#3)#4{% + \set@magic + \@Z #4\magicnum\@Za #2\unitlength\@Zb #3\unitlength + \@Zc #2\unitlength \advance\@Zc-\@Z + \@Zd #3\unitlength \advance\@Zd-\@Z + \@Ze -#4\unitlength \advance\@Ze\@Za + \@Zf -#4\unitlength \advance\@Zf\@Zb + \l@cbezier[#1](\@Ze,\@Zb)(\@Ze,\@Zd)(\@Zc,\@Zf)(\@Za,\@Zf)} +%% +% \end{macrocode} +% +% I use the logicals from the \verb+\oval+ defined in \LaTeX. So I need just +% one more logical \verb+\if@ovf+. +% +% \begin{macrocode} +\newif\if@ovf +\def\cCircle{\@ifnextchar [{\@cCircle}{\@cCircle[0]}} +\def\@cCircle[#1](#2,#3)#4[#5]{% + \@ovtfalse\@ovbfalse\@ovlfalse\@ovrfalse\@ovffalse + \c@@cnta#1\relax + \@tfor\reserved@a:=#5\do{\csname @ov\reserved@a true\endcsname}% + \if@ovf\@ovttrue \divide\c@@cnta\tw@\fi + \if@ovt + \if@ovr + \@circle@rt[\c@@cnta](#2,#3){#4} + \else\if@ovl + \@circle@lt[\c@@cnta](#2,#3){#4} + \else\divide\c@@cnta\tw@ + \@circle@rt[\c@@cnta](#2,#3){#4} + \@circle@lt[\c@@cnta](#2,#3){#4} + \fi\fi + \if@ovf + \@circle@rb[\c@@cnta](#2,#3){#4} + \@circle@lb[\c@@cnta](#2,#3){#4} + \fi + \else\if@ovb + \if@ovr + \@circle@rb[\c@@cnta](#2,#3){#4} + \else\if@ovl + \@circle@lb[\c@@cnta](#2,#3){#4} + \else\divide\c@@cnta\tw@ + \@circle@rb[\c@@cnta](#2,#3){#4} + \@circle@lb[\c@@cnta](#2,#3){#4} + \fi\fi + \else + \divide\c@@cnta\tw@ + \if@ovr + \@circle@rb[\c@@cnta](#2,#3){#4} + \@circle@rt[\c@@cnta](#2,#3){#4} + \else + \if@ovl + \@circle@lb[\c@@cnta](#2,#3){#4} + \@circle@lt[\c@@cnta](#2,#3){#4} + \else + \PackageError{Ebezier}{Missing or illegal position specifier in cCircle} + \fi\fi\fi\fi} +%% +\def\cArc{\@ifnextchar [{\@cArc}{\@cArc[0]}} +\def\@cArc[#1](#2,#3)(#4,#5){% + \c@@cntc#1\relax + \@X #2\unitlength \@Y #3\unitlength + \@Za #4\unitlength \@Zb #5\unitlength + \@Zc 2\@X \advance\@Zc-\@Za \@Zd 2\@Y \advance\@Zd-\@Zb + \@Xa\@Y \advance\@Xa-\@Zb \@Ya\@Za \advance\@Ya-\@X + \multiply\@Xa 4 \divide\@Xa\thr@@ \multiply\@Ya 4 \divide\@Ya\thr@@ + \@Ze\@Za \advance\@Ze\@Xa \@Zf\@Zb \advance\@Zf\@Ya + \@Zg\@Zc \advance\@Zg\@Xa \@Zh\@Zd \advance\@Zh\@Ya + \l@cbezier[#1](\@Za,\@Zb)(\@Ze,\@Zf)(\@Zg,\@Zh)(\@Zc,\@Zd)} +%% +% \end{macrocode} +% +% Historically from this point starts the calculation part. The notation +% will be more \LaTeX\ convenient. +% +% All square roots are calculated by the same iteration. To keep numbers +% small enough some scaling has to be done (factor \verb+\c@@cntd+). +% +% \begin{macrocode} +\def\LenMult#1#2#3{\setlength{#3}{#1*\ratio{#2}{\unitlength}}} +%% +\def\LenDiv#1#2#3{\setlength{#3}{\unitlength*\ratio{#1}{#2}}} +%% +\def\AbsLen#1{\ifdim#1<\z@\setlength{#1}{-#1}\fi} +%% +\def\LenSqrt#1#2{% + \setlength{\@Za}{#1}% + \ifdim\@Za>\eps\loop\setlength{\@Zb}{(\@Za+\unitlength*\ratio{#1}{\@Za})/2}% + \setlength{\@Zc}{\@Za-\@Zb}\AbsLen{\@Zc}% + \ifdim\@Zc>\eps\setlength{\@Za}{\@Zb}\repeat\fi% + \setlength{#2}{\@Za}} +%% +\def\Length(#1,#2)(#3,#4)#5{% + \setlength{\@Zd}{#3\unitlength-#1\unitlength}% + \setlength{\@Ze}{#4\unitlength-#2\unitlength}% + \setcounter{@cntd}{1}% + \setlength{\@Zf}{\@Zd}\ifdim\@Ze>\@Zd\setlength{\@Zf}{\@Ze}\fi + \loop\setlength{\@Zd}{\@Zd/2}\setlength{\@Ze}{\@Ze/2}\setlength{\@Zf}{\@Zf/2}% + \multiply\c@@cntd\tw@\ifdim\@Zf>\x@ pt\repeat + \LenMult{\@Zd}{\@Zd}{\@Zg}\LenMult{\@Ze}{\@Ze}{\@Zh}\setlength{\@Zf}{\@Zg+\@Zh}% + \LenSqrt{\@Zf}{\@Zg}\setlength{#5}{\@Zg*\value{@cntd}}} +%% +\def\LenNorm#1#2#3{% + \setlength{\@Zd}{#1}\setlength{\@Ze}{#2}\setcounter{@cntd}{1}% + \setlength{\@Zf}{\@Zd}\ifdim\@Ze>\@Zd\setlength{\@Zf}{\@Ze}\fi + \loop\setlength{\@Zd}{\@Zd/2}\setlength{\@Ze}{\@Ze/2}\setlength{\@Zf}{\@Zf/2}% + \multiply\c@@cntd\tw@\ifdim\@Zf>\x@ pt\repeat + \LenMult{\@Zd}{\@Zd}{\@Zg}\LenMult{\@Ze}{\@Ze}{\@Zh}\setlength{\@Zf}{\@Zg+\@Zh}% + \LenSqrt{\@Zf}{\@Zg}\setlength{#3}{\@Zg*\value{@cntd}}} +%% +\def\PathLengthQ[#1](#2,#3)(#4,#5)(#6,#7){% + \PathLength\z@\c@@cntc#1\relax + \ifnum \c@@cntc<\@ne \c@@cntc\pathmax\relax\fi + \ifnum \c@@cntc>\pathmax \c@@cntc\pathmax\relax + \PackageWarning{ebezier}{Counter reset to pathmax=\pathmax!}\fi + \@Za\z@ \@Zb\z@ \c@@cntb\c@@cntc\relax \advance\c@@cntb\@ne + \@Xb #4\unitlength \advance\@Xb-#2\unitlength \multiply\@Xb\tw@ + \@Yb #5\unitlength \advance\@Yb-#3\unitlength \multiply\@Yb\tw@ + \@Xa #6\unitlength \advance\@Xa-#2\unitlength + \advance\@Xa-\@Xb \divide\@Xa\c@@cntc + \@Ya #7\unitlength \advance\@Ya-#3\unitlength + \advance\@Ya-\@Yb \divide\@Ya\c@@cntc \c@@cnta\@ne\relax + \@whilenum{\c@@cnta<\c@@cntb}\do + {\@X\c@@cnta\@Xa \advance\@X\@Xb \divide\@X\c@@cntc \multiply\@X\c@@cnta + \@Y\c@@cnta\@Ya \advance\@Y\@Yb \divide\@Y\c@@cntc \multiply\@Y\c@@cnta + \@Zi\@X\@Zj\@Y + \advance\@X-\@Za \advance\@Y-\@Zb \LenNorm{\@X}{\@Y}{\@Z}% + \advance\PathLength\@Z + \@Za\@Zi\@Zb\@Zj \advance\c@@cnta\@ne}} +%% +\def\PathLengthC[#1](#2,#3)(#4,#5)(#6,#7)(#8,#9){% + \PathLength\z@ \c@@cntc#1\relax + \ifnum \c@@cntc<\@ne \c@@cntc\pathmax\relax\fi + \ifnum \c@@cntc>\pathmax \c@@cntc\pathmax\relax + \PackageWarning{ebezier}{Counter reset to pathmax=\pathmax!}\fi + \@Za\z@ \@Zb\z@ \c@@cnta\c@@cntc\relax \advance\c@@cnta\@ne + \@Xa #4\unitlength \advance\@Xa-#2\unitlength \multiply\@Xa\thr@@ + \@Xb #6\unitlength \advance\@Xb-#2\unitlength \multiply\@Xb\thr@@ + \advance\@Xb-2\@Xa + \@Xc #8\unitlength \advance\@Xc-#2\unitlength + \advance\@Xc-\@Xa \advance\@Xc-\@Xb + \@Ya #5\unitlength \advance\@Ya-#3\unitlength \multiply\@Ya\thr@@ + \@Yb #7\unitlength \advance\@Yb-#3\unitlength \multiply\@Yb\thr@@ + \advance\@Yb-2\@Ya + \@Yc #9\unitlength \advance\@Yc-#3\unitlength + \advance\@Yc-\@Ya \advance\@Yc-\@Yb + \divide\@Xc\c@@cntc \divide\@Yc\c@@cntc + \c@@cntb\@ne\relax + \@whilenum{\c@@cntb<\c@@cnta}\do + {\@X\c@@cntb\@Xc \@Y\c@@cntb\@Yc \advance\@X\@Xb \advance\@Y\@Yb + \divide\@X\c@@cntc \divide\@Y\c@@cntc + \multiply\@X\c@@cntb \multiply\@Y\c@@cntb + \advance\@X\@Xa \advance\@Y\@Ya + \divide\@X\c@@cntc \divide\@Y\c@@cntc + \multiply\@X\c@@cntb \multiply\@Y\c@@cntb + \@Zi\@X\@Zj\@Y + \advance\@X-\@Za \advance\@Y-\@Zb \LenNorm{\@X}{\@Y}{\@Z}% + \advance\PathLength\@Z + \@Za\@Zi\@Zb\@Zj\advance\c@@cntb\@ne}} +%% +% \end{macrocode} +% +% The most complex macro is explained in the text. The exception is +% handled by the logical \verb+\if@ovf+. +% +% \begin{macrocode} +\def\cArcs{\@ifnextchar [{\@cArcs}{\@cArcs[0]}} +\def\@cArcs[#1](#2,#3)(#4,#5)(#6,#7){% + \c@@cntc#1\relax + \@ovffalse + \@X#2\unitlength\@Y#3\unitlength + \@Zi#6\unitlength\@Zj#7\unitlength + \setlength{\@Xa}{\@X-\@Zi}\setlength{\@Ya}{\@Y-\@Zj}% + \LenNorm{\@Xa}{\@Ya}{\@Xb}% + \@Xa#4\unitlength \advance\@Xa\@Zi \advance\@Xa-2\@X + \@Ya#5\unitlength \advance\@Ya\@Zj \advance\@Ya-2\@Y + \@Xc\@Xa\AbsLen{\@Xc}\@Yc\@Ya\AbsLen{\@Yc}% + \ifdim\@Xc<\eps\ifdim\@Yc<\eps\@ovftrue\fi\fi + \if@ovf + \cArc[#1](#2,#3)(#4,#5)% + \else + \LenNorm{\@Xa}{\@Ya}{\@Yb}% + \setlength{\@Xc}{\unitlength*\ratio{\@Xb}{\@Yb}}% + \setlength{\@Yc}{(-\unitlength+\@Xc*2)*4/3}% + \@Xb-#5\unitlength \advance\@Xb\@Zj + \@Z\@Xb\AbsLen{\@Z}% + \ifdim\@Z<100\eps \@Xb#4\unitlength \advance\@Xb-\@Zi \@Xa\@Ya\fi + \setlength{\@Z}{\@Yc*\ratio{\@Xa}{\@Xb}}% + \@Xa#4\unitlength\@Ya#5\unitlength + \setlength{\@Za}{\@Y-\@Ya}\setlength{\@Zb}{\@Xa-\@X}% + \setlength{\@Zc}{\@Zj-\@Y}\setlength{\@Zd}{\@X-\@Zi}% + \@Xb\@Xa \LenMult{\@Z}{\@Za}{\@Zh}\advance\@Xb\@Zh + \@Yb\@Ya\LenMult{\@Z}{\@Zb}{\@Zh}\advance\@Yb\@Zh + \@Xc\@Zi\LenMult{\@Z}{\@Zc}{\@Zh}\advance\@Xc\@Zh + \@Yc\@Zj\LenMult{\@Z}{\@Zd}{\@Zh}\advance\@Yc\@Zh + \@Z\@Xa\@Za\@Ya\@Zb\@Xb\@Zc\@Yb\@Zd\@Xc\@Ze\@Yc + \l@cbezier[#1](\@Z,\@Za)(\@Zb,\@Zc)(\@Zd,\@Ze)(\@Zi,\@Zj)% + \fi} +% +% \end{macrocode} +% \Finale \PrintIndex \PrintChanges +\endinput diff --git a/macros/latex/contrib/ebezier/ebezier.ins b/macros/latex/contrib/ebezier/ebezier.ins new file mode 100644 index 0000000000..adcb4ae5b0 --- /dev/null +++ b/macros/latex/contrib/ebezier/ebezier.ins @@ -0,0 +1,32 @@ +%% LaTeX2e file `ebezier.ins' +%% from source `ebezier' on 2005/03/01. +%% +%% Gerhard A. Bachmaier +%% Institute for Medical Informatics, Statistics, and Documentation +%% Medical University of Graz +%% send bugs to: gerhard.bachmaier@meduni-graz.at +% +\def\batchfile{ebezier.ins} +\input docstrip.tex +\keepsilent +\Msg{*** Generating the LaTeX2e package files ***} +\generate{\file{ebezier.sty}{\from{ebezier.dtx}{package}}} +\Msg{***********************************************************} +\Msg{*} +\Msg{* To finish the installation you have to move the following} +\Msg{* file(s) into a directory searched by TeX:} +\Msg{*} +\Msg{* \space\space ebezier.sty} +\Msg{*} +\Msg{* To produce the documentation run the files ending with} +\Msg{* `.dtx' through LaTeX.} +\Msg{*} +\Msg{* Process any name.idx file by:} +\Msg{* \space\space\space\space makeindex -s gind.ist ebezier} +\Msg{*} +\Msg{* Then rerun LaTeX twice} +\Msg{*} +\Msg{* Happy TeXing} +\Msg{***********************************************************} +\endinput + diff --git a/macros/latex/contrib/ebezier/ebezier.pdf b/macros/latex/contrib/ebezier/ebezier.pdf new file mode 100644 index 0000000000..e4fd5894f8 Binary files /dev/null and b/macros/latex/contrib/ebezier/ebezier.pdf differ -- cgit v1.2.3