diff options
author | Karl Berry <karl@freefriends.org> | 2017-05-17 21:57:11 +0000 |
---|---|---|
committer | Karl Berry <karl@freefriends.org> | 2017-05-17 21:57:11 +0000 |
commit | 0da0790c8e0a586ac62d03aa1546f6dead322af0 (patch) | |
tree | 3d126a2a503c68f1ade5b42cf8097dbf4d89b79a | |
parent | 53fd5f4c53a010d8797af79d9c2ccf3c98b770a0 (diff) |
axodraw2 (17may17)
git-svn-id: svn://tug.org/texlive/trunk@44396 c570f23f-e606-0410-a88d-b1316a301751
-rw-r--r-- | Master/texmf-dist/doc/latex/axodraw2/README | 41 | ||||
-rw-r--r-- | Master/texmf-dist/doc/latex/axodraw2/axodraw2-man.pdf | bin | 0 -> 415732 bytes | |||
-rw-r--r-- | Master/texmf-dist/doc/latex/axodraw2/axodraw2-man.tex | 5160 | ||||
-rw-r--r-- | Master/texmf-dist/doc/latex/axodraw2/example.tex | 19 | ||||
-rw-r--r-- | Master/texmf-dist/source/latex/axodraw2/axohelp.c | 3699 | ||||
-rw-r--r-- | Master/texmf-dist/tex/latex/axodraw2/axodraw2.sty | 4728 | ||||
-rwxr-xr-x | Master/tlpkg/bin/tlpkg-ctan-check | 2 | ||||
-rwxr-xr-x | Master/tlpkg/libexec/ctan2tds | 2 | ||||
-rw-r--r-- | Master/tlpkg/tlpsrc/axodraw2.tlpsrc | 0 | ||||
-rw-r--r-- | Master/tlpkg/tlpsrc/collection-mathscience.tlpsrc | 1 |
10 files changed, 13650 insertions, 2 deletions
diff --git a/Master/texmf-dist/doc/latex/axodraw2/README b/Master/texmf-dist/doc/latex/axodraw2/README new file mode 100644 index 00000000000..1a0bc97dd79 --- /dev/null +++ b/Master/texmf-dist/doc/latex/axodraw2/README @@ -0,0 +1,41 @@ +Axodraw2 is a package that defines macros for drawing Feynman graphs +in LaTeX documents. + +It is an important update of the axodraw package, but since it is not +completely backwards compatible, we have given the style file a +changed name. + +Many new features have been added, with new types of line, and much +more flexibility in their properties: For details see the +documentation. + +In addition, it is now possible to use axodraw2 with pdflatex, as well +as with the latex-dvips method. However with pdflatex (and also lualatex +and xelatex), an external program, axohelp, is used to perform the +geometrical calculations needed for the pdf code inserted in the +output file. The processing involves a run of pdflatex, a run of +axohelp, and then another run of pdflatex. + +The files in the distribution are: + + README This file + axodraw2.sty The main style file + axohelp.c Source code of axohelp + axohelp.exe MS-Windows executable for axohelp + axodraw2-man.pdf Documentation + axodraw2-man.tex Source for documentation + example.tex Example latex file for use of axodraw2 + + +Authors, copyright, license +--------------------------- + +(C) 1994-2016 John Collins (jcc8 at psu dot edu) and Jos Vermaseren +(t68 at nikhef dot nl) + +Axodraw2 is free software: you can redistribute it and/or modify it +under the terms of the GNU General Public License as published by the +Free Software Foundation, either version 3 of the License, or (at your +option) any later version. See the files axodraw2.sty or axohelp.c +for more details. + diff --git a/Master/texmf-dist/doc/latex/axodraw2/axodraw2-man.pdf b/Master/texmf-dist/doc/latex/axodraw2/axodraw2-man.pdf Binary files differnew file mode 100644 index 00000000000..4294ea3b14d --- /dev/null +++ b/Master/texmf-dist/doc/latex/axodraw2/axodraw2-man.pdf diff --git a/Master/texmf-dist/doc/latex/axodraw2/axodraw2-man.tex b/Master/texmf-dist/doc/latex/axodraw2/axodraw2-man.tex new file mode 100644 index 00000000000..03569ef2a77 --- /dev/null +++ b/Master/texmf-dist/doc/latex/axodraw2/axodraw2-man.tex @@ -0,0 +1,5160 @@ +\documentclass[12pt]{article} +\usepackage{a4wide} +% Use fix-cm or lmodern to get scaleable cm fonts +\usepackage{longtable,fix-cm,url,units,hyperref} + +\usepackage{axodraw2} + +\def\num{$\langle$number$\rangle$} +\def\colorname{$\langle$colorname$\rangle$} + +% How to typeset filenames and program names: Use \file and \program +% to allow stylistic changes. +% Basic definition of \file would bes \def\file#1{\texttt{#1}}, but +% that would not allow line breaks in long names. So define it by +% \DeclareUrlCommand from url package. (We can't use \url itself, +% because that provokes hyperref into making a hyperlink.) +\DeclareUrlCommand\file{\urlstyle{tt}} + +% Similarly specify how to typeset names of programs +\def\program#1{\texttt{#1}} + +% Backslash of the kind used in verbatim +\newcommand\BS{\symbol{`\\}} + +% Set the name of a TeX macro (and possibly its signature). +% In the argument, the initial backslash. Allow \{ and \} in the +% argument. E.g. \name{SetSpace\{\#\}}} +\newcommand\name[1]{% + \bgroup + \def\{{\symbol{`\{}}% + \def\}{\symbol{`\}}}% + \texttt{\BS#1}% + \egroup +} + + +\begin{document} + +%% ?? To get settings useful to test compatibility of axodraw2 with +%% color.sty, uncomment the following line: +%\SetColor{Blue} \color{green} \pagecolor[cmyk]{0,0.02,0.05,0} +%% Note green is useful, because it is defined in rgb color model +%% and the apparently equivalent Green, cmyk 1 0 1 0, looks quite +%% different on screen. So we can test the colors are entering graphics +%% correctly. + +%% ?? To test whether offsets work correctly, uncomment the following +%% line: +%\SetOffset(10,20) \SetScaledOffset(10,-20) + + +\setcounter{page}{0} +\thispagestyle{empty} +\hfill \begin{minipage}{3.0cm} +Nikhef 2015-025 +\end{minipage} +\vspace{20mm} + +\begin{center} +{\LARGE\bf\sc Axodraw Version 2} +\end{center} +\vspace{5mm} +\begin{center} +{\large John C. Collins$^{\, a}$ and J.A.M. Vermaseren$^{\, b}$} +\vspace{1cm}\\ +{\it $^a$ Department of Physics, Pennsylvania State University, \\ +\vspace{0.1cm} +University Park, Pennsylvania 16802, USA} \\ +\texttt{jcc8 at psu dot edu} \\ +\vspace{0.5cm} +{\it $^b$Nikhef Theory Group \\ +\vspace{0.1cm} +Science Park 105, 1098 XG Amsterdam, The Netherlands} \\ +\texttt{t68 at nikhef dot nl} \\ +\vspace{1.0cm} +(3 June 2016) +\end{center} +\vspace{5mm} + +\begin{abstract} +We present version two of the \LaTeX{} graphical style file Axodraw. +It has a number of new drawing primitives and many extra options, and +it can now work with \program{pdflatex} to directly produce +output in PDF file format (but with the aid of an auxiliary program). +\end{abstract} + +\newpage + +\tableofcontents + +\newpage + + +%>>#[ Introduction : +%========================= +\section{Introduction} +\label{sec:intro} + +This is the documentation for axodraw2, a \LaTeX{} package for drawing +Feynman graphs (and other simple graphics). This version is a +substantial update of the original axodraw package \cite{axodraw1}, +which was released +in 1994, and which has become rather popular in the preparation of articles in +elementary-particle physics. One of its advantages is that its +drawing primitives are included in the .tex document, in a +human-writable form. (This also allows convenient production of +axodraw figures by other software, e.g., Jaxodraw +\cite{jaxodraw1,jaxodraw2}.) +This is in distinction to methods that +use a separate program to create graphics files that are read in +during the processing of the \LaTeX{} file. The objects needed in +Feynman graphs are often difficult to draw at high quality with +conventional computer graphics software. + +The original axodraw package has hardly been modified since its +introduction. The new version addresses several later needs. A +detailed list of the changes is given in Sec.\ \ref{sec:changes}. + +One change arises from the fact that \TeX{} (and hence \LaTeX{}) +themselves do not possess sufficiently useful methods of drawing +complicated graphics, so that the drawing of the graphics is actually +done inserting suitable code in the final output file (postscript or +pdf). The original axodraw worked only with the +\program{latex}-\program{dvips} processing chain to put the diagrams in +the final postscript file.\footnote{A pdf file can be produced from + the postscript file by a program like \program{ps2pdf}.} Now we also +have in common use the \program{pdflatex} (and \program{lualatex} and +\program{xelatex}) programs that directly produce pdf. The new version +of axodraw works with \program{pdflatex}, \program{lualatex}, and +\program{xelatex}, as well as with the \program{latex}-\program{dvips} +method. + +Furthermore, more kinds of graphical object and greater flexibility in +their properties have been found useful for Feynman graphs. The new +version provides a new kind of line, B\'ezier, and is able to make the +various kinds of line doubled. There is now a very flexible +configuration of arrows. Many of the changes correspond to +capabilities of JaxoDraw \cite{jaxodraw1,jaxodraw2}, which is a +graphical program for drawing Feynman graphs, and which is able to +write and to import diagrams in the axodraw format. + +Finally, substantial improvements have been made in the handling of +colors, with much better compatibility with modern packages used to +set colors in the normal \LaTeX{} part of a document. + +Since some of the changes (especially in the internal coding) +introduce potential incompatibilities with the original version of +axodraw, the new version of the style file is given a new name +\file{axodraw2.sty}. Then the many legacy documents (e.g., on +\url{http://arxiv.org}) that use the old axodraw will continue to use +the old version, and will therefore continue to be compilable without +any need for any possible changes in the source document, and with unchanged +output. Even so, as regards the coding of diagrams, there are very +few backwardly incompatible changes in axodraw2. + +The software is available under the GNU General Public License +\cite{GPL} version 3. + + + +%========================= +\section{Changes} +\label{sec:changes} + +\subsection{Changes relative to original, axodraw version 1} +\label{sec:changes.wrt.1} + +Relative to the original version of axodraw, the current version, +axodraw2, has the following main changes: +\begin{itemize} + +\item A bug that the line bounding an oval did not have a uniform + width has been corrected. + +\item A bug has been corrected that axodraw did not work with the + revtex4 document class when \verb+\maketitle+ and two-column mode + were used. + +\item Axodraw2 works both when pdf output is produced directly using + the programs \program{pdflatex}, \program{lualatex}, and + \program{xelatex}, as well as when a postscript file is produced by + the latex--dvips method. The old version only worked when + postscript output was produced. However, an auxiliary program is + needed when using \program{pdflatex}, \program{lualatex}, or + \program{xelatex}. See Sec.\ \ref{sec:doc.compile} for how this is + done. + +\item In the original axodraw, a diagram is coded inside a + \verb+picture+ environment of \LaTeX. Now, a specialized + \verb+axopicture+ environment is provided and preferred; it provides + better behavior, especially when diagrams are to be scaled. + +\item In association with this, there are some changes in how scaling + of diagrams is done. + +\item An inconsistency in length units between postscript and \TeX{} + has been corrected. All lengths are now specified in terms of + $\unit[1]{pt} = \unit[1/72.27]{in} = \unit[0.3515]{mm}$. Previously + the unit length for graphics was the one defined by postscript to be + $\unit[1]{bp} = \unit[1/72]{in} = \unit[0.3528]{mm}$. + +\item Substantial improvements have been made in the treatment of + color. When named colors are used, axodraw2's use of color is + generally compatible with that of the modern, \LaTeX-standard + \file{color.sty} package. It also provides all the macros that were + defined in v.\ 1 of axodraw, including those of the \file{colordvi.sty} + package used by v.\ 1. + +\item The various types of line can now be produced as double lines, + e.g., + \begin{axopicture}(35,5)(0,-2) + \SetWidth{1} + \Line[double,sep=2.5](0,2)(35,2) + \end{axopicture}. + This is commonly used, for example, for notating Wilson lines. + +\item Lines can be made from B\'ezier curves. + Currently this is only for simple lines, not photon, gluon, or + zigzag lines. + +\item Gluon, photon, and zigzag lines can be dashed. + +\item Macros are provided for drawing gluon circles, without the + endpoint effects given by the corresponding gluon arc macros. + +\item The positions and sizes of arrows can be adjusted. See Sec.\ + \ref{sec:arrows} for all the possibilities. One example is + \begin{axopicture}(30,6)(0,-2) + \SetWidth{1} + \Line[arrow,arrowpos=0.8](0,2)(30,2) + \end{axopicture} + +\item Macros for drawing polygons and filled polygons are provided. + +\item Macros for drawing rotated boxes are provided. + +\item A macro \verb+\ECirc+ is provided for drawing a circle with a + transparent interior. + +\item A macro \verb+\EBoxc+ is provided for drawing a box with a + specified center. + +\item A macro \verb+\AxoGrid+ is provided for drawing a grid. One + use is to provide a useful tool in designing pictures. + +\item Since there are now many more possibilities to specify the + properties of a line, optional arguments to the main line drawing + commands can be used to specify them in a keyword style. + +\item A new macro named \verb+\Arc+ is introduced. With the aid of + optional arguments, this unifies the behavior of various arc-drawing + commands in the original axodraw. + +\item For consistency with the \verb+\Gluon+ macro, the + \verb+\GlueArc+ macro has been renamed to \verb+\GluonArc+, with the old + macro retained as a synonym. + +\item The behavior of arcs is changed to what we think is more natural + behavior when the specified opening is outside the natural range. + +\item What we call macros for drawing objects with postscript text are + now implemented within \LaTeX{} instead of relying on instructions + inserted in the postscript code. Thus all the normal \LaTeX{} + commands, including mathematics, can now be used in all text + objects, with proper scaling. The placement and scaling of text + objects are more consistent. + +\item Some new named colors are provided: + \LightYellow{LightYellow}, \LightRed{LightRed}, + \LightBlue{LightBlue}, \LightGray{LightGray}, + \VeryLightBlue{VeryLightBlue}. + (LightYellow, LightRed, LightBlue, LightGray, VeryLightBlue.) + +\item The macros originally specified as \verb+\B2Text+, + \verb+\G2Text+, and \verb+\C2Text+ are now named \verb+\BTwoText+, + \verb+\GTwoText+, and \verb+\CTwoText+. The intent of the + original code was to define macros with names \verb+\B2Text+, etc. + However in normal \TeX, macro names of more than one character + must only contain letters, unlike typical programming languages + that also allow digits. So the rules for \TeX{} macro names mean + that in defining, for example \verb+\def\B2Text(#1,#2)#3#4{...}+, + the original version of axodraw actually defined a macro named + named \verb+\B+, obligatorially followed by \verb+2Text+. This + caused a conflict if the user wished to define a macro \verb+\B+. + If it is desired to retain the old behavior, then the following + should be placed in the preamble of the .tex file, then the + axodraw2 package should be invoked in the source document with the + \texttt{v1compatible} option: + \begin{verbatim} + \usepackage[v1compatible]{axodraw2} + \end{verbatim} + +\end{itemize} + +\subsection{Changes relative to axodraw4j distributed with JaxoDraw} +\label{sec:changes.wrt.4j} + +The JaxoDraw program \cite{jaxodraw2} is distributed with a +version of axodraw called axodraw4j. As of July 2014, this was +effectively a predecessor of axodraw2, but without the possibility of +working with \program{pdflatex}. (The suffix ``4j'' is intended to mean ``for +JaxoDraw''.) + +The changes in axodraw2 relative to the version of axodraw4j dated +2008/11/19 are the following subset of those listed in Sec.\ +\ref{sec:changes.wrt.1}: +\begin{itemize} +\item Correction of the oval-drawing bug. +\item The ability to work with \program{pdflatex}, \program{lualatex}, + and \program{xelatex}. +\item The improvements in the handling of color. +\item The double and arrow options for B\'ezier lines. +\item The dash option for gluons and photons. +\item Color option for all lines. +\item Correction of inconsistency of length unit between \TeX{} and + postscript. +\item Better drawing of double gluons and photons. +\item The gluon circle, polygon, rotated box, \verb+\ECirc+, + \verb+\EBoxc+, and the \verb+\AxoGrid+ macros +\item A series of ``LongArrow'' macros for drawing lines with the + arrow at the end. The same effect could only be achieved in + axodraw4j with arrowpos=1 option to the basic line-drawing + commands. +\item A series of macros like \verb+\DashDoubleLine+ to provide access + to the dashed and double properties in the style of the macros + provided in v.\ 1 of axodraw. This is in addition to the optional + arguments that allow the same effect in axodraw4j and in axodraw2. +\item The \texttt{v1compatible} and other options are provided for the + package. +\item Better treatment of the scaling of objects. +\item The treatment of ``postscript text objects'' within \LaTeX{} + itself. +\end{itemize} + + +%--------------- +\subsection{Backward compatibility, etc} + +The official user interface of axodraw2 is backward-compatible with +versions 1 and 4j, with the exception of the issue mentioned above +about the commands that have the signatures \verb+\B2Text+, +\verb+\G2Text+, and \verb+\C2Text+. There are some minor changes in +the objects that are drawn, mostly concerning the exact dimensions of +default arrows and the scaling of the sizes of text objects. The +scoping of color changes is significantly different, but improved. + +The old axodraw only used the tools available in \LaTeX{} in the early +1990s. The new version needs a more modern installation. It has been +extensively tested with TeXLive 2011 and 2016. + +We have tested backwards compatibility by compiling the version 1 +manual with axodraw2; only a trivially modified preamble was needed. +It also worked to compile Collins's QCD book\cite{qcdbook}, +which has a large number +of JaxoDraw figures (processed automatically to pieces of axodraw code +imported into the document); only changes in the preamble were needed. + +Axodraw2 uses the following \LaTeX{} packages: \program{keyval}, +\program{ifthen}, \program{graphicx}, \program{color}, \program{ifxetex}. +It defines its own set of 73 named colors --- Sec.\ \ref{sec:colors} +--- which are the same as the 68 defined as dvips-defined names in the +color package, plus 5 more. + +In addition axodraw2 provides an \verb+axopicture+ environment +inside of which axodraw2's graphics are coded and drawn. In the old +axodraw, \LaTeX's \verb+picture+ environment was used instead. We +recommend the use of \verb+axopicture+ environment in axodraw2, and +that is the only method we document. However, old diagrams coded with +\verb+picture+ environment continue to work. + + +%========================= +\section{Installation} +\label{sec:installation} + +%--------------- +\subsection{Installation from standard \TeX{} distribution} + +At the moment that this document was written, axodraw2 was not part of any +standard \TeX{} distribution. + +It is on CTAN at \url{http://ctan.org/tex-archive/graphics/axodraw2}, +so that it should eventually be part of the standard distributions +(TeXLive and MiKTeX). After that, axodraw2 will either be installed +by default or can be installed by using the package manager of the +\TeX{} distribution. When available, this will be the easiest method +of installation. + + + +%--------------- +\subsection{Manual installation} + +%For a manual installation, the minimum that needs to be done is to put +For a manual installation, what needs to be done is to put +the file \file{axodraw2.sty} in a place where it will be found by +the \program{latex} program. If you wish to use axodraw2 with +\program{pdflatex}, you will also need to compile the \program{axohelp} +program and put it in an appropriate directory. Documentation can +also be installed if you want. + +%-- +\subsubsection{Style file texttt{axodraw2.sty}} + +If you merely want to try out axodraw2, just put the file +\file{axodraw2.sty} in the same directory as the \file{.tex} +file(s) you are working on. + +Otherwise, put it in an appropriate directory for a \LaTeX{} style +file, and, if necessary, run the texhash program to ensure that the +file is in the \TeX{} system's database of files. For example, +suppose that you have a TeXLive system installed for all users on a +Unix-like system (e.g., Linux or OS-X), and that TeXLive is installed, +as is usual, under the directory \file{/usr/local/texlive}. Then an +appropriate place for axodraw2 is in a directory +\file{/usr/local/texlive/texmf-local/tex/latex/axodraw2}. You will +need to run the \program{texhash} program in this last case. For such +a system-wide installation, you will probably have to do these +operations as an administrative user (e.g., root), possibly +supplemented by running the relevant commands with the \program{sudo} +program. + +%-- +\subsubsection{Helper program \program{axohelp}} +\label{sec:axohelp} + +If you wish to use axodraw2 with \program{pdflatex}, \program{lualatex}, +or \program{xelatex}., then you need to install the \program{axohelp} +program. + +On a Unix-like system (e.g., linux or OS-X), you first need to compile +the program by a C compiler. An appropriate shell command to do this +is +\begin{verbatim} + cc -o axohelp -O3 axohelp.c -lm +\end{verbatim} +(Note that this is a C compiler, \emph{not} a C++ compiler.) Most linux +systems have the program \program{cc} already installed. This also applies to +OS-X at versions below 10.7. But on OS-X version 10.7 and higher, you +will need to install a compiler, which can be done by installing XCode +and the associated command-line utilities. If you have the GNU +compilers installed, you might need to use the command \program{gcc} +instead of \program{cc}. + +For Microsoft Windows, if you do not have a C compiler available, you +can use the Windows binary \file{axohelp.exe} we have provided. It +should work with Windows 7 or higher. + +In any case once you have the executable (named \program{axohelp} on +unix-like systems, or \program{axohelp.exe} on a Microsoft system), put +it in a directory where it will be found when you run programs from +the command line. + + +%-- +\subsubsection{Testing} + +To test whether the installation works, you need a simple test file. +An example is given in Sec.\ \ref{sec:example}, and is provided +with the axodraw2 distribution as \file{example.tex}. + +At a command line with the current directory set to the directory +containing the file \file{example.tex}, run the following commands: +\begin{verbatim} + latex example + dvips example -o +\end{verbatim} +If all goes well, you will obtain a file \file{example.ps}. When +you view it, it should contain the diagram shown in Sec.\ +\ref{sec:example}. You can make a pdf file instead by the commands +\begin{verbatim} + latex example + dvipdf example +\end{verbatim} +A more extensive test can be made by compiling the manual. + +To make a pdf file directly, with \program{pdflatex}, you use the commands +\begin{verbatim} + pdflatex example + axohelp example + pdflatex example +\end{verbatim} +The \program{axohelp} run takes as input a file \file{example.ax1} +produced by the first run of \program{pdflatex} and makes an output +file \file{example.ax2}. The second run of \program{pdflatex} reads +the \file{example.ax2} file and uses the result to place the axodraw +objects in the \file{example.pdf} file. + + +%-- +\subsubsection{Documentation} + +Put the documentation in a place where you can find it. If you +installed the \file{axodraw2.sty} file in +\file{/usr/local/texlive/texmf-local/tex/latex/axodraw2}, the +standard place for the documentation would be +\file{usr/local/texlive/texmf-local/doc/latex/axodraw2}. + + +%========================= +\section{Use} +\label{sec:use} + +In this section we show how to use axodraw2, illustrated with an +example. + +\subsection{Basic example} +\label{sec:example} + +The principles of using axodraw2 are illustrated by the following +complete \LaTeX{} document: +\begin{verbatim} + \documentclass{article} + \usepackage{axodraw2} + \begin{document} + Example of Feynman graph using axodraw2 macros: + \begin{center} + \begin{axopicture}(200,110) + \SetColor{Red} + \Arc[arrow](100,50)(40,0,180) + \Text(100,100){$\alpha P_1 + \beta P_2 + k_\perp$} + \SetColor{Black} + \Arc[arrow](100,50)(40,180,360) + \Gluon(0,50)(60,50){5}{4} + \Vertex(60,50){2} + \Gluon(140,50)(200,50){5}{4} + \Vertex(140,50){2} + \end{axopicture} + \end{center} + \end{document} +\end{verbatim} +After compilation according to the instructions in Sec.\ +\ref{sec:doc.compile}, viewing the resulting file should show the +following Feynman graph: +\begin{center} + \begin{axopicture}(200,110) + \SetColor{Red} + \Arc[arrow](100,50)(40,0,180) + \Text(100,100){$\alpha P_1 + \beta P_2 + k_\perp$} + \SetColor{Black} + \Arc[arrow](100,50)(40,180,360) + \Gluon(0,50)(60,50){5}{4} + \Vertex(60,50){2} + \Gluon(140,50)(200,50){5}{4} + \Vertex(140,50){2} + \end{axopicture} +\end{center} +See Sec.\ \ref{sec:examples} for more examples + +\emph{Important note about visibility of graphics objects:} If you +view this document on a computer monitor, Feynman graphs drawn with +narrow lines may not fully match what was intended. This is because +of the way graphics viewers interact with the limited resolution of +computer monitors. To see the example graphs properly, you may need to +use a large enough magnification, or to use an actual print out. + +\emph{Note about sending a document to others}: If for example, you +submit an article to arXiv.org, it is likely that their automated +system for processing the file will not run axohelp. So together with +the tex file, you one should also submit the .ax2 file. + + +%----------------------- +\subsection{Document preparation} +\label{sec:doc.prep} + +The general rules for preparation of a document are: +\begin{itemize} + +\item Insert the following + \begin{verbatim} + \usepackage{axodraw2} + \end{verbatim} + in the preamble of the \file{.tex} file. + There are some options and commands that can be used to change axodraw2's + behavior from its default. See Secs.\ \ref{sec:invoke} and + \ref{sec:settings} for details. + +\item Where you want to insert axodraw2 objects, put them inside an + axopicture environment, specified in Sec.\ \ref{sec:env}, + \begin{verbatim} + \begin{axopicture}(x,y) + ... + \end{axopicture} + \end{verbatim} + Here \texttt{x} and \texttt{y} denote the desired size of the box + that is to be inserted in the document and that contains the graph. + An optional offset can be specified (as with \LaTeX's + \texttt{picture} environment). By default the units are + $\unit[1]{pt} = \unit[1/72.27]{in} = \unit[0.3515]{mm}$. + +\end{itemize} +Full details of all these components are in Sec.\ +\ref{sec:reference}. + +The design of graphs can be done manually, and this can be greatly +facilitated with the new \verb:\AxoGrid: command. A convenient way of +constructing diagrams is to use the graphical program +JaxoDraw~\cite{jaxodraw1,jaxodraw2}, which is what most people +do. This program can export axodraw code. It also uses axodraw as one +way of making postscript and pdf files. The original version of +axodraw was used by JaxoDraw until version 1.3. In version 2 of +JaxoDraw, a specially adapted version of \file{axodraw.sty} is used, +named \file{axodraw4j.sty}. The output from version 2 of +JaxoDraw is compatible with axodraw2. + + +%----------------------- +\subsection{Document compilation} +\label{sec:doc.compile} + +\subsubsection{To make a postscript file} +\label{sec:doc.compile.ps} + +When a postscript file is needed, you just make the postscript file as +usual. E.g., when the source file is \file{example.tex}, you run +the following commands: +\begin{verbatim} + latex example + dvips example -o +\end{verbatim} +which results in a postscript file \file{example.ps}. Of course, if +there are cross references to be resolved, you may need multiple runs +of \program{latex}, as usual. When needed, use of \program{bibtex}, +\program{makeindex}, and other similar programs is also as usual. +Instead of \program{latex}, one may also use the \program{dvilualatex} +program, which behaves like \program{latex} except for providing some +extra capabilities that are sometimes useful. + +Internally, axodraw uses \TeX's \verb+\special+ mechanism to put +specifications of postscript code into the \file{.dvi} file, and +\program{dvips} puts this code in the postscript file. This postscript +code performs the geometrical calculations needed to specific +axodraw's objects, and then draws them when the file is displayed or +printed. + +\emph{Important note about configuration of \program{dvips}:} You may +possibly find that when you run \program{dvips} that it spends a lot of +time running \program{mktexpk} to make bitmapped fonts, or that the +postscript +file contains bitmapped type-3 fonts. This is \emph{not} the default +situation in typical current installations. But if you do find this +situation, which is highly undesirable in most circumstances, you +should arrange for \program{dvips} to use type 1 fonts. This can be +done either by appropriately configuring your \TeX{} installation, for +which you will have to locate instructions, or by giving +\program{dvips} its \texttt{-V0} option: +\begin{verbatim} + dvips -V0 example -o +\end{verbatim} +Once you do this, you should see, from \program{dvips}'s output, +symptoms of its use of type 1 fonts. \emph{Let us re-emphasize that + you do not have to be concerned with this issue, under + normal circumstances. But since things were different within our + memory, we give some suggestions as to what to do in what are + currently abnormal circumstances.} + +\subsubsection{To make a pdf file via \program{latex}} + +There are multiple methods of making pdf files for a latex document; +we will not give all the advantages and disadvantages here. + +One way is to convert the postscript file, e.g., by +\begin{verbatim} + ps2pdf example.ps +\end{verbatim} +You can also produce a pdf file from the dvi file produced by +\program{latex} by the \program{dvipdf} command, e.g,. +\begin{verbatim} + dvipdf example +\end{verbatim} +\emph{Important note:} The program here is \program{dvipdf} and +\emph{not} the similarly named \program{dvipdfm} or \program{dvipdfmx}, +which are incompatible with axodraw. The reason why \program{dvipdf} +works is that it internally makes a postscript file and then converts +it to pdf. + + +\subsubsection{To make a pdf file by \program{pdflatex}, + \program{lualatex}, or \program{xelatex}} + +A common and standard way to make a pdf file is the \program{pdflatex} +program, which makes pdf directly. It has certain advantages, among +which are the possibility of importing a wide variety of graphics file +formats. (In contrast, the \program{latex} program only handles +encapsulated postscript.) + +However, to use axodraw2 with \program{pdflatex}, you need an +auxiliary program, \program{axohelp}, as in +\begin{verbatim} + pdflatex example + axohelp example + pdflatex example +\end{verbatim} +What happens is that during a run of \program{pdflatex}, axodraw2 +%writes a file \file{example.ax1} with specifications of its +writes a file \file{example.ax1} containing specifications of its +graphical objects. Then running \program{axohelp} reads the +%\file{example.ax1} file, computes the necessary pdf code to draw the +\file{example.ax1} file, computes the necessary pdf code to draw the +objects, and writes the results to \file{example.ax2}. The next run +of \program{pdflatex} reads \file{example.ax2} and uses it to put the +appropriate code in the output pdf file. + +The reason for the extra program is that axodraw needs many +geometrical calculations to place and draw its graphical objects. +\LaTeX{} itself does not provide anything convenient and efficient for +these calculations, while the PDF language does not offer sufficient +computational facilities, unlike the postscript language. + +If you modify a document, and recompile with \program{pdflatex}, you +will only need to rerun \program{axohelp} if the modifications +involve axodraw objects. Axodraw2 will output an appropriate message +when a rerun of \program{axohelp} is needed. + +If you wish to use \program{lualatex} or \program{xelatex}, instead of +\program{pdflatex}, then you can simply run the program +\program{lualatex} or \program{xelatex} instead of +\program{pdflatex}. These are equally compatible with axodraw2. + + + + +%----------------------- +\subsection{Automation of document compilation} +\label{sec:doc.auto.compile} + +It can be useful to automate the multiple steps for compiling a +\LaTeX{} document. One of us has provided a program \program{latexmk} +to do this --- see \url{http://www.ctan.org/pkg/latexmk/}. Here we +show how to configure +\program{latexmk} to run \program{axohelp} as needed when a document is +compiled via the \program{pdflatex} route. + +All you need to do is to put the following lines in one of +\program{latexmk}'s initialization files (as specified in its +documentation): +\begin{verbatim} + add_cus_dep( "ax1", "ax2", 0, "axohelp" ); + sub axohelp { return system "axohelp \"$_[0]\""; } + $clean_ext .= " %R.ax1 %R.ax2"; +\end{verbatim} +The first two lines specify that \program{latexmk} is to make +\file{.ax2} files from \file{.ax1} files by the \program{axohelp} +program, whenever necessary. (After that \program{latexmk} +automatically also does any further runs of \program{pdflatex} that are +necessary.) The last line is optional; it adds \file{.ax1} and +\file{.ax2} files to the list of files that will be deleted when +\program{latexmk} is requested to do a clean up of generated, +recreatable files. + +\program{Latexmk} is installed by default by the currently common +distributions of \TeX{} software, i.e., TeXLive and MiKTeX. It has as +an additional requirement a properly installed Perl system. For the +TeXLive distribution, this requirement is always met. + +With the above configuration, you need no change in how you invoke +\program{latexmk} to compile a document, when it uses axodraw2. For +producing postscript, you can simply use +\begin{verbatim} + latexmk -ps example +\end{verbatim} +and for producing pdf via \program{pdflatex} you can use +\begin{verbatim} + latexmk -pdf example +\end{verbatim} +Then \program{latexmk} takes care of whatever runs are needed of all +the relevant programs, now including \program{axohelp}, as well +whatever, possibly multiple, runs are needed for the usual programs +(\program{latex}, \program{pdflatex}, \program{bibtex}, etc). + + + +%>>#] Introduction : +%>>#[ The Commands : + +\section{Reference} +\label{sec:reference} + +\subsection{Package invocation} +\label{sec:invoke} + +To use the axodraw2 package in a \LaTeX{} document, you simply put +\begin{verbatim} + \usepackage{axodraw2} +\end{verbatim} +in the preamble of the document, as normal. + +The \verb+\usepackage+ command takes optional arguments +(comma-separated list of keywords) in square brackets, e.g., +\begin{verbatim} + \usepackage[v1compatible]{axodraw2} +\end{verbatim} +The options supported by axodraw2 are +\begin{itemize} +\item \texttt{v1compatible}: This makes axodraw2's operation more + compatible with v.\ 1. It allows the use of \verb+\B2Text+, + \verb+\G2Text+, and \verb+\C2Text+ as synonyms for the macros named + \verb+\BTwoText+, \verb+\GTwoText+, and \verb+\CTwoText+. + (You may wish also to use the \texttt{canvasScaleisUnitLength} + option, so that the scaling of the units in the \texttt{axopicture} + environment is the same as it was for the \texttt{picture} + environment used in v.\ 1.) +\item \texttt{canvasScaleIs1pt}: Unit for canvas dimensions + in an \texttt{axopicture} environment is fixed at $\unit[1]{pt}$, +\item \texttt{canvasScaleIsObjectScale}: Unit for canvas dimensions + in an \texttt{axopicture} environment are the same as those set for + axodraw objects (by the \verb+\SetScale+ macro). This is the + default setting, so the option need not be given. +\item \texttt{canvasScaleIsUnitLength}: Unit for canvas dimensions + in an \texttt{axopicture} environment is the current value of + \verb+\unitlength+, exactly as for \LaTeX{}'s \texttt{picture} + environment. (Thus, this corresponds to the behavior of the + original axodraw v.\ 1, which simply used the \texttt{picture} + environment.) +\item \texttt{PStextScalesIndependently}: Axodraw's text objects are + scaled by the factor set by the \verb+\SetTextScale+ command. +\item \texttt{PStextScalesLikeGraphics}: Axodraw's text objects are + scaled by the factor set by same factor for its graphics objects, + i.e., the scale set by the \verb+\SetScale+ command. +\end{itemize} +(N.B. Default scaling factors are initialized to unity.) + +\emph{Note:} If you use \program{axodraw}'s commands for placing text +and you use the standard \TeX{} Computer Modern fonts for the +document, then when you compile your document you may get a lot of +warning messages. These are about fonts not being available in +certain sizes. To fix this problem invoke the package +\program{fix-cm} in your document's preamble: +\begin{verbatim} + \usepackage{fix-cm} +\end{verbatim} +It is also possible to use the package \program{lmodern} for the same +purpose. + + +\subsection{Environment(s)} +\label{sec:env} + +The graphical and other objects made by axodraw2 are placed in an +\texttt{axopicture} environment, which is invoked either as +\begin{verbatim} + \begin{axopicture}(x,y) + ... + \end{axopicture} +\end{verbatim} +or +\begin{verbatim} + \begin{axopicture}(x,y)(xoffset,yoffset) + ... + \end{axopicture} +\end{verbatim} +Here, the \dots{} denote sequences of axodraw2 commands, as documented +in later sections, for drawing lines, etc. The \texttt{axopicture} +environment is just like standard \LaTeX's \texttt{picture} +environment,\footnote{In fact, the \texttt{axopicture} is changed from + the \texttt{picture} environment only by making some + axodraw-specific settings. So the \texttt{picture} environment that + was used in v.\ 1 may also be used with axodraw2; it merely has a + lack of automation on the setting of the canvas scale relative to + the object scale, and, in the future, other possible + initializations.}, except for doing some axodraw-specific +initialization. It inserts a region of size \texttt{x} by \texttt{y} +(with default units of $\unit[1]{pt} = \unit[1/72.27]{in} = +\unit[0.3515]{mm}$). Here \texttt{x} and \texttt{y} are set to the +numerical values you need. + +The positioning of axodraw objects is specified by giving $x$ and $y$ +coordinates, e.g., for the ends of lines. The origin of these +coordinates is, by default, at the lower left corner of the box that +\texttt{axopicture} inserts in your document. But sometimes, +particularly after editing a graph, you will find this is not +suitable. To avoid changing a lot of coordinate values to get correct +placement, you can specify an offset by the optional arguments +\texttt{(xoffset,yoffset)} to the \texttt{axopicture} environment, +exactly as for \LaTeX's \texttt{picture} environment. The offset +\texttt{(xoffset,yoffset)} denotes the position of the bottom left +corner of the box inserted in your document relative to the coordinate +system used for specifying object positions. Thus +\begin{verbatim} + \begin{axopicture}(20,20) + \Line(0,0)(20,20) + \end{axopicture} +\end{verbatim} +and +\begin{verbatim} + \begin{axopicture}(20,20)(-10,20) + \Line(-10,20)(10,40) + \end{axopicture} +\end{verbatim} +are exactly equivalent. + +Within an \texttt{axopicture} environment, all the commands that can +be used inside an ordinary \texttt{picture} environment can also be +used. + +We can think of the \texttt{axopicture} environment as defining a +drawing canvas for axodraw's graphical and text objects. +There are possibilities for manipulating (separately) the units used +to specify the canvas and the objects. These can be useful for +scaling a diagram or parts of it from an originally chosen design. +See Secs.\ \ref{sec:units} and \ref{sec:settings} for details. + + +\subsection{Graphics drawing commands} +\label{sec:commands} + +In this section we present commands for drawing graphical objects, +split up by category. Later, we will give: details of options to the +line-drawing commands, explanations of some details about specifying +gluons and about specifying arrow parameters, and then commands for +textual objects and for adjusting settings (e.g., separation in a +double line). Mostly, we present the commands by means of examples. +Note that many of the arguments of the commands, notably arguments for +$(x,y)$ coordinate values are delimited by parentheses and commas +instead of the brace delimiters typically used in \LaTeX. + +It should also be noted that some commands provide different ways of +performing the same task. For instance +\begin{verbatim} + \BCirc(50,50){30} +\end{verbatim} +can also be represented by +\begin{verbatim} + \CCirc(50,50){30}{Black}{White} +\end{verbatim} +when the current color is black. The presence of the BCirc command has been +maintained both for backward compatibility, and because it represents +a convenient short hand for a common situation. This also holds for similar +commands involving boxes and triangles. For the new Polygon, FilledPolygon, +RotatedBox and FilledRotatedBox commands we have selected a more minimal +scheme. + +Similar remarks apply to the new feature of options for line drawing +commands. Originally in v.\ 1, a line with an arrow would be coded as +\begin{verbatim} + \ArrowLine(30,65)(60,25) +\end{verbatim} +It is now also possible to code using the general \verb+\Line+ macro, +but with a keyword optional argument: +\begin{verbatim} + \Line[arrow](30,65)(60,25) +\end{verbatim} +One advantage of the option method is a variety of other properties of +an individual line may also be coded, as in +\begin{verbatim} + \Line[arrow,arrowpos=1](30,65)(60,25) +\end{verbatim} +without the need to use separate global setting for the property, by +the commands listed in Sec.\ \ref{sec:settings}, or by having a +corresponding compulsory argument to the command. +Which way to do things is a matter of user taste in particular +situations. + +%--#[ AxoGrid : + +\subsubsection{Grid drawing} + +\noindent +\begin{minipage}{3.83cm} +\begin{axopicture}{(90,140)(-10,0)} +\AxoGrid(0,0)(10,10)(9,14){LightGray}{0.5} +\end{axopicture} +\end{minipage} +\begin{minipage}{11.5cm} +\label{axogrid} +\verb:\AxoGrid(0,0)(10,10)(9,14){LightGray}{0.5}: \hfill \\ +This command is used in our examples to allow the reader to compare the +coordinates in the commands with those of the actual picture. The arguments +are first the position of the left bottom corner, then two values that tell +the size of the divisions in the $x$ and $y$ direction. Next there are two +values that specify how many divisions there should be in the $x$ and $y$ +direction. Then the color of the lines is given and finally the width of +the lines. Note that if there are $(n_x,n_y)$ divisions there will be +$n_x+1$ vertical lines and $n_y+1$ horizontal lines. The temporary use of +this command can also be convenient when designing pictures manually. +\end{minipage}\vspace{4mm} + +%--#] AxoGrid : +%--#[ Line : + +\subsubsection{Ordinary straight lines} +\label{sec:Line} + + +All of the commands in this section can be given optional keyword +arguments, which are defined in Secs.\ \ref{sec:options} and +\ref{sec:arrows}. These can be used to specify the type of line +(dashed, double), to specify the use of an arrow, and its parameters, and +to specify some of the line's parameters. + +The basic line drawing command is \verb+\Line+:\\[3mm] +\begin{minipage}{3.83cm} +\begin{axopicture}{(90,40)(-10,0)} +\AxoGrid(0,0)(10,10)(9,4){LightGray}{0.5} +\Line(10,10)(80,30) +\end{axopicture} +\end{minipage} +\begin{minipage}{11.5cm} +\label{line} +\verb:\Line(10,10)(80,30): \hfill \\ +In this command we have two coordinates. The (solid) line goes from the +first to the second. +\end{minipage}\vspace{4mm} + +Examples of the use of optional arguments are:\\[3mm] +\begin{minipage}{3.83cm} +\begin{axopicture}{(90,80)(-10,0)} +\AxoGrid(0,0)(10,10)(9,8){LightGray}{0.5} +\Line[color=Magenta,arrow](10,70)(80,70) +\Line[dash](10,50)(80,50) +\Line[arrow,double](10,30)(80,30) +\Line[arrow,dash,double](10,10)(80,10) +\end{axopicture} +\end{minipage} +\begin{minipage}{11.5cm} +\label{line.options} +\begin{verbatim} +\Line[color=Magenta,arrow](10,70)(80,70) +\Line[dash](10,50)(80,50) +\Line[arrow,double](10,30)(80,30) +\Line[arrow,dash,double](10,10)(80,10) +\end{verbatim} +\end{minipage} +\\[4mm] +Details of the specification of arrows, together with alternative +commands for making lines with arrows are given in Sec.\ +\ref{sec:arrows}. + +\vspace{4mm} +%--#] Line : +%--#[ DoubleLine : + +Alternative commands for dashed and/or double lines are:\\[3mm] +\noindent +\begin{minipage}{3.83cm} +\begin{axopicture}{(90,40)(-10,0)} +\AxoGrid(0,0)(10,10)(9,4){LightGray}{0.5} +\DoubleLine(10,25)(80,25){1} +\DoubleLine[color=Red](10,15)(80,15){2} +\end{axopicture} +\end{minipage} +\begin{minipage}{11.5cm} +\label{doubleline} +\verb:\DoubleLine(10,25)(80,25){1}: \hfill \\ +\verb:\DoubleLine[color=Red](10,15)(80,15){2}: \hfill \\ +In this command we have two coordinates as in the Line command but two +lines are drawn. The extra parameter is the separation between the two +lines. Note however that everything between the lines is blanked out. +\end{minipage}\vspace{4mm} + +%--#] DoubleLine : +%--#[ DashLine : + +\noindent +\begin{minipage}{3.83cm} +\begin{axopicture}{(90,40)(-10,0)} +\AxoGrid(0,0)(10,10)(9,4){LightGray}{0.5} +\DashLine(10,25)(80,25){2} +\DashLine(10,15)(80,15){6} +\end{axopicture} +\end{minipage} +\begin{minipage}{11.5cm} +\label{dashline} +\verb:\DashLine(10,25)(80,25){2}: \hfill \\ +\verb:\DashLine(10,15)(80,15){6}: \hfill \\ +In this command we have two coordinates. The dashed line goes from the +first to the second. The extra parameter is the size of the dashes. The +space between the dashes is transparent. +\end{minipage}\vspace{4mm} + +%--#] DashLine : +%--#[ DashDoubleLine : + +\noindent +\begin{minipage}{3.83cm} +\begin{axopicture}{(90,40)(-10,0)} +\AxoGrid(0,0)(10,10)(9,4){LightGray}{0.5} +\DashDoubleLine(10,25)(80,25){1.5}{2} +\DashDoubleLine(10,15)(80,15){1.5}{6} +\end{axopicture} +\end{minipage} +\begin{minipage}{11.5cm} +\label{dashdoubleline} +\verb:\DashDoubleLine(10,25)(80,25){1.5}{2}: \hfill \\ +\verb:\DashDoubleLine(10,15)(80,15){1.5}{6}: \hfill \\ +In this command we have two coordinates. The dashed lines go from the +first to the second. The first extra parameter is the separation between +the lines and the second extra parameter is the size of the dashes. +\end{minipage}\vspace{4mm} + +%--#] DashDoubleLine : +%--#[ Arc : + +\subsubsection{Arcs} +\label{sec:Arc} + +The commands in this section draw circular arcs in types corresponding +to the straight lines of Sec.\ \ref{sec:Line}. In v.\ 1, some of +these commands had names containing ``Arc'' and some ``CArc''. Some +kinds had variant names containing ``Arcn'', whose the direction of +drawing was clockwise instead of anticlockwise. In v.\ 2, we have +tried to make the situation more consistent. First, all the old names +have been retained, for backward compatibility. Second, a general +purpose command \verb+\Arc+ has been introduced; in a single command, +with the aid of optional arguments, it covers all the variants. See +Secs.\ \ref{sec:options} and \ref{sec:arrows} for full details. The +options can be used to specify the type of line (dashed, double, +clockwise or anticlockwise), to specify the use of arrow, and its +parameters, and to specify some of the line's parameters. The other +commands in this section can also be given optional keyword arguments. + +The basic \verb+\Arc+ command has the form\\[3mm] +\noindent +\begin{minipage}{3.83cm} +\begin{axopicture}{(90,50)(-10,0)} +\AxoGrid(0,0)(10,10)(9,5){LightGray}{0.5} +\Arc(45,0)(40,20,160) +\end{axopicture} +\end{minipage} +\begin{minipage}{11.5cm} +\label{carc} +\verb:\Arc(45,0)(40,20,160):\hfill \\ +In this command we have one coordinate: the center of the circle. Then +follow the radius of the circle, the start angle and the finishing angle. +The arc will be drawn counterclockwise. +\end{minipage}\vspace{4mm} + +An example of the use of the optional parameters is:\\[3mm] +\begin{minipage}{3.83cm} +\begin{axopicture}{(80,80)(-10,0)} +\AxoGrid(0,0)(10,10)(8,8){LightGray}{0.5} +\Arc[arrow,dash,clockwise](40,40)(30,20,160) +\end{axopicture} +\end{minipage} +\begin{minipage}{11.5cm} +\label{carc.opt} +\verb:\Arc[arrow,dash,clockwise](40,40)(30,20,160): +\end{minipage}\vspace{4mm} + +Alternative commands for dashed and/or double arcs are as follows. +\vspace*{4mm} + +%--#] Arc : +%--#[ DoubleArc : + +\noindent +\begin{minipage}{3.83cm} +\begin{axopicture}{(90,50)(-10,0)} +\AxoGrid(0,0)(10,10)(9,5){LightGray}{0.5} +\DoubleArc[color=Green](45,0)(40,20,160){2} +\end{axopicture} +\end{minipage} +\begin{minipage}{11.5cm} +\label{doublearc} +\verb:\DoubleArc[color=Green](45,0)(40,20,160){2}:\hfill \\ +In this command we have one coordinate: the center of the circle. Then +follow the radius of the circle, the start angle and the finishing angle. +The arc will be drawn counterclockwise. The last argument is the line +separation of the double line. +\end{minipage}\vspace{4mm} + +%--#] DoubleArc : +%--#[ DashArc : + +\noindent +\begin{minipage}{3.83cm} +\begin{axopicture}{(90,50)(-10,0)} +\AxoGrid(0,0)(10,10)(9,5){LightGray}{0.5} +\DashArc(45,0)(40,20,160){4} +\end{axopicture} +\end{minipage} +\begin{minipage}{11.5cm} +\label{dasharc} +\verb:\DashArc(45,0)(40,20,160){4}:\hfill \\ +In this command we have one coordinate: the center of the circle. Then +follow the radius of the circle, the start angle and the finishing angle. +The arc will be drawn counterclockwise. The last argument is the size of +the dashes. +\end{minipage}\vspace{4mm} + +%--#] DashArc : +%--#[ DashDoubleArc : + +\noindent +\begin{minipage}{3.83cm} +\begin{axopicture}{(90,50)(-10,0)} +\AxoGrid(0,0)(10,10)(9,5){LightGray}{0.5} +\DashDoubleArc(45,0)(40,20,160){2}{4} +\end{axopicture} +\end{minipage} +\begin{minipage}{11.5cm} +\label{dashdoublearc} +\verb:\DashDoubleArc(45,0)(40,20,160){2}{4}:\hfill \\ +In this command we have one coordinate: the center of the circle. Then +follow the radius of the circle, the start angle and the finishing angle. +The arc will be drawn counterclockwise. The last two arguments are the line +separation of the double line and the size of the dashes. +\end{minipage}\vspace{4mm} + +%--#] DashDoubleArc : +%--#[ Bezier : + +\subsubsection{B\'ezier lines} +\label{sec:Bezier} + +The commands in this section draw B\'ezier curves, specified by 4 +points. The variants are just as for straight lines, Sec.\ +\ref{sec:Line}. + +All of the commands in this section can be given optional keyword +arguments, which are defined in Sec.\ \ref{sec:options}. These can be +used to specify the type of line (dashed, double), to specify the use +of an arrow, and its parameters, and to specify some of the line's +parameters. + +The basic general purpose command is \verb+\Bezier+:\\[3mm] +\noindent +\begin{minipage}{3.83cm} +\begin{axopicture}{(60,60)(-25,0)} +\AxoGrid(0,0)(10,10)(6,6){LightGray}{0.5} +\Bezier(10,10)(75,30)(65,40)(20,50) +\end{axopicture} +\end{minipage} +\begin{minipage}{11.5cm} +\label{bezier} +\verb:\Bezier(10,10)(75,30)(65,40)(20,50): \hfill \\ +Draws a cubic B\'ezier curve based on the four given points. The first +point is the starting point and the fourth the finishing point. The +second and third points are the two control points. +\end{minipage}\vspace{4mm} + +An example of the use of optional arguments is +\\[3mm] +\begin{minipage}{3.83cm} +\begin{axopicture}{(60,60)(-25,0)} +\AxoGrid(0,0)(10,10)(6,6){LightGray}{0.5} +\Bezier[color=Red,arrow,double,arrowpos=1](10,10)% + (75,30)(65,40)(20,50) +\end{axopicture} +\end{minipage} +\begin{minipage}{11.5cm} +\label{bezier.opt} +\begin{verbatim} + \Bezier[color=Red,arrow,double,arrowpos=1](10,10)% + (75,30)(65,40)(20,50) +\end{verbatim} +\end{minipage}\vspace{4mm} + +%--#] Bezier : +%--#[ DoubleBezier : +Alternative ways of making dashed and/or double B\'ezier curves +are:\\[3mm] +\noindent +\begin{minipage}{3.83cm} +\begin{axopicture}{(60,60)(-25,0)} +\AxoGrid(0,0)(10,10)(6,6){LightGray}{0.5} +\DoubleBezier(10,10)(75,30)(65,40)(20,50){1.5} +\end{axopicture} +\end{minipage} +\begin{minipage}{11.5cm} +\label{doublebezier} +\verb:\DoubleBezier(10,10)(75,30)(65,40)(20,50){1.5}: \hfill \\ +Draws a cubic B\'ezier curve based on the four given points. +The first four arguments are the same as for \verb+\Bezier+. +The final argument is the line separation. +\end{minipage}\vspace{4mm} + +%--#] DoubleBezier : +%--#[ DashBezier : + +\noindent +\begin{minipage}{3.83cm} +\begin{axopicture}{(60,60)(-25,0)} +\AxoGrid(0,0)(10,10)(6,6){LightGray}{0.5} +\DashBezier(10,10)(75,30)(65,40)(20,50){4} +\end{axopicture} +\end{minipage} +\begin{minipage}{11.5cm} +\label{dashbezier} +\verb:\DashBezier(10,10)(75,30)(65,40)(20,50){4}: \hfill \\ +Draws a cubic B\'ezier curve based on the four given points. +The first four arguments are the same as for \verb+\Bezier+. +The final argument is the size of the dashes. +\end{minipage}\vspace{4mm} + +%--#] DashBezier : +%--#[ DashDoubleBezier : + +\noindent +\begin{minipage}{3.83cm} +\begin{axopicture}{(60,60)(-25,0)} +\AxoGrid(0,0)(10,10)(6,6){LightGray}{0.5} +\DashDoubleBezier(10,10)(75,30)(65,40)(20,50){1.5}{4} +\end{axopicture} +\end{minipage} +\begin{minipage}{11.5cm} +\label{dashdoublebezier} +\verb:\DashDoubleBezier(10,10)(75,30)(65,40)(20,50){1.5}{4}: +Draws a cubic B\'ezier curve based on the four given points. +The first four arguments are the same as for \verb+\Bezier+. +The final two arguments are the line separation and the size of the +dashes. +\end{minipage}\vspace{4mm} + +%--#] DashDoubleBezier : +%--#[ Curve : + +\subsubsection{Curves} + +The commands in this section draw curves through an arbitrary sequence +of points. They only exist in variants for continuous and dashed +lines. No optional arguments are allowed. +\vspace{4mm} + +\noindent +\begin{minipage}{3.83cm} +\begin{axopicture}{(60,60)(-25,0)} +\AxoGrid(0,0)(10,10)(6,6){LightGray}{0.5} +\Curve{(5,55)(10,32.5)(15,23)(20,18)(25,14.65)(30,12.3)(40,9.5)(55,7)} +\end{axopicture} +\end{minipage} +\begin{minipage}{11.5cm} +\label{curve} +\verb:\Curve{(5,55)(10,32.5)(15,23)(20,18): \hfill \\ +\verb: (25,14.65)(30,12.3)(40,9.5)(55,7)}: \hfill \\ +Draws a smooth curve through the given points. The $x$ coordinates of the +points should be in ascending order. The curve is obtained by constructing +quadratic fits to each triplet of adjacent points and then in each interval +between two points interpolating between the two relevant parabolas. +\end{minipage}\vspace{4mm} + +%--#] Curve : +%--#[ DashCurve : + +\noindent +\begin{minipage}{3.83cm} +\begin{axopicture}{(60,60)(-25,0)} +\AxoGrid(0,0)(10,10)(6,6){LightGray}{0.5} +\DashCurve{(5,55)(10,32.5)(15,23)(20,18)(25,14.65)(30,12.3)(40,9.5)(55,7)}{4} +\end{axopicture} +\end{minipage} +\begin{minipage}{11.5cm} +\label{dashcurve} +\verb:\DashCurve{(5,55)(10,32.5)(15,23)(20,18): \hfill \\ +\verb: (25,14.65)(30,12.3)(40,9.5)(55,7)}{4}: \hfill \\ +Draws a smooth dashed curve through the given points. The $x$ coordinates of +the points should be in ascending order. The last argument is the size of +the dashes. +\end{minipage}\vspace{4mm} + +%--#] DashCurve : +%--#[ Gluon : + +\subsubsection{Gluon lines} +\label{sec:Gluon} + +The basic gluon drawing commands are \verb+\Gluon+, \verb+\GluonArc+, +\verb+\GluonCirc+. There are also variants for dashed and double +gluons. But arrows aren't possible. + +See Sec.\ \ref{sec:gluon.remarks} for additional information on the +shape of gluon lines. + +All of the commands in this section can be given optional keyword +arguments, which are defined in Sec.\ \ref{sec:options}. These can be +used to specify the type of line (dashed, double), and to specify some +of the line's parameters. +\vspace{3mm} + +\noindent +\begin{minipage}{3.83cm} +\begin{axopicture}{(90,40)(-10,0)} +\AxoGrid(0,0)(10,10)(9,4){LightGray}{0.5} +\Gluon(10,20)(80,20){5}{7} +\end{axopicture} +\end{minipage} +\begin{minipage}{11.5cm} +\label{gluon} +\verb:\Gluon(10,20)(80,20){5}{7}: \hfill \\ +In this command we have coordinates for the start and end of the line, +the amplitude of the windings and the number of windings. A negative +value for the amplitude reverses the orientation of the windings --- +see Sec.\ \ref{sec:gluon.remarks} for details. +\end{minipage} +\\[4mm] +Optional arguments can be used, e.g., \hfill \\[3mm] +\noindent +\begin{minipage}{3.83cm} +\begin{axopicture}{(90,40)(-10,0)} +\AxoGrid(0,0)(10,10)(9,4){LightGray}{0.5} +\Gluon[color=Blue,dash,dashsize=1,double](10,20)(80,20){4}{7} +\end{axopicture} +\end{minipage} +\begin{minipage}{11.5cm} +\label{gluon.opt} +\verb:\Gluon[color=Blue,dash,double](10,20)(80,20){4}{7}: +\end{minipage} + + +\vspace{4mm} + +%--#] Gluon : +%--#[ DoubleGluon : +\noindent +Examples of the other commands for various types of gluon line are as +follows. They can all take optional arguments. +\\[3mm] +\begin{minipage}{3.83cm} +\begin{axopicture}{(90,40)(-10,0)} +\AxoGrid(0,0)(10,10)(9,4){LightGray}{0.5} +\DoubleGluon(10,20)(80,20){5}{7}{1.3} +\end{axopicture} +\end{minipage} +\begin{minipage}{11.5cm} +\label{doublegluon} +\verb:\DoubleGluon(10,20)(80,20){5}{7}{1.3}:\hfill \\ +The first 6 arguments are as in the \verb+\Gluon+ command. The +extra argument is the line separation. +\end{minipage}\vspace{4mm} + +%--#] DoubleGluon : +%--#[ DashGluon : + +\noindent +\begin{minipage}{3.83cm} +\begin{axopicture}{(90,40)(-10,0)} +\AxoGrid(0,0)(10,10)(9,4){LightGray}{0.5} +\DashGluon(10,20)(80,20){5}{7}{1} +\end{axopicture} +\end{minipage} +\begin{minipage}{11.5cm} +\label{dashgluon} +\verb:\DashGluon(10,20)(80,20){5}{7}{1}:\hfill \\ +The first 6 arguments are as in the \verb+Gluon+ command. The +extra argument is the size of the dashes. +\end{minipage}\vspace{4mm} + +%--#] DashGluon : +%--#[ DashDoubleGluon : + +\noindent +\begin{minipage}{3.83cm} +\begin{axopicture}{(90,40)(-10,0)} +\AxoGrid(0,0)(10,10)(9,4){LightGray}{0.5} +\DashDoubleGluon(10,20)(80,20){5}{7}{1.3}{1} +\end{axopicture} +\end{minipage} +\begin{minipage}{11.5cm} +\label{dashdoublegluon} +\verb:\DashDoubleGluon(10,20)(80,20){5}{7}{1.3}{1}:\hfill \\ +The first 7 arguments are as in the \verb+DoubleGluon+ +command. +The last two arguments are the line +separation of the double line and the size of the dashes. +\end{minipage} +\vspace{8mm} + +%--#] DashDoubleGluon : +%--#[ GluonArc : + +\noindent +\begin{minipage}{3.83cm} +\begin{axopicture}{(90,50)(-10,0)} +\AxoGrid(0,0)(10,10)(9,5){LightGray}{0.5} +\GluonArc(45,0)(40,20,160){5}{8} +\end{axopicture} +\end{minipage} +\begin{minipage}{11.5cm} +\label{gluonarc} +\verb:\GluonArc(45,0)(40,20,160){5}{8}:\hfill \\ +In this command we have one coordinate: the center of the circle. Then +follow the radius of the circle, the start angle and the finishing angle. +The arc will be drawn counterclockwise. The final two parameters are the +amplitude of the windings and the number of windings. +Like the other commands in this section, this command can take +optional arguments, Sec.\ \ref{sec:options}. +\end{minipage} +\vspace{4mm} + +%--#] GluonArc : +%--#[ DoubleGluonArc : + +\noindent +\begin{minipage}{3.83cm} +\begin{axopicture}{(90,50)(-10,0)} +\AxoGrid(0,0)(10,10)(9,5){LightGray}{0.5} + \DoubleGluonArc[color=Red](45,0)(40,20,160)% + {5}{8}{1.3} +\end{axopicture} +\end{minipage} +\begin{minipage}{11.5cm} +\label{doublegluonarc} +\begin{verbatim} + \DoubleGluonArc[color=Red](45,0)(40,20,160)% + {5}{8}{1.3} +\end{verbatim} +The first 7 arguments are as in the \verb+GluonArc+ command. The extra +argument is the separation in the double line. +\end{minipage}\vspace{4mm} + +%--#] DoubleGluonArc : +%--#[ DashGluonArc : + +\noindent +\begin{minipage}{3.83cm} +\begin{axopicture}{(90,50)(-10,0)} +\AxoGrid(0,0)(10,10)(9,5){LightGray}{0.5} +\DashGluonArc(45,0)(40,20,160){5}{8}{1.5} +\end{axopicture} +\end{minipage} +\begin{minipage}{11.5cm} +\label{dashgluonarc} +\verb:\DashGluonArc(45,0)(40,20,160){5}{8}{1.5}:\hfill \\ +The first 7 arguments are as in the \verb+GluonArc+ command. The extra +argument is the size of the dash segments. +\end{minipage}\vspace{4mm} + +%--#] DashGluonArc : +%--#[ DashDoubleGluonArc : + +\noindent +\begin{minipage}{3.83cm} +\begin{axopicture}{(90,50)(-10,0)} +\AxoGrid(0,0)(10,10)(9,5){LightGray}{0.5} +\DashDoubleGluonArc(45,0)(40,20,160){5}{8}{1.3}{1.5} +\end{axopicture} +\end{minipage} +\begin{minipage}{11.5cm} +\label{dashdoublegluonarc} +\verb:\DashDoubleGluonArc(45,0)(40,20,160){5}{8}{1.3}{1.5}:\hfill \\ +The first 7 arguments are as in the \verb+GluonArc+ command. The extra +arguments are the separation of the lines and the size of the dash +segments. +\end{minipage}\vspace{10mm} + +%--#] DashDoubleGluonArc : +%--#[ GluonCirc : + +\noindent +\begin{minipage}{3.83cm} +\begin{axopicture}{(80,80)(-15,0)} +\AxoGrid(0,0)(10,10)(8,8){LightGray}{0.5} +\GluonCirc(40,40)(30,0){5}{16} +\end{axopicture} +\end{minipage} +\begin{minipage}{11.5cm} +\label{gluoncirc} +\verb:\GluonCirc(40,40)(30,0){5}{16}:\hfill \\ +The arguments are: Coordinates for the center of the circle, the +radius and a phase, the +amplitude of the gluon windings and the number of windings. +Like the other commands in this section, this command can take +optional arguments, Sec.\ \ref{sec:options}. The phase argument +specifies a counterclockwise rotation of the line relative to a +default starting point. +\end{minipage}\vspace{4mm} + +%--#] GluonCirc : +%--#[ DoubleGluonCirc : + +\noindent +\begin{minipage}{3.83cm} +\begin{axopicture}{(80,80)(-15,0)} +\AxoGrid(0,0)(10,10)(8,8){LightGray}{0.5} +\DoubleGluonCirc[color=Red](40,40)(30,0){5}{16}{1.3} +\end{axopicture} +\end{minipage} +\begin{minipage}{11.5cm} +\label{doublegluoncirc} +\verb:\DoubleGluonCirc[color=Red](40,40)(30,0){5}{16}{1.3}:\hfill \\ +The first 6 arguments are as for the \verb+GluonCirc+ command. The +final argument is the line separation. +\end{minipage}\vspace{4mm} + +%--#] DoubleGluonCirc : +%--#[ DashGluonCirc : + +\noindent +\begin{minipage}{3.83cm} +\begin{axopicture}{(80,80)(-15,0)} +\AxoGrid(0,0)(10,10)(8,8){LightGray}{0.5} +\DashGluonCirc(40,40)(30,0){5}{16}{1.5} +\end{axopicture} +\end{minipage} +\begin{minipage}{11.5cm} +\label{dashgluoncirc} +\verb:\DashGluonCirc(40,40)(30,0){5}{16}{1.5}:\hfill \\ +The first 6 arguments are as for the \verb+GluonCirc+ command. +The final argument is the size of the dashes. +\end{minipage}\vspace{4mm} + +%--#] DashGluonCirc : +%--#[ DashDoubleGluonCirc : + +\noindent +\begin{minipage}{3.83cm} +\begin{axopicture}{(80,80)(-15,0)} +\AxoGrid(0,0)(10,10)(8,8){LightGray}{0.5} +\DashDoubleGluonCirc(40,40)(30,0){5}{16}{1.3}{1.5} +\end{axopicture} +\end{minipage} +\begin{minipage}{11.5cm} +\label{dashdoublegluoncirc} +\verb:\DashDoubleGluonCirc(40,40)(30,0){5}{16}{1.3}{1.5}:\hfill \\ +The first 6 arguments are as for the \verb+GluonCirc+ command. +The final 2 arguments are the line separation and the size of the +dashes. +\end{minipage}\vspace{4mm} + +%--#] DashDoubleGluonCirc : +%--#[ Photon : + +\subsubsection{Photon lines} +\label{sec:Photon} + +The basic drawing commands for drawing photon lines are \verb+\Photon+ +and \verb+\PhotonArc+. There are also variants for dashed and double +photons. But arrows aren't possible. + +All of the commands in this section can be given optional keyword +arguments, which are defined in Sec.\ \ref{sec:options}. These can be +used to specify the type of line (dashed, double), and to specify some +of the line's parameters.\vspace{3mm} + +\noindent +\begin{minipage}{3.83cm} +\begin{axopicture}{(90,40)(-10,0)} +\AxoGrid(0,0)(10,10)(9,4){LightGray}{0.5} +\Photon(10,20)(80,20){5}{7} +\end{axopicture} +\end{minipage} +\begin{minipage}{11.5cm} +\label{photon} +\verb:\Photon(10,20)(80,20){5}{7}: \hfill \\ +In this command we have two coordinates, the amplitude of the wiggles and +the number of wiggles. +A negative value for the amplitude will reverse the orientation of the +wiggles. +The line will be drawn with the number of wiggles rounded to the +nearest half integer. +Like the other commands in this section, this command can take +optional arguments, Sec.\ \ref{sec:options}. +\end{minipage}\vspace{4mm} + +%--#] Photon : +%--#[ DoublePhoton : + +\noindent +\begin{minipage}{3.83cm} +\begin{axopicture}{(90,40)(-10,0)} +\AxoGrid(0,0)(10,10)(9,4){LightGray}{0.5} +\DoublePhoton(10,20)(80,20){5}{7}{1.3} +\end{axopicture} +\end{minipage} +\begin{minipage}{11.5cm} +\label{doublephoton} +\verb:\DoublePhoton(10,20)(80,20){5}{7}{1.3}:\hfill \\ +The first 6 arguments are as in the \verb+Photon+ command. The +extra argument is the line separation. +\end{minipage}\vspace{4mm} + +%--#] DoublePhoton : +%--#[ DashPhoton : + +\noindent +\begin{minipage}{3.83cm} +\begin{axopicture}{(90,40)(-10,0)} +\AxoGrid(0,0)(10,10)(9,4){LightGray}{0.5} +\DashPhoton[color=Red](10,20)(80,20){5}{7}{1} +\end{axopicture} +\end{minipage} +\begin{minipage}{11.5cm} +\label{dashphoton} +\verb:\DashPhoton[color=Red](10,20)(80,20){5}{7}{1}:\hfill \\ +The first 6 arguments are as in the \verb+Photon+ command. The +extra argument is the size of the dashes. +\end{minipage}\vspace{4mm} + +%--#] DashPhoton : +%--#[ DashDoublePhoton : + +\noindent +\begin{minipage}{3.83cm} +\begin{axopicture}{(90,40)(-10,0)} +\AxoGrid(0,0)(10,10)(9,4){LightGray}{0.5} +\DashDoublePhoton(10,20)(80,20){5}{7}{1.3}{1} +\end{axopicture} +\end{minipage} +\begin{minipage}{11.5cm} +\label{dashdoublephoton} +\verb:\DashDoublePhoton(10,20)(80,20){5}{7}{1.3}{1}:\hfill \\ +The first 6 arguments are as in the \verb+Photon+ +command. +The final 2 arguments are the line separation and the size of the +dashes. +\end{minipage}\vspace{10mm} + +%--#] DashDoublePhoton : +%--#[ PhotonArc : + +\noindent +\begin{minipage}{3.83cm} +\begin{axopicture}{(90,50)(-10,0)} +\AxoGrid(0,0)(10,10)(9,5){LightGray}{0.5} +\PhotonArc(45,0)(40,20,160){5}{8} +\end{axopicture} +\end{minipage} +\begin{minipage}{11.5cm} +\label{photonarc} +\verb:\PhotonArc(45,0)(40,20,160){5}{8}:\hfill \\ +In this command we have one coordinate: the center of the circle. Then +follow the radius of the circle, the start angle and the finishing angle. +The arc will be drawn counterclockwise. The final two parameters are the +amplitude of the wiggles and the number of wiggles. +Like the other commands in this section, this command can take +optional arguments, Sec.\ \ref{sec:options}. +\end{minipage}\vspace{4mm} + +%--#] PhotonArc : +%--#[ DoublePhotonArc : + +\noindent +\begin{minipage}{3.83cm} +\begin{axopicture}{(90,50)(-10,0)} +\AxoGrid(0,0)(10,10)(9,5){LightGray}{0.5} +\DoublePhotonArc[color=Red](45,0)(40,20,160)% + {5}{8}{1.3} +\end{axopicture} +\end{minipage} +\begin{minipage}{11.5cm} +\label{doublephotonarc} +\begin{verbatim} +\DoublePhotonArc[color=Red](45,0)(40,20,160)% + {5}{8}{1.3} +\end{verbatim} +The first 7 arguments are as in the \verb+PhotonArc+ command. The extra +argument is the separation of the double line. +\end{minipage}\vspace{4mm} + +%--#] DoublePhotonArc : +%--#[ DashPhotonArc : + +\noindent +\begin{minipage}{3.83cm} +\begin{axopicture}{(90,50)(-10,0)} +\AxoGrid(0,0)(10,10)(9,5){LightGray}{0.5} +\DashPhotonArc(45,0)(40,20,160){5}{8}{1.5} +\end{axopicture} +\end{minipage} +\begin{minipage}{11.5cm} +\label{dashphotonarc} +\verb:\DashPhotonArc(45,0)(40,20,160){5}{8}{1.5}:\hfill \\ +The first 7 arguments are as in the \verb+PhotonArc+ command. The +extra argument is the size of the dash segments. +\end{minipage}\vspace{4mm} + +%--#] DashPhotonArc : +%--#[ DashDoublePhotonArc : + +\noindent +\begin{minipage}{3.83cm} +\begin{axopicture}{(90,50)(-10,0)} +\AxoGrid(0,0)(10,10)(9,5){LightGray}{0.5} +\DashDoublePhotonArc(45,0)(40,20,160){5}{8}{1.3}{1.5} +\end{axopicture} +\end{minipage} +\begin{minipage}{11.5cm} +\label{dashdoublephotonarc} +\verb:\DashDoublePhotonArc(45,0)(40,20,160){5}{8}{1.3}{1.5}:\hfill \\ +The first 7 arguments are as in the \verb+PhotonArc+ command. The +extra arguments are the separation of the lines and the size of the +dash segments. +\end{minipage}\vspace{4mm} + +%--#] DashDoublePhotonArc : +%--#[ ZigZag : + +\subsubsection{Zigzag lines} + +The basic drawing commands for drawing zigzag lines are \verb+\Zigzag+ +and \verb+\ZigzagArc+. There are also variants for dashed and double +lines. But arrows aren't possible. + +All of the commands in this section can be given optional keyword +arguments, which are defined in Sec.\ \ref{sec:options}. These can be +used to specify the type of line (dashed, double), and to specify some +of the line's parameters. +\vspace{4mm} + +\noindent +\begin{minipage}{3.83cm} +\begin{axopicture}{(90,40)(-10,0)} +\AxoGrid(0,0)(10,10)(9,4){LightGray}{0.5} +\ZigZag(10,20)(80,20){5}{7.5} +\end{axopicture} +\end{minipage} +\begin{minipage}{11.5cm} +\label{zigzag} +\verb:\ZigZag(10,20)(80,20){5}{7.5}: \hfill \\ +In this command we have two coordinates, the amplitude of the sawteeth and +the number of sawteeth. +A negative value for the amplitude will reverse the orientation of the +sawteeth. +The line will be drawn with the number of sawteeth rounded to the +nearest half integer. +\end{minipage} +\\[3mm] +Like the other commands in this section, this command can take +optional arguments, Sec.\ \ref{sec:options}, e.g.,\\[3mm] +\noindent +\begin{minipage}{3.83cm} +\begin{axopicture}{(90,40)(-10,0)} +\AxoGrid(0,0)(10,10)(9,4){LightGray}{0.5} +\ZigZag[color=Red,double,sep=1.5](10,20)(80,20){5}{7} +\end{axopicture} +\end{minipage} +\begin{minipage}{11.5cm} +\label{zigzag.opt} +\verb:\ZigZag[color=Red,double,sep=1.5](10,20)(80,20){5}{7}: +\end{minipage}\vspace{6mm} + +%--#] ZigZag : +%--#[ DoubleZigZag : + +\noindent +\begin{minipage}{3.83cm} +\begin{axopicture}{(90,40)(-10,0)} +\AxoGrid(0,0)(10,10)(9,4){LightGray}{0.5} +\DoubleZigZag(10,20)(80,20){5}{7}{1.3} +\end{axopicture} +\end{minipage} +\begin{minipage}{11.5cm} +\label{doublezigzag} +\verb:\DoubleZigZag(10,20)(80,20){5}{7}{1.3}:\hfill \\ +The first 6 arguments are as in the \verb+ZigZag+ command. The +extra argument is the line separation. +\end{minipage}\vspace{4mm} + +%--#] DoubleZigZag : +%--#[ DashZigZag : + +\noindent +\begin{minipage}{3.83cm} +\begin{axopicture}{(90,40)(-10,0)} +\AxoGrid(0,0)(10,10)(9,4){LightGray}{0.5} +\DashZigZag(10,20)(80,20){5}{7}{1} +\end{axopicture} +\end{minipage} +\begin{minipage}{11.5cm} +\label{dashzigzag} +\verb:\DashZigZag(10,20)(80,20){5}{7}{1}:\hfill \\ +The first 6 arguments are as in the \verb+ZigZag+ command. The +extra argument is the size of the dashes. +\end{minipage}\vspace{4mm} + +%--#] DashZigZag : +%--#[ DashDoubleZigZag : + +\noindent +\begin{minipage}{3.83cm} +\begin{axopicture}{(90,40)(-10,0)} +\AxoGrid(0,0)(10,10)(9,4){LightGray}{0.5} +\DashDoubleZigZag(10,20)(80,20){5}{7}{1.3}{1} +\end{axopicture} +\end{minipage} +\begin{minipage}{11.5cm} +\label{dashdoublezigzag} +\verb:\DashDoubleZigZag(10,20)(80,20){5}{7}{1.3}{1}:\hfill \\ +The first 6 arguments are as in the \verb+ZigZag+ command. +The extra arguments are the separation of the lines and the size of +the dash segments. +\end{minipage}\vspace{6mm} + +%--#] DashDoubleZigZag : +%--#[ ZigZagArc : + +\noindent +\begin{minipage}{3.83cm} +\begin{axopicture}{(90,50)(-10,0)} +\AxoGrid(0,0)(10,10)(9,5){LightGray}{0.5} +\ZigZagArc(45,0)(40,20,160){5}{8} +\end{axopicture} +\end{minipage} +\begin{minipage}{11.5cm} +\label{zigzagarc} +\verb:\ZigZagArc(45,0)(40,20,160){5}{8}:\hfill \\ +In this command we have one coordinate: the center of the circle. Then +follow the radius of the circle, the start angle and the finishing +angle. The arc will be drawn counterclockwise. The final two +arguments are the amplitude of the sawteeth and the number of +sawteeth. Like the other commands in this section, this command can +take optional arguments, Sec.\ \ref{sec:options}. +\end{minipage}\vspace{4mm} + +%--#] ZigZagArc : +%--#[ DoubleZigZagArc : + +\noindent +\begin{minipage}{3.83cm} +\begin{axopicture}{(90,50)(-10,0)} +\AxoGrid(0,0)(10,10)(9,5){LightGray}{0.5} +\DoubleZigZagArc(45,0)(40,20,160){5}{8}{1.3} +\end{axopicture} +\end{minipage} +\begin{minipage}{11.5cm} +\label{doublezigzagarc} +\verb:\DoubleZigZagArc(45,0)(40,20,160){5}{8}{1.3}:\hfill \\ +The first 7 arguments are as for the \verb+ZigZagArc+ command. The +extra argument is the separation in the double line. +\end{minipage}\vspace{4mm} + +%--#] DoubleZigZagArc : +%--#[ DashZigZagArc : + +\noindent +\begin{minipage}{3.83cm} +\begin{axopicture}{(90,50)(-10,0)} +\AxoGrid(0,0)(10,10)(9,5){LightGray}{0.5} +\DashZigZagArc(45,0)(40,20,160){5}{8}{1.5} +\end{axopicture} +\end{minipage} +\begin{minipage}{11.5cm} +\label{dashzigzagarc} +\verb:\DashZigZagArc(45,0)(40,20,160){5}{8}{1.5}:\hfill \\ +The first 7 arguments are as for the \verb+ZigZagArc+ command. The +extra argument is the size of the dash segments. +\end{minipage}\vspace{4mm} + +%--#] DashZigZagArc : +%--#[ DashDoubleZigZagArc : + +\noindent +\begin{minipage}{3.83cm} +\begin{axopicture}{(90,50)(-10,0)} +\AxoGrid(0,0)(10,10)(9,5){LightGray}{0.5} +\DashDoubleZigZagArc(45,0)(40,20,160){5}{8}{1.3}{1.5} +\end{axopicture} +\end{minipage} +\begin{minipage}{11.5cm} +\label{dashdoublezigzagarc} +\verb:\DashDoubleZigZagArc(45,0)(40,20,160){5}{8}{1.3}{1.5}:\hfill \\ +The first 7 arguments are as for the \verb+ZigZagArc+ command. The +final 2 arguments are the separation of the lines and the size of the +dash segments. +\end{minipage}\vspace{4mm} + +%--#] DashDoubleZigZagArc : +%--#[ Vertex : + +\subsubsection{Vertices, circles, ovals} +\label{sec:other.graphics} + +The commands in this section are for graphical elements other +than those that we conceived of as lines in Feynman graphs. Many of +these have standard uses as components of Feynman graphs\footnote{Of + course, none of the commands is restricted to its originally + envisaged use, or to being used to draw Feynman graphs. But + especially the line-drawing commands have been designed from the + point-of-view of being suitable for the needs of drawing particular + elements of Feynman graphs.}. The commands here are mostly shown +in association with other objects, to indicate some of their +properties. +\vspace{4mm} + +\noindent +\begin{minipage}{3.83cm} +\begin{axopicture}{(80,50)(-15,0)} +\AxoGrid(0,0)(10,10)(8,5){LightGray}{0.5} +\Line(10,10)(70,10) +\Photon(40,10)(40,40){4}{3} +\Vertex(40,10){1.5} +\end{axopicture} +\end{minipage} +\begin{minipage}{11.5cm} +\label{vertex} +\verb:\Line(10,10)(70,10): \hfill \\ +\verb:\Photon(40,10)(40,40){4}{3}: \hfill \\ +\verb:\Vertex(40,10){1.5}: \hfill \\ +\verb+\Vertex+ gives a vertex, as is often used for connecting lines +in Feynman graphs. It gives a fat dot. The arguments are coordinates +(between parentheses) for its center, and the radius of the dot. +\end{minipage}\vspace{4mm} + +%--#] Vertex : +%--#[ ECirc : + +\noindent +\begin{minipage}{3.83cm} +\begin{axopicture}{(60,60)(-25,0)} +\AxoGrid(0,0)(10,10)(6,6){LightGray}{0.5} +\Red{\Line(0,0)(60,60)} +\ECirc(30,30){20} +\end{axopicture} +\end{minipage} +\begin{minipage}{11.5cm} +\label{ecirc} +\verb:\Red{\Line(0,0)(60,60)}:\\ +\verb:\ECirc(30,30){20}:\\ +\verb+\ECirc+ draws a circle with its center at the specified +coordinate (first two arguments) and the specified radius (third +argument). The interior is transparent, so that it does not erase +previously drawn material. +If you need a filled circle, use the \verb+\Vertex+ command (to which +we have defined a synonym \verb+\FCirc+ to match similar commands for +other shapes). +\end{minipage}\vspace{4mm} + +%--#] ECirc : +%--#[ BCirc : + +\noindent +\begin{minipage}{3.83cm} +\begin{axopicture}{(60,60)(-25,0)} +\AxoGrid(0,0)(10,10)(6,6){LightGray}{0.5} +\Red{\Line(0,0)(60,60)} +\BCirc(30,30){20} +\Blue{\Line(60,0)(0,60)} +\end{axopicture} +\end{minipage} +\begin{minipage}{11.5cm} +\label{bcirc} +\verb:\Red{\Line(0,0)(60,60)}:\\ +\verb:\BCirc(30,30){20}:\\ +\verb:\Blue{\Line(60,0)(0,60)}:\\ +\verb+\BCirc+ +draws a circle with the center at the specified coordinate (first two +arguments) and the specified radius (third argument). The interior is +white and opaque, so that it erases previously written objects, but not +subsequently drawn objects. +\end{minipage}\vspace{4mm} + +%--#] BCirc : +%--#[ GCirc : + +\noindent +\begin{minipage}{3.83cm} +\begin{axopicture}{(60,60)(-25,0)} +\AxoGrid(0,0)(10,10)(6,6){LightGray}{0.5} +\Red{\Line(0,0)(60,60)} +\GCirc(30,30){20}{0.82} +\Blue{\Line(60,0)(0,60)} +\end{axopicture} +\end{minipage} +\begin{minipage}{11.5cm} +\label{gcirc} +\verb:\Red{\Line(0,0)(60,60)}:\\ +\verb:\GCirc(30,30){20}{0.82}:\\ +\verb:\Blue{\Line(60,0)(0,60)}:\\ +\verb+\GCirc+ draws a circle with the center at the specified +coordinate (first two arguments) and the specified radius (third +argument). Previously written contents are overwritten and made gray +according to the grayscale specified by the fourth argument (0=black, +1=white). +\end{minipage}\vspace{4mm} + +%--#] GCirc : +%--#[ CCirc : + +\noindent +\begin{minipage}{3.83cm} +\begin{axopicture}{(60,60)(-25,0)} +\AxoGrid(0,0)(10,10)(6,6){LightGray}{0.5} +\Red{\Line(0,0)(60,60)} +\CCirc(30,30){20}{Red}{Yellow} +\Blue{\Line(60,0)(0,60)} +\end{axopicture} +\end{minipage} +\begin{minipage}{11.5cm} +\label{ccirc} +\verb:\Red{\Line(0,0)(60,60)}:\\ +\verb:\CCirc(30,30){20}{Red}{Yellow}:\\ +\verb:\Blue{\Line(60,0)(0,60)}:\\ +\verb+\CCirc+ draws a colored circle with the center at the specified +coordinate (first two arguments) and the specified radius (third +argument). The fourth argument is the name of the color for the circle +itself. Its interior is overwritten and colored with the color +specified by name in the fifth argument. +\end{minipage}\vspace{4mm} + +%--#] CCirc : +%--#[ Oval : + +\noindent +\begin{minipage}{3.83cm} +\begin{axopicture}{(80,110)(-15,0)} +\AxoGrid(0,0)(10,10)(8,11){LightGray}{0.5} +\Oval(40,80)(20,30)(0) +\Oval(40,30)(20,30)(30) +\end{axopicture} +\end{minipage} +\begin{minipage}{11.5cm} +\label{oval} +\verb:\Oval(40,80)(20,30)(0):\\ +\verb:\Oval(40,30)(20,30)(30):\\ +\verb:\Oval: draws an oval. The first pair of values is the center of +the oval. The next pair forms the half-height and the half-width. The +last argument is a (counterclockwise) rotation angle. The interior is +transparent, so that it does not erase previously drawn material. +\end{minipage}\vspace{4mm} + +%--#] Oval : +%--#[ FOval : + +\noindent +\begin{minipage}{3.83cm} +\begin{axopicture}{(80,60)(-15,0)} +\AxoGrid(0,0)(10,10)(8,6){LightGray}{0.5} +\SetColor{Yellow} +\FOval(40,30)(20,30)(30) +\end{axopicture} +\end{minipage} +\begin{minipage}{11.5cm} +\label{foval} +\verb:\SetColor{Yellow}:\\ +\verb:\FOval(40,80)(20,30)(30):\\ +\verb:\FOval: draws an oval filled with the current color overwriting +previously written material. Its arguments are the same as for the +\verb:\Oval: command. +\end{minipage}\vspace{4mm} + +%--#] FOval : +%--#[ GOval : + +\noindent +\begin{minipage}{3.83cm} +\begin{axopicture}{(80,60)(-15,0)} +\AxoGrid(0,0)(10,10)(8,6){LightGray}{0.5} +\Red{\Line(0,0)(80,60)} +\GOval(40,30)(20,30)(0){0.6} +\Blue{\Line(80,0)(0,60)} +\end{axopicture} +\end{minipage} +\begin{minipage}{11.5cm} +\label{goval} +\verb:\Red{\Line(0,0)(80,60)}:\\ +\verb:\GOval(40,30)(20,30)(0){0.6}: \\ +\verb:\Blue{\Line(80,0)(0,60)}:\\ +\verb:\GOval: draws an oval with a gray interior. +The first 5 arguments are the same as for the \verb:\Oval: command. +The last argument indicates the +grayscale with which the oval will be filled, overwriting previously +written contents (0=black, 1=white). +\end{minipage}\vspace{4mm} + +%--#] GOval : +%--#[ COval : + +\noindent +\begin{minipage}{3.83cm} +\begin{axopicture}{(80,60)(-15,0)} +\AxoGrid(0,0)(10,10)(8,6){LightGray}{0.5} +\SetWidth{1} +\Green{\Line(0,0)(80,60)} +\COval(40,30)(20,30)(20){Orange}{Blue} +\Yellow{\Line(80,0)(0,60)} +\end{axopicture} +\end{minipage} +\begin{minipage}{11.5cm} +\label{coval} +\verb:\Green{\Line(0,0)(80,60)}:\\ +\verb:\COval(40,30)(20,30)(20){Orange}{Blue}:\\ +\verb:\Yellow{\Line(80,0)(0,60)}:\\ +\verb:\COval: draws a colored oval. +The first 5 arguments are the same as for the \verb:\Oval: command. +The last two arguments are the names of two colors. +The first is the color of the line that forms the oval and the second is +the color of the inside. +\end{minipage}\vspace{4mm} + +%--#] COval : +%--#[ EBox : + +Commands for drawing boxes are in two series. For the first set, the +box's position is specified by the coordinates of its bottom left +corner and top right corner:\\[4mm] +\noindent +\begin{minipage}{3.83cm} +\begin{axopicture}{(60,50)(-25,0)} +\AxoGrid(0,0)(10,10)(6,5){LightGray}{0.5} +\EBox(10,10)(50,40) +\end{axopicture} +\end{minipage} +\begin{minipage}{11.5cm} +\label{ebox} +\verb:\EBox(10,10)(50,40): \hfill \\ +Draws a box. The points specified are the bottom left corner and the top +right corner. +The interior is transparent, so that it does not erase previously +drawn material. +\end{minipage}\vspace{4mm} + +%--#] EBox : +%--#[ FBox : + +\noindent +\begin{minipage}{3.83cm} +\begin{axopicture}{(60,50)(-25,0)} +\AxoGrid(0,0)(10,10)(6,5){LightGray}{0.5} +\FBox(10,10)(50,40) +\end{axopicture} +\end{minipage} +\begin{minipage}{11.5cm} +\label{fbox} +\verb:\FBox(10,10)(50,40): \hfill \\ +Draws a box filled with the current color overwriting +previously written material. Its arguments are the same as for the +\verb:\EBox: command. +\end{minipage}\vspace{4mm} + +%--#] FBox : +%--#[ BBox : + +\noindent +\begin{minipage}{3.83cm} +\begin{axopicture}{(60,50)(-25,0)} +\AxoGrid(0,0)(10,10)(6,5){LightGray}{0.5} +\BBox(10,10)(50,40) +\end{axopicture} +\end{minipage} +\begin{minipage}{11.5cm} +\label{bbox} +\verb:\BBox(10,10)(50,40): \hfill \\ +Draws a blanked-out box. The points specified are the bottom left corner +and the top right corner. +\end{minipage}\vspace{4mm} + +%--#] BBox : +%--#[ GBox : + +\noindent +\begin{minipage}{3.83cm} +\begin{axopicture}{(60,50)(-25,0)} +\AxoGrid(0,0)(10,10)(6,5){LightGray}{0.5} +\GBox(10,10)(50,40){0.9} +\end{axopicture} +\end{minipage} +\begin{minipage}{11.5cm} +\label{gbox} +\verb:\GBox(10,10)(50,40){0.9}: \hfill \\ +Draws a box filled with a grayscale given by the fifth argument (black=0, +white=1). The points specified are the bottom left corner and the top +right corner. +\end{minipage}\vspace{4mm} + +%--#] GBox : +%--#[ CBox : + +\noindent +\begin{minipage}{3.83cm} +\begin{axopicture}{(60,50)(-25,0)} +\AxoGrid(0,0)(10,10)(6,5){LightGray}{0.5} +\SetWidth{1.5} +\CBox(10,10)(50,40){Green}{LightRed} +\end{axopicture} +\end{minipage} +\begin{minipage}{11.5cm} +\label{cbox} +\verb:\CBox(10,10)(50,40){Green}{LightRed}: \hfill \\ +Draws a box in the color specified by name in the fifth argument. The +contents are filled with the color specified by name in the sixth +argument. The points specified are the bottom left corner and the top +right corner. +\end{minipage}\vspace{4mm} + +%--#] CBox : +%--#[ EBoxc : + +For the other series of box-drawing commands, the box's position is +specified by its center, and its width and height. The command names +end with a ``\texttt{c}'', for ``center'':\\[3mm] +\noindent +\begin{minipage}{3.83cm} +\begin{axopicture}{(60,50)(-25,0)} +\AxoGrid(0,0)(10,10)(6,5){LightGray}{0.5} +\EBoxc(30,25)(40,30) +\end{axopicture} +\end{minipage} +\begin{minipage}{11.5cm} +\label{eboxc} +\label{boxc} +\verb:\EBoxc(30,25)(40,30): \hfill \\ +Draws a box. The first two numbers give the center of the box. The next two +numbers are the width and the height of the box. Instead of \verb:\EBoxc: +one may also use \verb:\Boxc:. + +There is also the similar command \verb:\FBoxc: that draws a filled box. +\end{minipage}\vspace{4mm} + +%--#] EBoxc : +%--#[ BBoxc : + +\noindent +\begin{minipage}{3.83cm} +\begin{axopicture}{(60,50)(-25,0)} +\AxoGrid(0,0)(10,10)(6,5){LightGray}{0.5} +\BBoxc(30,25)(40,30) +\end{axopicture} +\end{minipage} +\begin{minipage}{11.5cm} +\label{bboxc} +\verb:\BBoxc(30,25)(40,30): \hfill \\ +Draws a box of which the contents are blanked out. The arguments are +the same as for the \verb+\EBoxc+ command. +\end{minipage}\vspace{4mm} + +%--#] BBoxc : +%--#[ GBoxc : + +\noindent +\begin{minipage}{3.83cm} +\begin{axopicture}{(60,50)(-25,0)} +\AxoGrid(0,0)(10,10)(6,5){LightGray}{0.5} +\GBoxc(30,25)(40,30){0.9} +\end{axopicture} +\end{minipage} +\begin{minipage}{11.5cm} +\label{gboxc} +\verb:\GBoxc(30,25)(40,30){0.9}: \hfill \\ +Draws a box filled with a grayscale given by the fifth argument (black=0, +white=1). +The first 4 arguments are the same as for the \verb+\EBoxc+ command. +\end{minipage}\vspace{4mm} + +%--#] GBoxc : +%--#[ CBoxc : + +\noindent +\begin{minipage}{3.83cm} +\begin{axopicture}{(60,50)(-25,0)} +\AxoGrid(0,0)(10,10)(6,5){LightGray}{0.5} +\SetWidth{1.5} +\CBoxc(30,25)(40,30){Brown}{LightBlue} +\end{axopicture} +\end{minipage} +\begin{minipage}{11.5cm} +\label{cboxc} +\verb:\CBoxc(30,25)(40,30){Brown}{LightBlue}: \hfill \\ +Draws a box in the color specified by name in the fifth argument. The +contents are filled with the color specified by name in the sixth +argument. +The first 4 arguments are the same as for the \verb+\EBoxc+ command. +\end{minipage}\vspace{4mm} + +%--#] BBoxc : +%--#] CBoxc : +%--#[ RotatedBox : + +\noindent +\begin{minipage}{3.83cm} +\begin{axopicture}{(60,50)(-25,0)} +\AxoGrid(0,0)(10,10)(6,5){LightGray}{0.5} +\RotatedBox(30,25)(40,30){30}{Red} +\end{axopicture} +\end{minipage} +\begin{minipage}{11.5cm} +\label{rotatedbox} +\verb:\RotatedBox(30,25)(40,30){30}{Red}: \hfill \\ +Draws a rotated box. The first two numbers give the center of the +box. The next two numbers are the width and the height of the box. The +fifth argument is the counterclockwise rotation angle and the sixth +argument is the color of the box. The interior of the box is +transparent. +\end{minipage}\vspace{4mm} + +%--#] RotatedBox : +%--#[ FilledRotatedBox : + +\noindent +\begin{minipage}{3.83cm} +\begin{axopicture}{(60,50)(-25,0)} +\AxoGrid(0,0)(10,10)(6,5){LightGray}{0.5} +\FilledRotatedBox(30,25)(40,30){30}{Blue} +\end{axopicture} +\end{minipage} +\begin{minipage}{11.5cm} +\label{filledrotatedbox} +\verb:\FilledRotatedBox(30,25)(40,30){30}{Blue}: \hfill \\ +Draws a rotated box. +The first 4 arguments are the same as for the \verb+\RotatedBox+ command. +The +fifth argument is the counterclockwise rotation angle and the sixth +argument is the color of the inside of the box. If a differently +colored outline is needed, it should be written with the +\verb+RotatedBox+ command. +\end{minipage}\vspace{4mm} + +%--#] FilledRotatedBox : +%--#[ ETri : + +\noindent +\begin{minipage}{3.83cm} +\begin{axopicture}{(60,50)(-25,0)} +\AxoGrid(0,0)(10,10)(6,5){LightGray}{0.5} +\ETri(10,20)(50,10)(40,40) +\end{axopicture} +\end{minipage} +\begin{minipage}{11.5cm} +\label{etri} +\verb:\ETri(10,20)(50,10)(40,40): \hfill \\ +Draws a triangle. The three points specified are the corners of the +triangle. +The interior is transparent. + +There is also the similar command \verb:\FTri: that draws a filled triangle. +\end{minipage}\vspace{4mm} + +%--#] ETri : +%--#[ BTri : + +\noindent +\begin{minipage}{3.83cm} +\begin{axopicture}{(60,50)(-25,0)} +\AxoGrid(0,0)(10,10)(6,5){LightGray}{0.5} +\BTri(10,20)(50,10)(40,40) +\end{axopicture} +\end{minipage} +\begin{minipage}{11.5cm} +\label{btri} +\verb:\BTri(10,20)(50,10)(40,40): \hfill \\ +Draws a blanked-out triangle. The three points specified are the corners of +the triangle. +\end{minipage}\vspace{4mm} + +%--#] BTri : +%--#[ GTri : + +\noindent +\begin{minipage}{3.83cm} +\begin{axopicture}{(60,50)(-25,0)} +\AxoGrid(0,0)(10,10)(6,5){LightGray}{0.5} +\GTri(10,20)(50,10)(40,40){0.9} +\end{axopicture} +\end{minipage} +\begin{minipage}{11.5cm} +\label{gtri} +\verb:\GTri(10,20)(50,10)(40,40){0.9}: \hfill \\ +Draws a triangle of which the content are filled with the grayscale +specified by the seventh argument (black=0, white=1). The three points +specified are the corners of the triangle. +\end{minipage}\vspace{4mm} + +%--#] GTri : +%--#[ CTri : + +\noindent +\begin{minipage}{3.83cm} +\begin{axopicture}{(60,50)(-25,0)} +\AxoGrid(0,0)(10,10)(6,5){LightGray}{0.5} +\SetWidth{1} +\CTri(10,20)(50,10)(40,40){Red}{Yellow} +\end{axopicture} +\end{minipage} +\begin{minipage}{11.5cm} +\label{ctri} +\verb:\CTri(10,20)(50,10)(40,40){Red}{Yellow}: \hfill \\ +Draws a triangle in the color named in the seventh argument. The +contents are filled with the color named in the eightth argument. The +three points specified are the corners of the triangle. +\end{minipage}\vspace{4mm} + +%--#] CTri : +%--#[ Polygon : + +\noindent +\begin{minipage}{3.83cm} +\begin{axopicture}{(60,50)(-25,0)} +\AxoGrid(0,0)(10,10)(6,5){LightGray}{0.5} +\Polygon{(10,20)(20,10)(40,20)(50,10)(45,40)(15,30)}{Red} +\end{axopicture} +\end{minipage} +\begin{minipage}{11.5cm} +\label{polygon} +\verb:\Polygon{(10,20)(20,10)(40,20)(50,10): \hfill \\ + \verb: (45,40)(15,30)}{Red}: \hfill \\ +Draws a polygon. The first argument is a sequence of two dimensional +points which form the corners of the polygon. The second argument is +the name of the color of the polygon. The interior is transparent. +\end{minipage}\vspace{4mm} + +%--#] Polygon : +%--#[ FilledPolygon : + +\noindent +\begin{minipage}{3.83cm} +\begin{axopicture}{(60,50)(-25,0)} +\AxoGrid(0,0)(10,10)(6,5){LightGray}{0.5} +\FilledPolygon{(10,20)(20,10)(40,20)(50,10)(45,40)(15,30)}{Apricot} +\end{axopicture} +\end{minipage} +\begin{minipage}{11.5cm} +\label{filledpolygon} +\verb:\FilledPolygon{(10,20)(20,10)(40,20)(50,10): \hfill \\ + \verb: (45,40)(15,30)}{Apricot}: \hfill \\ +Draws a polygon. The first argument is a sequence of two dimensional +points which form the corners of the polygon. The second argument is +the name of the color of the interior. +\end{minipage}\vspace{4mm} + +%--#] FilledPolygon : +%--#[ LinAxis : + +\noindent +\begin{minipage}{3.83cm} +\begin{axopicture}{(100,50)(-5,0)} +\AxoGrid(0,0)(10,10)(10,5){LightGray}{0.5} +\LinAxis(10,30)(90,30)(4,5,5,0,1) +\LinAxis(10,10)(90,10)(4,5,5,2,1) +\end{axopicture} +\end{minipage} +\begin{minipage}{11.5cm} +\label{linaxis} +\verb:\LinAxis(10,30)(90,30)(4,5,5,0,1):\\ +\verb:\LinAxis(10,10)(100,10)(4,5,5,2,1): \\ +\verb+\LinAxis+($x_1$,$y_1$)($x_2$,$y_2$)($N_D$,$d$,hashsize,offset,width) + draws a line to be used as an axis in a graph. Along the axis + are hash marks. Going from the first coordinate to the second, the + hash marks are on the left side if `hashsize', which is the size of the + hash marks, is positive and on the right side if it is negative. + $N_D$ is the number of `decades', indicated by fat hash marks, and + $d$ is the (integer) number of subdivisions inside each decade. The offset + parameter tells to which subdivision the first coordinate + corresponds. When it is zero, this coordinate corresponds to a fat + mark of a decade. Because axes have their own width, this is + indicated with the last parameter. +%Draws a line with subdivisions that can be used as the axis on a histogram +%or other figure. The first four arguments are the endpoints of the axis. +%Then we have the number of decades, the number of divisions inside each +%decade, the size of the hash marks, the offset in divisions at which we +%start and the linewidth. The hashmarks will be on the left side when going +%from point 1 to point 2. +\end{minipage}\vspace{4mm} + +%--#] LinAxis : +%--#[ LogAxis : + +\noindent +\begin{minipage}{3.83cm} +\begin{axopicture}{(100,40)(-5,0)} +\AxoGrid(0,0)(10,10)(10,4){LightGray}{0.5} +\LogAxis(0,30)(100,30)(4,3,0,1) +\LogAxis(0,10)(100,10)(4,3,3,1) +\end{axopicture} +\end{minipage} +\begin{minipage}{11.5cm} +\label{logaxis} +\verb:\LogAxis(0,30)(100,30)(4,3,0,1): \hfill \\ +\verb:\LogAxis(0,10)(100,10)(4,3,3,1): \hfill \\ +\verb+\LogAxis+($x_1$,$y_1$)($x_2$,$y_2$)($N_L$,hashsize + ,offset,width) \hfill \\ + This draws a line to be used as a logarithmic axis in a graph. Along + the axis are hash marks. Going from the first coordinate to the second, + the hash marks are on the left side if `hashsize', which is the size of + the hash marks, is positive and on the right side if it is negative. + $N_L$ is the number of orders of magnitude, indicated by fat hash + marks. The offset parameter tells to which integer subdivision the + first coordinate corresponds. When it is zero, this coordinate + corresponds to a fat mark, which is identical to when the value would + have been 1. Because axes have their own width, this is indicated with + the last parameter. +%Draws a line with subdivisions that can be used as the axis on a histogram +%or other figure. The first four arguments are the endpoints of the axis. +%Then we have the number of orders of magnitude, +%the size of the hash marks, the offset inside a logarithm at which we +%start and the linewidth. The hashmarks will be on the left side when going +%from point 1 to point 2. +\end{minipage}\vspace{4mm} + +%--#] LogAxis : +%>>#] The Commands : +%>>#[ Text : + +\subsection{Text} +\label{sec:text} + +%--#[ Implementation : + +Axodraw2 provides several commands for inserting text into diagrams. +Some are for plain text, with a chosen placement and angle. Some +allow placement of text inside boxes. There are two sets of commands. +Some we call \TeX-text commands; these use the standard \LaTeX{} fonts +as used in the rest of the document. The others we call +postscript-text commands; these use a user-specified standard +postscript font or, if the user wishes, the usual document font, at a +user-chosen size. + +[\emph{Side issue:} In version 1 of axodraw, the difference between +the classes of text command was caused by a serious implementation +difficulty. With the then-available \LaTeX{} technology, certain +graphic effects, could not be achieved within \LaTeX, at least not +easily. So direct programming in postscript was resorted to, with the +result that normal \LaTeX{} commands, including mathematics, were not +available in the postscript-text commands. With the greatly improved +methods now available, this has all changed, and the restrictions have +gone. But since the commands and their basic behavior is already +defined, we have retained the distinction between \TeX{}-text commands +and postscript-text commands.] + +In the original version of Axodraw the commands for two lines inside a +box were \verb:B2Text:, \verb:G2Text: and \verb:C2Text:. This causes +some problems explained in Sec.\ \ref{sec:changes.wrt.1}. If you need to +retain compatibility with v.\ 1 on this issue, e.g., with old files or +old diagrams or for personal preference, you can use the +\texttt{v1compatible} option when loading axodraw2 --- see Sec.\ +\ref{sec:invoke}. + +\vspace{4mm} + +%--#] Implementation : +%--#[ Text : + +\subsubsection{\TeX-type text} + +Illustrated by examples, the commands to insert text are as follows: + +\medskip + +\noindent +\begin{minipage}{3.83cm} +\begin{axopicture}{(90,90)(-10,0)} +\AxoGrid(0,0)(10,10)(9,9){LightGray}{0.5} +\Text(10,10)[l]{left} +\Text(45,45){centered} +\Text(80,80)[rt]{right-top} +\Text(20,60)(45){$e^{i\pi/4}$} +\SetColor{Red} +\Vertex(10,10){1.5} +\Vertex(45,45){1.5} +\Vertex(80,80){1.5} +\end{axopicture} +\end{minipage} +\begin{minipage}{11.5cm} +\label{text} +\verb:\Text(10,10)[l]{left}: \hfill \\ +\verb:\Text(45,45){centered}: \hfill \\ +\verb:\Text(80,80)[rt]{right-top}: \hfill \\ +\verb:\Text(20,60)(45){$e^{i\pi/4}$}: \hfill \\ +\verb:\SetColor{Red}: \hfill \\ +\verb:\Vertex(10,10){1.5}: \hfill \\ +\verb:\Vertex(45,45){1.5}: \hfill \\ +\verb:\Vertex(80,80){1.5}: \hfill \\ +\verb+\Text+ writes text in the current \LaTeX{} font. The most +general form is \verb+\Text(x,y)(theta)[pos]{text}+; but either or +both of the theta and pos arguments (and their delimiters) can be omitted. +It puts the text +at focal point $(x,y)$, with a rotation by anticlockwise angle theta. +The default angle is zero, and the default position is to +center the text horizontally and vertically at the focal point. The +position letters are any relevant combination of `l', `r', `t', and +`b', as in the various +\TeX/\LaTeX{} box commands to indicate left, right, top or bottom +adjustment with respect to the focal point. No indication means +centered. +\end{minipage}\vspace{4mm} + +%--#] Text : +%--#[ rText : + +\noindent +\begin{minipage}{3.83cm} +\begin{axopicture}{(90,90)(-10,0)} +\AxoGrid(0,0)(10,10)(9,9){LightGray}{0.5} +\rText(10,10)[l][l]{left-left} +\rText(45,45)[][u]{upside} +\rText(80,10)[r][r]{right-right} +\rText(20,60)[][r]{$e^{i\pi}$} +\SetColor{Red} +\Vertex(10,10){1.5} +\Vertex(45,45){1.5} +\Vertex(80,10){1.5} +\end{axopicture} +\end{minipage} +\begin{minipage}{11.5cm} +\label{rtext} +\verb:\rText(10,10)[l][l]{left-left}: \hfill \\ +\verb:\rText(45,45)[][u]{upside}: \hfill \\ +\verb:\rText(80,10)[r][r]{right-right}: \hfill \\ +\verb:\rText(20,60)[][r]{$e^{i\pi}$}: \hfill \\ +\verb:\SetColor{Red}: \hfill \\ +\verb:\Vertex(10,10){1.5}: \hfill \\ +\verb:\Vertex(45,45){1.5}: \hfill \\ +\verb:\Vertex(80,10){1.5}: \hfill \\ +The \verb:\rText: command gives a subset of the functionality of the +\verb+\Text+ command. It is used for backward compatibility with +Axodraw v.\ 1. The general form of the command is +\verb:\rText(x,y)[mode][rotation]{text}:. +Unlike the case with the \verb:\Text: command and typical standard +\LaTeX{} commands, if the option letters are omitted, the square +brackets must be retained. +The coordinates $(x,y)$ are +the focal point of the text. The third argument is \verb+l+, +\verb+r+, or empty to indicate the justification of the text. The +fourth argument is \verb+l+, \verb+r+, \verb+u+, or empty to indicate +respectively whether the text is rotated left (anticlockwise) by 90 +degrees, is rotated right (clockwise) by 90 degrees, is upside-down, +or is not rotated. The fifth argument is the text. +This command is retained only for backward compatibility; +for new diagrams it is probably better to use the the \verb:\Text:. +\end{minipage}\vspace{4mm} + +%--#] rText : +%--#[ SetPFont : + +\subsubsection{Postscript-type text} +\label{sec:PSText} + +The remaining text-drawing commands can use postscript fonts with an +adjustable size. + +To set the font for later text-drawing commands in this class, the +\verb:\SetPFont: command sets the `Postscript' +font, e.g., +\begin{verbatim} + \SetPFont{Helvetica}{20} +\end{verbatim} +(This font is initialized by axodraw2 to Times-Roman at 10pt.) +The font set in this way is used in the \verb:PText:, \verb:BText:, +\verb:GText:, \verb:CText:, \verb:BTwoText:, \verb:GTwoText: and +\verb:CTwoText: commands. The fonts that can be used are the 35 fonts +that are made available by Adobe and that are normally available in +all postscript interpreters, including printers. The fonts, together +with the names used to specify them in the normal font-setting +commands of \TeX{} and \LaTeX{}, are shown in Table \ref{tab:Pfont}. + +\begin{table} +\begin{tabular}{|l|l|l|l|} +\hline +Font name & \LaTeX{} & Font name & \LaTeX{} \\ +\hline +AvantGarde-Book & pagk & Helvetica-Narrow & phvrrn\\ +AvantGarde-BookOblique & pagko & Helvetica-NarrowOblique & phvron\\ +AvantGarde-Demi & pagd & NewCenturySchlbk-Bold & pncb \\ +AvantGarde-DemiOblique & pagdo & NewCenturySchlbk-BoldItalic & pncbi \\ +Bookman-Demi & pbkd & NewCenturySchlbk-Italic & pncri \\ +Bookman-DemiItalic & pbkdi & NewCenturySchlbk-Roman & pncr \\ +Bookman-Light & pbkl & Palatino-Bold & pplb \\ +Bookman-LightItalic & pbkli & Palatino-BoldItalic & pplbi \\ +Courier-Bold & pcrb & Palatino-Italic & pplri \\ +Courier-BoldOblique & pcrbo & Palatino-Roman & pplr \\ +Courier & pcrr & Symbol & psyr \\ +Courier-Oblique & pcrro & Times-Bold & ptmb \\ +Helvetica-Bold & phvb & Times-BoldItalic & ptmbi \\ +Helvetica-BoldOblique & phvbo & Times-Italic & ptmri \\ +Helvetica-NarrowBold & phvbrn& Times-Roman & ptmr \\ +Helvetica-NarrowBoldOblique & phvbon& ZapfChancery-MediumItalic & pzcmi \\ +Helvetica & phvr & ZapfDingbats & pzdr \\ +Helvetica-Oblique & phvro & & \\ +\hline +\end{tabular} +\caption{Available postscript fonts and their corresponding names in + \LaTeX.} +\label{tab:Pfont} +\end{table} +If you prefer to use the normal document font (which would normally be +Computer Modern in the common document classes), you simply leave the +fontname empty, e.g,. +\begin{verbatim} + \SetPFont{}{20} +\end{verbatim} +As for the second, fontsize argument, leaving it empty uses the size +that \LaTeX{} is using at the moment the text-drawing command starts, +e.g., +\begin{verbatim} + \SetPFont{Helvetica-Bold}{} +\end{verbatim} +\vspace{3mm} + +%--#] SetPFont : +%--#[ PText : + +\noindent +\begin{minipage}{3.83cm} +\begin{axopicture}{(90,90)(-10,0)} +\AxoGrid(0,0)(10,10)(9,9){LightGray}{0.5} +\SetPFont{Helvetica}{13} +\PText(10,10)(0)[l]{left} +\PText(45,45)(30)[]{centered} +\PText(80,80)(20)[rt]{right-top} +%\PText(20,60)(140)[]{$e^{i\pi}$} +\SetColor{Red} +\Vertex(10,10){1.5} +\Vertex(45,45){1.5} +\Vertex(80,80){1.5} +\end{axopicture} +\end{minipage} +\begin{minipage}{11.5cm} +\label{ptext} +\verb:\SetPFont{Helvetica}{13}: \hfill \\ +\verb:\PText(10,10)(0)[l]{left}: \hfill \\ +\verb:\PText(45,45)(30)[]{centered}: \hfill \\ +\verb:\PText(80,80)(20)[rt]{right-top}: \hfill \\ +%\verb:\PText(20,60)(90)[]{$e^{i\pi}$}: \hfill \\ +\verb:\SetColor{Red}: \hfill \\ +\verb:\Vertex(10,10){1.5}: \hfill \\ +\verb:\Vertex(45,45){1.5}: \hfill \\ +\verb:\Vertex(80,80){1.5}: \hfill \\ +The \verb:\PText: command writes %text +in Axodraw's current Postscript font. +The first two arguments give the focal point, the third argument is a +rotation angle and the fourth argument is as in the various \TeX/\LaTeX{} +box commands to indicate left, right, top or bottom adjustment with respect +to the focal point. No indication means centered. + +Note that use of normal \LaTeX{} font setting commands or of math-mode +will not normally have the desired effect. +\end{minipage}\vspace{4mm} + +%--#] PText : +%--#[ BText : + +\noindent +\begin{minipage}{4.53cm} +\begin{axopicture}{(110,110)(-10,0)} +\AxoGrid(0,0)(10,10)(10,9){LightGray}{0.5} +\ArrowLine(30,65)(60,25) +\SetPFont{Bookman-Demi}{14} +\BText(30,65){Who?} +\SetPFont{AvantGarde-Book}{16} +\BText(60,25){Me?} +\end{axopicture} +\end{minipage} +\begin{minipage}{10.8cm} +\label{btext} +\verb:\ArrowLine(30,65)(60,25): \hfill \\ +\verb:\SetPFont{Bookman-Demi}{14}: \hfill \\ +\verb:\BText(30,65){Who?}: \hfill \\ +\verb:\SetPFont{AvantGarde-Book}{16}: \hfill \\ +\verb:\BText(60,25){Me?}: \hfill \\ +The \verb:\BText: command writes a centered box with text in it. It uses +Axodraw's current Postscript font. +\end{minipage}\vspace{4mm} + +%--#] BText : +%--#[ GText : + +\noindent +\begin{minipage}{4.53cm} +\begin{axopicture}{(110,110)(-10,0)} +\AxoGrid(0,0)(10,10)(10,9){LightGray}{0.5} +\ArrowLine(30,65)(60,25) +\SetPFont{Bookman-Demi}{12} +\GText(30,65){0.9}{Why?} +\SetPFont{Courier-Bold}{5} +\GText(60,25){0.75}{We wanted it that way!} +\end{axopicture} +\end{minipage} +\begin{minipage}{10.8cm} +\label{gtext} +\verb:\ArrowLine(30,65)(60,25): \hfill \\ +\verb:\SetPFont{Bookman-Demi}{12}: \hfill \\ +\verb:\GText(30,65){0.9}{Why?}: \hfill \\ +\verb:\SetPFont{Courier-Bold}{5}: \hfill \\ +\verb:\GText(60,25){0.75}{We wanted it that way!}: \hfill \\ +The \verb:\GText: command writes a centered box with text in it. It uses +Axodraw's current Postscript font. The third argument is the grayscale +with which +the box will be filled. 0 is black and 1 is white. +\end{minipage}\vspace{4mm} + +%--#] GText : +%--#[ CText : + +\noindent +\begin{minipage}{4.53cm} +\begin{axopicture}{(110,110)(-10,0)} +\AxoGrid(0,0)(10,10)(9,9){LightGray}{0.5} +\ArrowLine(30,65)(60,25) +\SetPFont{Times-Bold}{15} +\CText(30,65){LightYellow}{LightBlue}{Who?} +\SetPFont{Courier-Bold}{14} +\CText(60,25){Red}{Yellow}{You!} +\end{axopicture} +\end{minipage} +\begin{minipage}{10.8cm} +\label{ctext} +\verb:\ArrowLine(30,65)(60,25): \hfill \\ +\verb:\SetPFont{Times-Bold}{15}: \hfill \\ +\verb:\CText(30,65){LightYellow}{LightBlue}{Who?}: \hfill \\ +\verb:\SetPFont{Courier-Bold}{14}: \hfill \\ +\verb:\CText(60,25){Red}{Yellow}{You!}: \hfill \\ +The \verb:\CText: command writes a centered box with text in it. It uses +Axodraw's current Postscript font. The third argument is the color of +the box and +the text. The fourth argument is the color with which the box will be +filled. +\end{minipage}\vspace{4mm} + +%--#] CText : +%--#[ BTwoText : +\noindent +\begin{minipage}{4.53cm} +\begin{axopicture}{(110,110)(-10,0)} +\AxoGrid(0,0)(10,10)(9,9){LightGray}{0.5} +\ArrowLine(30,65)(60,25) +\SetPFont{Bookman-Demi}{14} +\BTwoText(30,65){Why}{Me?} +\SetPFont{AvantGarde-Book}{16} +\BTwoText(60,25){You}{did it} +\end{axopicture} +\end{minipage} +\begin{minipage}{10.8cm} +\label{btwotext} +\verb:\ArrowLine(30,65)(60,25): \hfill \\ +\verb:\SetPFont{Bookman-Demi}{14}: \hfill \\ +\verb:\BTwoText(30,65){Why}{Me?}: \hfill \\ +\verb:\SetPFont{AvantGarde-Book}{16}: \hfill \\ +\verb:\BTwoText(60,25){You}{did it}: \hfill \\ +The \verb:\BTwoText: command writes a centered box with two lines of text in +it. It uses Axodraw's current Postscript font. +\end{minipage}\vspace{4mm} + +%--#] BTwoText : +%--#[ GTwoText : + +\noindent +\begin{minipage}{4.53cm} +\begin{axopicture}{(110,110)(-10,0)} +\AxoGrid(0,0)(10,10)(10,9){LightGray}{0.5} +\ArrowLine(30,65)(60,25) +\SetPFont{Bookman-Demi}{12} +\GTwoText(30,65){0.9}{Prove}{it!} +\SetPFont{Courier-Bold}{11} +\GTwoText(60,25){0.75}{Sherlock}{says so} +\end{axopicture} +\end{minipage} +\begin{minipage}{10.8cm} +\label{gtwotext} +\verb:\ArrowLine(30,65)(60,25): \hfill \\ +\verb:\SetPFont{Bookman-Demi}{12}: \hfill \\ +\verb:\GTwoText(30,65){0.9}{Prove}{it!}: \hfill \\ +\verb:\SetPFont{Courier-Bold}{11}: \hfill \\ +\verb:\GTwoText(60,25){0.75}{Sherlock}{says so}: \hfill \\ +The \verb:\GTwoText: command writes a centered box with two lines of text in +it. It uses Axodraw's current Postscript font. The third argument is the +grayscale with which the box will be filled. 0 is black and 1 is white. +\end{minipage}\vspace{4mm} + +%--#] GTwoText : +%--#[ CTwoText : + +\noindent +\begin{minipage}{4.53cm} +\begin{axopicture}{(110,110)(-10,0)} +\AxoGrid(0,0)(10,10)(9,9){LightGray}{0.5} +\ArrowLine(30,65)(60,25) +\SetPFont{Times-Bold}{10} +\CTwoText(30,65){LightYellow}{Blue}{That is}{no proof!} +\SetPFont{Courier-Bold}{14} +\CTwoText(60,25){Red}{Yellow}{Yes}{it is} +\end{axopicture} +\end{minipage} +\begin{minipage}{10.8cm} +\label{ctwotext} +\verb:\ArrowLine(30,65)(60,25): \hfill \\ +\verb:\SetPFont{Times-Bold}{10}: \hfill \\ +\verb:\CTwoText(30,65){LightYellow}{Blue}: \\ + \verb:{That is}{no proof!}: \hfill \\ +\verb:\SetPFont{Courier-Bold}{14}: \hfill \\ +\verb:\CTwoText(60,25){Red}{Yellow}{Yes}{it is}: \hfill \\ +The \verb:\CTwoText: command writes a centered box with two lines of text in +it. It uses Axodraw's current Postscript font. The third argument is +the color of both +the box and the text. The fourth argument is the color with which the box +will be filled. +\end{minipage}\vspace{4mm} + +%--#] CTwoText : +%--#[ Features : + +Note that because you can now use \LaTeX{} commands for the text +arguments of the commands described in this section, the effects of +the \verb+\BTwoText+, \verb+\GTwoText+, and \verb+\CTwoText+ can be +achieved also by the use of regular \verb:\BText: etc commands. +Mathematics can also be used. (None of these was possible in v.\ 1 of +axodraw.) Here are some examples: \vspace{4mm} + +\noindent +\begin{minipage}{5.5cm} +\begin{axopicture}{(150,90)(-10,0)} +\AxoGrid(0,0)(10,10)(12,9){LightGray}{0.5} +\SetPFont{Helvetica}{15} +\BText(60,45){% + \begin{minipage}{4.5cm} + Here is boxed text in a larger size, including + mathematics: $\alpha^2$. + \end{minipage}% +} +\end{axopicture} +\end{minipage} +\begin{minipage}{8.5cm} +\label{btext2} +\begin{verbatim} +\SetPFont{Helvetica}{15} +\BText(70,45){% + \begin{minipage}{4.5cm} + Here is boxed text in a + larger size, including + mathematics: $\alpha^2$. + \end{minipage}% +} +\end{verbatim} +This example shows that the \verb:\BText: command can also be used +with minipages and other \LaTeX{} methods to make more complicated +boxed texts. +\end{minipage} +\vspace{4mm} + +\noindent +\begin{minipage}{5.5cm} +\begin{axopicture}{(150,90)(-10,0)} +\AxoGrid(0,0)(10,10)(13,9){LightGray}{0.5} +\SetPFont{}{15} +\BText(65,45){% + \begin{minipage}{4cm} + \sffamily Here is boxed text in a + large size, including + mathematics: $\alpha^2$. + \end{minipage}% +} +\end{axopicture} +\end{minipage} +\begin{minipage}{8.5cm} +\label{btext2.mod} +\begin{verbatim} +\SetPFont{}{15} +\BText(65,45){% + \begin{minipage}{4cm} + \sffamily Here is boxed text in a + large size, including + mathematics: $\alpha^2$. + \end{minipage}% +} +\end{verbatim} +But if you use mathematics, the text may be more elegant if you use +the document font, which has matching fonts for text and mathematics. +Use of a sans-serif font (by \verb:\sffamily:) may be better in a diagram. +\end{minipage} +\vspace{4mm} + +%--#] Features : +%>>#] Text : +%>>#[ Options : + +\subsection{Options} +\label{sec:options} + +Almost all of axodraw2's line-drawing commands take optional +arguments. The form here is familiar from many standard \LaTeX{} +commands. The optional arguments are placed in square brackets after +the command name, and are made of a comma-separated list of items of +the form: \texttt{keyword} or \texttt{keyword=value}. The required +arguments are placed afterwards. + +Optional arguments can be used to set particular characteristics of a +line, e.g., whether it is dashed or has an arrow. They can also be +used to set some of the line's parameters, to be used instead of +default values. (The default values can be adjusted by commands +listed in Sec.\ \ref{sec:settings}. Those commands are useful for +adjusting parameters that apply to multiple lines, while the optional +arguments are useful for setting parameters for individual lines.) + +The original axodraw only had different command names to determine +whether lines were dashed, or had arrows, etc. The new version +retains these commands, +but now the basic commands +(\verb:\Line:, \verb:\Arc:, \verb:\Gluon:, etc) can also be treated as +generic commands, with the different varieties (dashed, double, and/or +with an arrow) being set by options. + +The same set of options are available for all types of line. However, +not all apply or are implemented for particular types of line. Thus, +\texttt{clockwise} is irrelevant for a straight line, while +\texttt{arrow} is not implemented for gluons, photons and zigzag +lines. Warnings are given for unimplemented features, while +inapplicable arguments are ignored. + +The full set of options. +\begin{center} +\begin{tabular}{ll} + color=\colorname & Set the line in this color. \\ + colour=\colorname & Same as color=\colorname. \\ + dash & Use a dashed line. \\ + dsize=\num & Set the dash size (when a line is dashed). \\ + dashsize=\num & Same as dsize=\num. \\ + double & Use a double line. \\ + sep=\num & Sets the separation for a double line. \\ + linesep=\num & Same as sep=\num. \\ + width=\num & Sets line width for this line only.\\[2mm] + clock & For arcs, makes the arc run clockwise. \\ + clockwise & For arcs, makes the arc run clockwise. \\[2mm] + arrow & Use an arrow.\\ + flip & If there is an arrow, its direction is flipped. \\ + + arrowpos=\num & The number should be between zero and one and\\ + & indicates where along the line the arrow should be. \\ + & 1 is at the end. 0.5 is halfway (the initial default).\\ + arrowaspect=\num & See Sec.\ \ref{sec:arrows}. \\ + arrowlength=\num & See Sec.\ \ref{sec:arrows}. \\ + arrowheight=\num & See Sec.\ \ref{sec:arrows}. \\ + arrowinset=\num & See Sec.\ \ref{sec:arrows}. \\ + arrowscale=\num & See Sec.\ \ref{sec:arrows}. \\ + arrowstroke=\num & See Sec.\ \ref{sec:arrows}. \\ + arrowwidth=\num & See Sec.\ \ref{sec:arrows}. \\ + inset=\num & Same as arrowinset.\\ +\end{tabular} +\end{center} +The options without an extra argument, e.g., \texttt{arrow}, are +actually of a boolean type. That is, they can also be used with a +suffix ``\texttt{=true}'' or ``\texttt{=false}'', e.g., +\texttt{arrow=true} or \texttt{arrow=false}. + +If an option is not provided, its default value is used. Defaults are +no dashes, no double lines, anticlockwise arcs, no arrow and if an +arrow is asked for, its position is halfway along the line. Other +arrow settings are explained in Sec.\ \ref{sec:arrows}. There are +also default values for dash size (3) and the separation of double +lines (2). + +The full set of the generic line commands with their syntax is +\begin{center} + \begin{tabular}{l} + \verb+\Line[options](x1,y1)(x2,y2)+ \\ + \verb+\Arc[options](x,y)(r,theta1,theta2)+ \\ + \verb+\Bezier[options](x1,y1)(x2,y2)(x3,y3)(x4,y4)+ \\ + \verb+\Gluon[options](x1,y1)(x2,y2){amplitude}{windings}+ \\ + \verb+\GluonArc[options](x,y)(r,theta1,theta2){amplitude}{windings}+ \\ + \verb+\GluonCirc[options](x,y)(r,phase){amplitude}{windings}+ \\ + \verb+\Photon[options](x1,y1)(x2,y2){amplitude}{windings}+ \\ + \verb+\PhotonArc[options](x,y)(r,theta1,theta2){amplitude}{windings}+ \\ + \verb+\ZigZag[options](x1,y1)(x2,y2){amplitude}{windings}+ \\ + \verb+\ZigZagArc[options](x,y)(r,theta1,theta2){amplitude}{windings}+ \\ + \end{tabular} +\end{center} +The applicability of the options is as follows +\begin{center} + \begin{tabular}{lcc} + & Arrow, etc & Clockwise \\ + \verb+\Line+ & Y & N \\ + \verb+\Arc+ & Y & Y \\ + \verb+\Bezier+ & Y & N \\ + \verb+\Gluon+ & N & N \\ + \verb+\GluonArc+ & N & Y \\ + \verb+\GluonCirc+ & N & N \\ + \verb+\Photon+ & N & N \\ + \verb+\PhotonArc+ & N & Y \\ + \verb+\ZigZag+ & N & N \\ + \verb+\ZigZagArc+ & N & Y \\ + \end{tabular} +\end{center} +The arrow options include those for setting the arrow dimensions. +Options not indicated in the last table apply to all cases. + +%{\sc The next options still have to be implemented, but it seems the most +%sensible thing to do.}\vspace{3mm} +% +%The third family is the one of the shapes: +% +%\begin{center} +%\begin{minipage}{14cm} +%\begin{verbatim} +%\Box[options](x1,y1)(x2,y2) +%\Tri[options](x1,y1)(x2,y2)(x3,y3) +%\Polygon[options]{(x1,y1)(x2,y2)...(xn,yn)} +%\Circ[options](x1,y1){radius} +%\Oval[options](x1,y1)(height,width)(rotation) +%\end{verbatim} +%\end{minipage} +%\end{center} +% +%\noindent The options here are: +%\begin{center} +%\begin{tabular}{ll} +% centered & For boxes: x1,y1 is the center. x2,y2 is width, +% height \\ +% blanked & Inside is blanked out. \\ +% inside & (Over)write only the inside. \\ +% color,line=$<$color$>$ & Main color. \\ +% filled,fill=$<$color$>$ & When both the outline and the inside are written. \\ +% gray,grayscale=\num & Inside is in gray. Filled overwrites this. \\ +% rotation=\num & Only for centered boxes: rotation angle. +%\end{tabular} +%\end{center} +%The options gray and filled imply blanked. Hence it is not needed to use +%blanked when either of those options is used. The default values are that +%none of these options are used. + +Some examples are: +\begin{verbatim} + \Line[double,sep=1.5,dash,dsize=4](10,10)(70,30) + \Line[double,sep=1.5,arrow,arrowpos=0.6](10,10)(70,30) +\end{verbatim} + +The options can also be used on the more explicit commands as extra +options. Hence it is possible to use +\begin{verbatim} + \DoubleLine[dash,dsize=4](10,10)(70,30){1.5} +\end{verbatim} +instead of the first line in the previous example. + +One may notice that some of the options are not accessible with the more +explicit commands. For example, it is possible to put arrows on B\'ezier +curves only by using the option `arrow' for the B\'ezier command. + +%>>#] Options : +%>>#[ Remarks about Gluons : +% +\subsection{Remarks about Gluons} +\label{sec:gluon.remarks} + +There are 12 commands that concern gluons. This allows much freedom in +developing one's own style. Gluons can be drawn as single solid lines, as +double lines, as dashed lines and as dashed double lines. + +Gluons have an amplitude and a number of windings. By varying these +quantities one may obtain completely different gluons as in: + +\noindent +\begin{minipage}{3.83cm} +\begin{axopicture}{(90,90)(-10,0)} +\AxoGrid(0,0)(10,10)(9,8){LightGray}{0.5} +\Gluon(10,70)(80,70){3}{5} +\Gluon(10,50)(80,50){3}{9} +\Gluon(10,30)(80,30){5}{7} +\Gluon(10,10)(80,10){8}{9} +\end{axopicture} +\end{minipage} +\begin{minipage}{11.5cm} +\label{gluons} +\verb:\Gluon(10,70)(80,70){3}{5}: \hfill \\ +\verb:\Gluon(10,50)(80,50){3}{9}: \hfill \\ +\verb:\Gluon(10,30)(80,30){5}{7}: \hfill \\ +\verb:\Gluon(10,10)(80,10){8}{9}: +\end{minipage}\vspace{4mm} + +One may change the orientation of the windings by reversing the +direction in which the gluon is drawn and/or changing the sign of the +amplitude: + +\noindent +\begin{minipage}{3.83cm} +\begin{axopicture}{(90,90)(-10,0)} +\AxoGrid(0,0)(10,10)(9,8){LightGray}{0.5} +\DoubleGluon(10,70)(80,70){5}{7}{1.2} +\DoubleGluon(80,50)(10,50){5}{7}{1.2} +\DoubleGluon(10,30)(80,30){-5}{7}{1.2} +\DoubleGluon(80,10)(10,10){-5}{7}{1.2} +\end{axopicture} +\end{minipage} +\begin{minipage}{11.5cm} +\label{gluonss} +\verb:\DoubleGluon(10,70)(80,70){5}{7}{1.2}: \hfill \\ +\verb:\DoubleGluon(80,50)(10,50){5}{7}{1.2}: \hfill \\ +\verb:\DoubleGluon(10,30)(80,30){-5}{7}{1.2}: \hfill \\ +\verb:\DoubleGluon(80,10)(10,10){-5}{7}{1.2}: +\end{minipage}\vspace{4mm} + +\noindent +\begin{minipage}{3.83cm} +\begin{axopicture}{(90,70)(-10,0)} +\AxoGrid(0,0)(10,10)(9,7){LightGray}{0.5} +\GluonArc(45,20)(40,20,160){5}{8} +\GluonArc(45,0)(40,20,160){-5}{8} +\end{axopicture} +\end{minipage} +\begin{minipage}{11.5cm} +\label{gluonarcA} +\verb:\GluonArc(45,20)(40,20,160){5}{8}:\hfill \\ +\verb:\GluonArc(45,0)(40,20,160){-5}{8}:\hfill \\ +Here one can see that the sign of the amplitude gives a completely +different aspect to a gluon on an arc segment. +\end{minipage}\vspace{4mm} + +There are two ways of drawing a gluon circle. One is with the command +GluonCirc and the other is an arc of 360 degrees with the GluonArc command. +The second way has a natural attachment point, because the GluonArc +command makes gluons with a begin- and endpoint. \vspace{4mm} + +\noindent +\begin{minipage}{3.83cm} +\begin{axopicture}{(80,80)(-15,0)} +\AxoGrid(0,0)(10,10)(8,8){LightGray}{0.5} +\GluonCirc(40,40)(30,0){5}{16} +\end{axopicture} +\end{minipage} +\begin{minipage}{11.5cm} +%\label{gluoncirc} +\verb:\GluonCirc(40,40)(30,0){5}{16}:\hfill \\ +This is the `complete circle'. If one likes to attach one or more lines to +it one should take into account that the best places for this are at a +distance radius+amplitude from the center of the circle. One can rotate the +circle by using the phase argument. +\end{minipage}\vspace{4mm} + +\noindent +\begin{minipage}{3.83cm} +\begin{axopicture}{(80,80)(-15,0)} +\AxoGrid(0,0)(10,10)(8,8){LightGray}{0.5} +\GluonArc(40,40)(30,0,360){5}{16} +\end{axopicture} +\end{minipage} +\begin{minipage}{11.5cm} +\label{gluonarc360} +\verb:\GluonArc(40,40)(30,0,360){5}{16}:\hfill \\ +In the 360 degree arc there is a natural point of attachment. Of course +there is only one such point. If one needs more than one such point one +should use more than one arc segment. +\end{minipage}\vspace{4mm} + +Some examples are: + +\begin{center} \begin{axopicture}{(460,60)(0,0)} +\Gluon(7,30)(27,30){3}{3} +\GluonCirc(50,30)(20,0){3}{16} +\Gluon(73,30)(93,30){3}{3} +\Vertex(27,30){1.5} +\Vertex(73,30){1.5} +% +\Gluon(110,30)(130,30){3}{3} +\GluonArc(150,30)(20,0,180){3}{8} +\GluonArc(150,30)(20,180,360){3}{8} +\Gluon(170,30)(190,30){3}{3} +\Vertex(130,30){1.5} +\Vertex(170,30){1.5} +% +\Gluon(210,30)(230,30){3}{3} +\GluonArc(250,30)(20,0,180){-3}{8} +\GluonArc(250,30)(20,180,360){-3}{8} +\Gluon(270,30)(290,30){3}{3} +\Vertex(230,30){1.5} +\Vertex(270,30){1.5} +% +\DashLine(310,30)(330,30){3} +\GluonArc(350,30)(20,-180,180){3}{16} +\Vertex(330,30){1.5} +% +\DashLine(387,30)(407,30){3} +\GluonCirc(430,30)(20,0){3}{16} +\Vertex(407,30){1.5} +% +\end{axopicture} \end{center} +This picture was generated with the code: +\begin{verbatim} +\begin{center} \begin{axopicture}{(460,60)(0,0)} + \Gluon(7,30)(27,30){3}{3} + \GluonCirc(50,30)(20,0){3}{16} + \Gluon(73,30)(93,30){3}{3} + \Vertex(27,30){1.5} + \Vertex(73,30){1.5} + \Gluon(110,30)(130,30){3}{3} + \GluonArc(150,30)(20,0,180){3}{8} + \GluonArc(150,30)(20,180,360){3}{8} + \Gluon(170,30)(190,30){3}{3} + \Vertex(130,30){1.5} + \Vertex(170,30){1.5} + \Gluon(210,30)(230,30){3}{3} + \GluonArc(250,30)(20,0,180){-3}{8} + \GluonArc(250,30)(20,180,360){-3}{8} + \Gluon(270,30)(290,30){3}{3} + \Vertex(230,30){1.5} + \Vertex(270,30){1.5} + \DashLine(310,30)(330,30){3} + \GluonArc(350,30)(20,-180,180){3}{16} + \Vertex(330,30){1.5} + \DashLine(387,30)(407,30){3} + \GluonCirc(430,30)(20,0){3}{16} + \Vertex(407,30){1.5} +\end{axopicture} \end{center} +\end{verbatim} + +%>>#] Remarks about Gluons : +%>>#[ Arrows : + +\subsection{Remarks about arrows} +\label{sec:arrows} + +%--#[ General : + +The old Axodraw arrows were rather primitive little triangles. The JaxoDraw +program has introduced fancier arrows which the user can also customize. +There are parameters connected to this as shown in the figure: +\begin{center} +\begin{axopicture}{(150,100)(0,0)} +\AxoGrid(0,0)(10,10)(15,10){LightGray}{0.5} +\SetWidth{3} +%\Line(10,50)(130,50) +%\FilledPolygon{(140,50)(90,90)(105,50)(90,10)}{White} +%\Polygon{(140,50)(90,90)(105,50)(90,10)}{Black} +%\SetWidth{0.5} +%\LongArrow(85,50)(85,90) +%\LongArrow(90,5)(105,5) +%\LongArrow(90,95)(140,95) +%\SetPFont{Helvetica}{9} +%\PText(110,85)(0)[l]{Length} +%\PText(76,71)(90)[c]{Width} +%\PText(110,5)(0)[l]{Inset} +\Line[arrow,arrowinset=0.3,arrowaspect=1,arrowwidth=40,arrowpos=1, + arrowstroke=3](10,50)(100,50) +\SetWidth{0.5} +\LongArrow(55,50)(55,90) +\LongArrow(60,5)(84,5) +\LongArrow(60,95)(140,95) +\SetPFont{Helvetica}{9} +\PText(100,85)(0)[l]{Length} +\PText(46,71)(90)[c]{Width} +\PText(90,5)(0)[l]{Inset} +\end{axopicture}\vspace{2mm} \\ +\verb:\Line[arrow,arrowinset=0.3,arrowaspect=1,arrowwidth=40,arrowpos=1,:\\ +\verb:arrowstroke=3](10,50)(100,50): +\end{center} +The full set of parameters is: +\begin{description} +\item[aspect] A multiplicative parameter when the length is calculated +from the width. The normal formula is: +$\mbox{length}=2\times \mbox{width}\times \mbox{aspect}$. +\item[inset] The fraction of the length that is taken inward. +\item[length] The full length of the arrowhead. +\item[position] The position of the arrow in the line as a fraction of the +length of the line. +\item[scale] A scale parameter for the complete arrowhead. +\item[stroke] The width of the line that makes up the arrowhead. If the +value is not set (default value is zero) the arrow is filled and overwrites +whatever was there. In the case of a stroke value the contents are +overwritten in the background color. +\item[width] The half width of the arrowhead. +\end{description} +The parameters can be set in two ways. One is with one of the commands +\begin{center} +\begin{tabular}{ll} +\verb:\SetArrowScale{number}: & Initial value is 1. \\ +\verb:\SetArrowInset{number}: & Initial value is 0.2 \\ +\verb:\SetArrowAspect{number}: & Initial value is 1.25 \\ +\verb:\SetArrowPosition{number}: & Initial value is 0.5 \\ +\verb:\SetArrowStroke{number}: & Initial value is 0 \\ +\end{tabular} \vspace{2mm} \\ +\end{center} +(A complete list of commands for setting defaults is in +Sec.\ \ref{sec:settings}.) +These commands determine settings that will hold for all following +commands, up to the end of whatever \LaTeX{} or \TeX{} grouping the +default setting is given in. E.g., setting a default value inside an +\texttt{axopicture} environment sets it until the end of the +environment only. (Thus the settings obey the normal rules of +\LaTeX{} for scoping.) + +The other way is to use one or more of these parameters as options in a +command that uses an arrow. The general use of options is in Sec.\ +\ref{sec:options}. The options that are available are +\begin{center} +\begin{tabular}{ll} + arrow & initial default=false \\ + arrowscale=\num & initial default=1 \\ + arrowwidth=\num & initial default=0 \\ + arrowlength=\num & initial default=0 \\ + arrowpos=\num & initial default=0.5 \\ + arrowinset=\num & initial default=0.2 \\ + arrowstroke=\num & initial default=0 \\ + arrowaspect=\num & initial default=1.25 \\ + flip & initial default=false +\end{tabular} +\end{center} +The arrow option tells the program to draw an arrow. Without it no +arrow will be drawn. The flip option indicates that the direction of +the arrow should be reversed from the `natural' direction. + +When +neither the width nor the length are specified, but instead both are +given as zero, they are computed from the line width (and the line +separation when there is a double line). The formula is: +\begin{eqnarray} + \mbox{Arrowwidth} & = & + 1.2 \times \left( \mbox{linewidth} + + 0.7 \times \mbox{separation} + + 1 + \right) + \times \mbox{arrowscale}, +\\ +\label{arrowlength} + \mbox{Length} & = & + 2 \times \mbox{arrowwidth} \times \mbox{arrowaspect}. +\end{eqnarray} +%If however $\mbox{linewidth} + \frac{1}{4} \times \mbox{separation} < +%0.5$ the formula for the arrow width becomes $\mbox{arrowwidth} = 2.5 +%\times \mbox{arrowscale}$. +If, however, $1.2 \times(\mbox{linewidth}+0.7\times\mbox{separation}+1)$ is less +than 2.5, the formula for the arrow width becomes +$\mbox{arrowwidth}=2.5\times\mbox{arrowscale}$. + +If only one of the arrowwidth or the arrowlength parameters is zero, +it is computed from the other non-zero parameter using formula +(\ref{arrowlength}). When both are non-zero, those are the values that +are used. + +The position of the arrowhead is a bit tricky. The arrowpos parameter is a +fraction of the length of the line and indicates the position of the center +of the arrowhead. This means that when arrowpos is one, the arrowhead +sticks out beyond the end of the line by half the arrowlength. When for +instance the line width is 0.5, the default length of the arrowhead +defaults to 6.25. Hence if one would like to compensate for this one should +make the line 3.125 points shorter. Usually 3 pt will be sufficient. + +Because of backward compatibility axodraw2 has many individual commands for +lines with arrows. We present them here, together with some `options' +varieties.\vspace{4mm} + +%--#] General : +%--#[ ArrowLine : + +\noindent +\begin{minipage}{3.83cm} +\begin{axopicture}{(90,80)(-10,0)} +\AxoGrid(0,0)(10,10)(9,8){LightGray}{0.5} +\Line[arrow,arrowscale=2](10,70)(80,70) +\Line[arrow,arrowpos=0.8,flip](10,50)(80,50) +\Line[arrow](10,30)(80,30) +\ArrowLine(10,10)(80,10) +\end{axopicture} +\end{minipage} +\begin{minipage}{11.5cm} +\label{arrowline} +\verb:\Line[arrow,arrowscale=2](10,70)(80,70): \hfill \\ +\verb:\Line[arrow,arrowpos=0.8,flip](10,50)(80,50): \hfill \\ +\verb:\Line[arrow](10,30)(80,30): \hfill \\ +\verb:\ArrowLine(10,10)(80,10): \hfill \\ +The default position for the arrow is halfway (arrowpos=0.5). With the line +command and the options we can put the arrow in any position. +\end{minipage}\vspace{4mm} + +%--#] ArrowLine : +%--#[ LongArrow : + +\noindent +\begin{minipage}{3.83cm} +\begin{axopicture}{(90,60)(-10,0)} +\AxoGrid(0,0)(10,10)(9,6){LightGray}{0.5} +\Line[arrow,arrowpos=1](10,30)(80,30) +\LongArrow(10,10)(80,10) +\SetWidth{4} +\LongArrow[arrowscale=0.8](10,50)(70,50) +\end{axopicture} +\end{minipage} +\begin{minipage}{11.5cm} +\label{longarrow} +\verb:\Line[arrow,arrowpos=1](10,30)(80,30): \hfill \\ +\verb:\LongArrow(10,10)(80,10): \hfill \\ +\verb:\SetWidth{4}: \hfill \\ +\verb:\LongArrow[arrowscale=0.8](10,50)(70,50): \hfill \\ +The \verb:\LongArrow: command just places the arrowhead at the end of the +line. The size of the arrowhead is a function of the linewidth. +\end{minipage}\vspace{4mm} + +%--#] LongArrow : +%--#[ ArrowDoubleLine : + +\noindent +\begin{minipage}{3.83cm} +\begin{axopicture}{(90,100)(-10,0)} +\AxoGrid(0,0)(10,10)(9,10){LightGray}{0.5} +\SetArrowStroke{1} +\Line[arrow,arrowpos=1,double,sep=5,arrowscale=1.3](10,90)(75,90) +\Line[arrow,arrowpos=1,double,sep=2,arrowscale=1.5](10,70)(80,70) +\Line[arrow,arrowpos=1,double,sep=2](10,50)(80,50) +\Line[arrow,double,sep=2](10,30)(80,30) +\ArrowDoubleLine(10,10)(80,10){2} +\end{axopicture} +\end{minipage} +\begin{minipage}{11.5cm} +\label{arrowdoubleline} +\verb:\SetArrowStroke{1}: \hfill \\ +\verb:\Line[arrow,arrowpos=1,double,sep=5,arrowscale=1.3]: \hfill \\ + \verb: (10,90)(75,90): \hfill \\ +\verb:\Line[arrow,arrowpos=1,double,sep=2,arrowscale=1.5]: \hfill \\ + \verb: (10,70)(80,70): \hfill \\ +\verb:\Line[arrow,arrowpos=1,double,sep=2](10,50)(80,50): \hfill \\ +\verb:\Line[arrow,double,sep=2](10,30)(80,30): \hfill \\ +\verb:\ArrowDoubleLine(10,10)(80,10){2}: \hfill \\ +As one can see, the arrows also work with double lines. +\end{minipage}\vspace{4mm} + +%--#] ArrowDoubleLine : +%--#[ ArrowDashLine : + +\noindent +\begin{minipage}{3.83cm} +\begin{axopicture}{(90,80)(-10,0)} +\AxoGrid(0,0)(10,10)(9,8){LightGray}{0.5} +\Line[arrow,arrowpos=0.3,dash,dsize=3,arrowscale=1.5](10,70)(80,70) +\DashArrowLine(10,50)(80,50){3} +\Line[arrow,dash,dsize=3](10,30)(80,30) +\ArrowDashLine(10,10)(80,10){3} +\end{axopicture} +\end{minipage} +\begin{minipage}{11.5cm} +\label{arrowdashline} +\verb:\Line[arrow,arrowpos=0.3,dash,dsize=3,arrowscale=1.5]: \\ + \verb:(10,70)(80,70): \\ +\verb:\DashArrowLine(10,50)(80,50){3}: \\ +\verb:\Line[arrow,dash,dsize=3](10,30)(80,30): \\ +\verb:\ArrowDashLine(10,10)(80,10){3}: \\ +We have not taken provisions for the dashes to be centered in the +arrowhead, because at times that is nearly impossible. The commands +\verb:\ArrowDashLine: and \verb:\DashArrowLine: are identical. +\end{minipage}\vspace{4mm} + +%--#] ArrowDashLine : +%--#[ ArrowDashDoubleLine : + +\noindent +\begin{minipage}{3.83cm} +\begin{axopicture}{(90,80)(-10,0)} +\AxoGrid(0,0)(10,10)(9,8){LightGray}{0.5} +\SetArrowStroke{0.5} +\Line[arrow,arrowpos=1,dash,dsize=3,double,sep=1.5,arrowscale=1.5](10,70)(80,70) +\DashArrowDoubleLine(10,50)(80,50){1.5}{3} +\Line[arrow,dash,dsize=3,double,sep=1.5](10,30)(80,30) +\ArrowDashDoubleLine(10,10)(80,10){1.5}{3} +\end{axopicture} +\end{minipage} +\begin{minipage}{11.5cm} +\label{arrowdashdoubleline} +\verb:\SetArrowStroke{0.5}: \\ +\verb:\Line[arrow,arrowpos=1,dash,dsize=3,double: \\ + \verb:,sep=1.5,arrowscale=1.5](10,70)(80,70): \\ +\verb:\DashArrowDoubleLine(10,50)(80,50){1.5}{3}: \\ +\verb:\Line[arrow,dash,dsize=3](10,30)(80,30): \\ +\verb:\ArrowDashDoubleLine(10,10)(80,10){1.5}{3}: \\ +The \verb:\ArrowDashDoubleLine: and \verb:\DashArrowDoubleLine: +commands are identical. +\end{minipage}\vspace{4mm} + +%--#] ArrowDashDoubleLine : +%--#[ LongArrowDashLine : + +\noindent +\begin{minipage}{3.83cm} +\begin{axopicture}{(90,80)(-10,0)} +\AxoGrid(0,0)(10,10)(9,8){LightGray}{0.5} +\Line[arrow,arrowpos=0,dash,dsize=3,arrowscale=1.5,flip](10,70)(80,70) +\DashLongArrowLine(10,50)(80,50){3} +\Line[arrow,arrowpos=1,dash,dsize=3](10,30)(80,30) +\LongArrowDashLine(10,10)(80,10){3} +\end{axopicture} +\end{minipage} +\begin{minipage}{11.5cm} +\label{longarrowdashline} +\verb:\Line[arrow,arrowpos=0,dash,dsize=3,arrowscale=1.5: \\ + \verb:,flip](10,70)(80,70): \\ +\verb:\DashLongArrowLine(10,50)(80,50){3}: \\ +\verb:\Line[arrow,arrowpos=1,dash,dsize=3](10,30)(80,30): \\ +\verb:\LongArrowDashLine(10,10)(80,10){3}: \\ +The commands +\verb:\LongArrowDashLine:, \verb:\DashLongArrowLine:, +\verb:\LongArrowDash: and \verb:\DashLongArrow: are identical. +\end{minipage}\vspace{4mm} + +%--#] LongArrowDashLine : +%--#[ ArrowArc : + +\noindent +\begin{minipage}{3.83cm} +\begin{axopicture}{(90,140)(-10,0)} +\AxoGrid(0,0)(10,10)(9,14){LightGray}{0.5} +\Arc[arrow,arrowpos=1,clock](45,95)(40,160,20) +\LongArrowArcn(45,80)(40,160,20) +\Arc[arrow,arrowpos=0.5,clock](45,65)(40,160,20) +\ArrowArcn(45,50)(40,160,20) +\Arc[arrow,arrowpos=1](45,35)(40,20,160) +\LongArrowArc(45,20)(40,20,160) +\Arc[arrow,arrowpos=0.5](45,5)(40,20,160) +\ArrowArc(45,-10)(40,20,160) +\end{axopicture} +\end{minipage} +\begin{minipage}{11.5cm} +\label{arrowarc} +\verb:\Arc[arrow,arrowpos=0,flip](45,95)(40,20,160): \\ +\verb:\LongArrowArcn(45,80)(40,20,160): \\ +\verb:\Arc[arrow,arrowpos=0.5](45,65)(40,20,160): \\ +\verb:\ArrowArcn(45,50)(40,20,160): \\ +\verb:\Arc[arrow,arrowpos=1](45,35)(40,20,160): \\ +\verb:\LongArrowArc(45,20)(40,20,160): \\ +\verb:\Arc[arrow,arrowpos=0.5](45,5)(40,20,160): \\ +\verb:\ArrowArc(45,-10)(40,20,160): \\ +The \verb:Arc: and the \verb:CArc: commands are identical. +\end{minipage}\vspace{4mm} + +%--#] ArrowArc : +%--#[ ArrowDashArc : + +\noindent +\begin{minipage}{3.83cm} +\begin{axopicture}{(90,110)(-10,0)} +\AxoGrid(0,0)(10,10)(9,11){LightGray}{0.5} +\Arc[arrow,dash,dsize=3,arrowpos=0.5,clock](45,65)(40,160,20) +\ArrowDashArcn(45,50)(40,160,20){3} +\Arc[arrow,dash,dsize=3,arrowpos=1](45,35)(40,20,160) +\LongArrowDashArc(45,20)(40,20,160){3} +\Arc[arrow,dash,dsize=3,arrowpos=0.5](45,5)(40,20,160) +\ArrowDashArc(45,-10)(40,20,160){3} +\end{axopicture} +\end{minipage} +\begin{minipage}{11.5cm} +\label{arrowdasharc} +\verb:\Arc[arrow,dash,dsize=3,arrowpos=0.5]: \\ + \verb:(45,65)(40,20,160): \\ +\verb:\ArrowDashArcn(45,50)(40,20,160){3}: \\ +\verb:\Arc[arrow,dash,dsize=3,arrowpos=1]: \\ + \verb:(45,35)(40,20,160): \\ +\verb:\LongArrowDashArc(45,20)(40,20,160){3}: \\ +\verb:\Arc[arrow,dash,dsize=3,arrowpos=0.5]: \\ + \verb:(45,5)(40,20,160): \\ +\verb:\ArrowDashArc(45,-10)(40,20,160){3}: \\ +The \verb:DashArrowArc: and the \verb:ArrowDashArc: commands are identical. +So are the commands \verb:DashArrowArcn: and \verb:ArrowDashArcn:. +\end{minipage}\vspace{4mm} + +%--#] ArrowDashArc : +%--#[ ArrowDashDoubleArc : + +\noindent +\begin{minipage}{3.83cm} +\begin{axopicture}{(90,80)(-10,0)} +\AxoGrid(0,0)(10,10)(9,8){LightGray}{0.5} +\Arc[arrow,dash,dsize=3,double,sep=1.5,arrowpos=0.5](45,35)(40,20,160) +\ArrowDashDoubleArc(45,20)(40,20,160){1.5}{3} +\Arc[arrow,double,sep=1.5,arrowpos=0.5](45,5)(40,20,160) +\ArrowDoubleArc(45,-10)(40,20,160){1.5} +\end{axopicture} +\end{minipage} +\begin{minipage}{11.5cm} +\label{arrowdashdoublearc} +\verb:\Arc[arrow,dash,dsize=3,double,sep=1.5: \\ + \verb:,arrowpos=0.5](45,35)(40,20,160): \\ +\verb:\ArrowDashDoubleArc(45,20)(40,160,20){1.5}{3}: \\ +\verb:\Arc[arrow,double,sep=1.5,arrowpos=0.5]: \\ + \verb:(45,5)(40,20,160): \\ +\verb:\ArrowDoubleArc(45,-10)(40,20,160){1.5}: \\ +Other commands involving Long do not exist. The options can take care of +their functionality. +\end{minipage}\vspace{4mm} + +%--#] ArrowDashDoubleArc : +%--#[ Bezier : + +Computing the position of the arrow in a B\'ezier curve is a bit complicated. +Let us recall the definition of a cubic B\'ezier curve: +\begin{eqnarray} + x & = & x_0 (1-t)^3 + 3 x_1 t (1-t)^2 + 3 x_2 t^2 (1-t) + x_3 t^3 + \nonumber \\ + y & = & y_0 (1-t)^3 + 3 y_1 t (1-t)^2 + 3 y_2 t^2 (1-t) + y_3 t^3 +\end{eqnarray} +Computing the length of the curve is done with the integral +\begin{eqnarray} + L & = & \int_0^1 dt + \sqrt{ \left( \frac{dx}{dt} \right)^2 + \left( \frac{dy}{dt} \right )^2 }, +\end{eqnarray} +which is an integral over the square root of a quartic polynomial. This we +do with a 16 point Gaussian quadrature and it gives us more than enough +accuracy\footnote{We need to compute the length of the B\'ezier curve also +when we want to put a dash pattern on it. The exact dash size is determined +such that an integer number of patterns fits in the line.}. Let us assume +now that we want the arrow at 0.6 of the length. To find the exact fraction +of the length involves finding the upper limit of the integral for which +the length is $0.6 L$. This requires an iteration procedure till we have a +reasonable accuracy for the position $(x,y)$. After that we have to calculate +the derivative in this point as well. + +Because the B\'ezier curves are new commands in axodraw2 there is no need for +backwards compatibility in the use of arrows. Hence all arrow commands are +done by means of the options. Some examples are: +\vspace{4mm} + +\noindent +\begin{minipage}{3.83cm} +\begin{axopicture}{(80,80)(-15,0)} +\AxoGrid(0,0)(10,10)(8,8){LightGray}{0.5} +\Bezier[arrow](10,10)(30,30)(10,50)(30,70) +\Bezier[arrow,dash,dsize=3](30,10)(50,30)(30,50)(50,70) +\Bezier[arrow,arrowpos=1,double,sep=1,arrowstroke=0.5](50,10)(70,30)(50,50)(70,70) +\end{axopicture} +\end{minipage} +\begin{minipage}{11.5cm} +\label{arrowbezier} +\verb:\Bezier[arrow](10,10)(30,30)(10,50)(30,70): \\ +\verb:\Bezier[arrow,dash,dsize=3](30,10)(50,30): \\ + \verb:(30,50)(50,70): \\ +\verb:\Bezier[arrow,arrowpos=1,double,sep=1,arrowstroke: \\ + \verb:=0.5](50,10)(70,30)(50,50)(70,70): +\end{minipage}\vspace{4mm} + +%--#] Bezier : +%>>#] Arrows : +%>>#[ Settings : + +\subsection{Units and scaling} +\label{sec:units} + +When you have constructed a diagram, you may need to change its scale, +to make it larger or smaller. Axodraw2 provides ways of doing this, +for scaling diagrams without recoding all the individual coordinates. +However the requirements for the nature of the scaling change between +different cases. For example, suppose a diagram is designed for use in +a journal article and you wish to use it in the slides for a seminar. +Then you will want to enlarge both the geometric size of the diagram's +objects and the text labels it contains. But if you wish to use a +scaled diagram in another place in a journal article, you will wish to +scale its lines etc, but will probably not wish to scale the text (to +preserve its legibility). + +Axodraw2 therefore provides tools for the different situations, so we +will now explain what to do. The commands to achieve this all appear +in the list of parameter-setting commands in Sec.\ \ref{sec:settings}. + + +\subsubsection{Scaling for slides} + +Suppose the original diagram is +\begin{center} +\begin{minipage}{10cm} +\begin{verbatim} + \SetPFont{Helvetica-Oblique}{12} + Document text. Then diagram: + \begin{axopicture}(60,43) + \Arc[arrow](30,0)(30,0,180) + \Text(30,33)[b]{$\alpha P_1$} + \CText(30,10){Red}{Yellow}{Arc} + \end{axopicture} +\end{verbatim} +\end{minipage} +\end{center} +to give +\begin{center} + \SetPFont{Helvetica-Oblique}{12} + Document text. Then diagram: + \begin{axopicture}(60,43) + \Arc[arrow](30,0)(30,0,180) + \Text(30,33)[b]{$\alpha P_1$} + \CText(30,10){Red}{Yellow}{Arc} + \end{axopicture} +\end{center} +Then you could double the scale of the diagram by +\begin{center} +\begin{minipage}{10cm} +\begin{verbatim} + \SetScale{2} + \fontsize{24}{26}\selectfont + \SetPFont{Helvetica-Oblique}{12} + Document text. Then diagram: + \begin{axopicture}(60,43) + \Arc[arrow](30,0)(30,0,180) + \Text(30,33)[b]{$\alpha P_1$} + \CText(30,10){Red}{Yellow}{Arc} + \end{axopicture} +\end{verbatim} +\end{minipage} +\end{center} +to get +\begin{center} + \SetScale{2} + \fontsize{24}{26}\selectfont + \SetPFont{Helvetica-Oblique}{12} + Document text. Then diagram: + \begin{axopicture}(60,43) + \Arc[arrow](30,0)(30,0,180) + \Text(30,33)[b]{$\alpha P_1$} + \CText(30,10){Red}{Yellow}{Arc} + \end{axopicture} +\end{center} +We have changed the size of the document font, as would be appropriate +for a make slides for a presentation; this we did by the +\verb+\fontsize+ command. The arc and the space inserted +in the document for the diagram have scaled up. The label inserted by +the \verb:\Text: command has changed to match the document font. The +postscript text in the \verb:\CText: was specified to be at +$\unit[12]{pt}$, but is now scaled up also. + +The above behavior is what axodraw2 does by default, and is what v.\ 1 +did. + + +\subsubsection{Scaling within article} + +If you wanted to make an enlarged figure in a journal article, you +would not change the document font. But the obvious modification to +the previous example is +\begin{center} +\begin{minipage}{10cm} +\begin{verbatim} + \SetScale{2} + \SetPFont{Helvetica-Oblique}{12} + Document text. Then diagram: + \begin{axopicture}(60,43) + \Arc[arrow](30,0)(30,0,180) + \Text(30,33)[b]{$\alpha P_1$} + \CText(30,10){Red}{Yellow}{Arc} + \end{axopicture} +\end{verbatim} +\end{minipage} +\end{center} +which gives +\begin{center} + \SetScale{2} + \SetPFont{Helvetica-Oblique}{12} + Document text. Then diagram: + \begin{axopicture}(60,43) + \Arc[arrow](30,0)(30,0,180) + \Text(30,33)[b]{$\alpha P_1$} + \CText(30,10){Red}{Yellow}{Arc} + \end{axopicture} +\end{center} +The label $\alpha P_1$ is now not enlarged, since it copies the +behavior of the document font. But the postscript text is enlarged, +which is probably undesirable. If you were scaling down the diagram +instead of scaling it up, the situation would be worse, because the +postscript font would be difficult to read. + +So in this situation, of scaling the diagram while keeping the +document font intact, you probably also want to leave unchanged the +size of the postscript font. You can achieve this by the +\verb:\PSTextScalesLikeGraphicsfalse: command: +\begin{center} +\begin{minipage}{10cm} +\begin{verbatim} + \SetScale{2} + \PSTextScalesLikeGraphicsfalse + \SetPFont{Helvetica-Oblique}{12} + Document text. Then diagram: + \begin{axopicture}(60,43) + \Arc[arrow](30,0)(30,0,180) + \Text(30,33)[b]{$\alpha P_1$} + \CText(30,10){Red}{Yellow}{Arc} + \end{axopicture} +\end{verbatim} +\end{minipage} +\end{center} +\begin{center} + \SetScale{2} + \PSTextScalesLikeGraphicsfalse + \SetPFont{Helvetica-Oblique}{12} + Document text. Then diagram: + \begin{axopicture}(60,43) + \Arc[arrow](30,0)(30,0,180) + \Text(30,33)[b]{$\alpha P_1$} + \CText(30,10){Red}{Yellow}{Arc} + \end{axopicture} +\end{center} + +To achieve this on a document-wide basis, which is probably what you +want, you can use the \texttt{PStextScalesIndependently} option when you +load axodraw2 --- see Sec.\ \ref{sec:invoke}. + +Nevertheless, if you turn off the default scaling of postscript text, +%you may still want to scale text. To do this you can use the +you may still want to scale text. For this you can use the +\verb:\SetTextScale: command, as in \verb:\SetTextScale{1.2}:. This +only has an effect when you have turned off the scaling of postscript +text with graphics objects; but then it applies to \TeX{} text +inserted by axodraw2's \verb:\Text: and \verb:\rText: commands, as +well text inserted by axodraw2's ``postscript-text'' commands. + +If you are confused by the above, we recommend experimentation to +understand how to achieve the effects that you specifically need. We +could have made the set of commands and options simpler, but only at +the expense of not being able to meet the demands of the different +plausible situations that we could imagine and have to deal with +ourselves. + +\subsubsection{Canvas and object scales} + +When you use \verb:\SetScale: outside an \verb:axopicture: +environment, as above, the scaling applies to both the axodraw2 +objects and the space inserted for the \texttt{axopicture} environment +in the document, as is natural. But you may find you need to scale a +subset of objects inside the diagram, e.g., +\begin{center} + \begin{minipage}{10cm} + \verb:\begin{axopicture}:(\dots)\\ + \hspace*{1cm} (First block)\\ + \verb:\SetScale{0.5}:\\ + \hspace*{1cm} (Second block)\\ + \verb:\end{axopicture}: + \end{minipage} +\end{center} +In this case, the units for specifying the objects in the second block +are different from those for specifying the \verb:axopicture: +environment's size (as well as the first block of objects). We thus +distinguish object units from canvas units, where ``canvas'' refers to +the \verb:axopicture: environment as a whole. + +Another complication is that the \LaTeX{} \verb+picture+ environment +has is own \verb:\unitlength: parameter. In v.\ 1 of axodraw, the +canvas scale was determined by \LaTeX's \verb:\unitlength:. But there +was an independent unit for the object scale; this was the one +determined by axodraw's \verb:\SetScale: command. Also, not all +objects used the object scale. The situation therefore got quite +confusing. In v.\ 1, if, as is often natural, you wished to scale the +canvas as well as the objects, you would have needed to set \LaTeX's +\verb:\unitlength: parameter as well as using axodraw's +\verb:\SetScale: command. + +So now we have arranged things so that the canvas and object scales +are tied by default, provided that you use axodraw2's \verb:\SetScale: +command, and that axodraw diagrams are inside \verb+axopicture+ +environments (in contrast to the \verb+picture+ environment used in +the original axodraw). +However, it may be necessary to keep backward compatibility in some +cases, and we weren't certain that the new behavior is exactly what is +always desired. So in axodraw2, we have provided three choices, given +by the \texttt{canvasScaleIs1pt}, \texttt{canvasScaleIsObjectScale}, +and \texttt{canvasScaleIsUnitLength} options when loading axodraw2 --- +see Sec.\ \ref{sec:invoke}. Naturally, +\texttt{canvasScaleIsObjectScale} is the default. If you wish to +change the setting mid-document, there are corresponding commands --- +Sec.\ \ref{sec:settings}. + + + +\subsection{Settings} +\label{sec:settings} + +Axodraw2 has a number of parameters that can be set by the user. The +parameters include defaults for line types, dimensions, etc. The +parameters can be set either inside the axopicture environment or +outside. If they are set outside they modify the default value for +subsequent pictures. If set inside they only affect the current +picture. (In general, the parameters obey the usual rules for the +scope of \LaTeX{} variables.) In many cases, the parameters provide +default values for a command to draw an object and can be overridden +for a single object by using an optional parameter in invoking the +command for the object. + +The unit for lengths is the current object scale, as set by the +\verb+\SetScale+ command. + +\break + +The parameter-setting commands are: +%\begin{center} +%\def\arraystretch{1.4} +%% +%% See preamble for definition of \name +%\def\descr#1#2{% +% % #1 = command-syntax, #2 = description +% \name{#1} & #2\\ +% \hline +%} +%\def\descrL#1#2{% +% % #1 = command-syntax, #2 = description +% % Set #1 on separate line +% \multicolumn{2}{|l|}{\name{#1}} \\ +% & #2\\ +% \hline +%} +%\catcode`\#=13 +%\def#{\#} +%% +%\begin{longtable}{|p{5cm}|p{10.2cm}|} +%\hline +% Command & Commentary +%\\ +%\hline +%% +%\descr{SetLineSep\{\#1\}}{ +% This sets the default separation of double lines. Its initial value +% is 2. +%} +%% +%\descr{SetDashSize\{\#1\}}{ +% This sets the default size for the size of the dashes of dashed +% lines. Its initial value is 3. +%} +%% +%\descr{SetWidth\{\#1\}}{ +% This sets the default width of lines. Its initial value is 1. +%} +%% +%\descr{SetScale\{\#1\}}{ +% This sets a scale factor. +% This factor applies a magnification factor to all +% axodraw2 graphics objects. When the setting that +% postscript-text-scales-like-graphics is set (as is true by +% default), it also applies to axodraw2's ``postscript-text'' +% writing commands (\name{PText}, \name{BText}, etc), but not to +% its \TeX{}-text commands (\name{Text} etc). The initial scale +% factor is unity. +%} +%% +%\descr{SetTextScale\{\#1\}}{ +% This factor applies a magnification factor to all +% axodraw2 text objects, but \emph{only when} the setting that +% postscript-text-scales-like-graphics is turned off. +%} +%% +%\descr{SetOffset(\#1,\#2)}{ +% Sets an offset value +% for all commands of +% axodraw2. Its value is not affected by the scale variable. +%} +%% +%\descr{SetScaledOffset(\#1,\#2)}{ +% Sets an offset for +% all commands of axodraw2. This +% offset is affected by the scale factor. +%} +%% +%\descr{SetColor\{\#1\}}{ +% Sets the named color, +% for both axodraw2 objects and regular text. See Sec.\ +% \ref{sec:colors} for details on using color with axodraw2. +%} +%% +%\descr{textRed}{ +% Alternative command for setting named a color +% for both axodraw2 objects and regular text. See Sec.\ +% \ref{sec:colors} for details on using color with axodraw2. +% There is one such command for each axodraw2 named color. +%} +%% +%\descr{SetPFont\{\#1\}\{\#2\}}{ +% Sets the Postscript +% font, and its size in units of points. See Sec.\ \ref{sec:PSText} +% for the commands that use this font, for a table of the names of +% the fonts. An empty first argument, instead of a font name, (as in +% \name{SetPFont\{\}\{20\}} indicates that the normal document font is +% to be used at the indicated size. An empty second argument, +% instead of the font size, (as in \name{SetPFont\{Helvetica\}\{\}} or +% \name{SetPFont\{\}\{\}}) indicates that the font size is to be +% \LaTeX's document font size at the time the text-making command is +% executed. +%} +%% +%\descr{SetArrowScale\{\#1\}}{ +% A scale parameter for the +% entire head of an arrow. +%} +%% +%\descr{SetArrowInset\{\#1\}}{ +% See Sec.\ \ref{sec:arrows}. +%} +%% +%\descr{SetArrowAspect\{\#1\}}{ +% See Sec.\ \ref{sec:arrows}. +%} +%% +%\descr{SetArrowPosition\{\#1\}}{ +% Determines where the +%arrowhead is on a line. The position is the fraction of the length of the +%line. +%} +%% +%\descr{SetArrowStroke\{\#1\}}{ +% This parameter determines the linewidth of the arrowhead if it is just +% outlined. Its initial value is zero (filled arrowhead). +%} +%% +%\descr{canvasScaleOnept}{ +% Sets canvas scale to $\unit[1]{pt}$. +%} +%% +%\descr{canvasScaleObjectScale}{ +% Sets canvas scale to equal the value set by \name{SetScale} in +% units of points. This is the initial default of axodraw2, +% unless overridden. +%} +%% +%\descr{canvasScaleUnitLength}{ +% The canvas scale is the same as \LaTeX's length parameter +% \name{unitlength}. +%} +%% +%\descrL{PSTextScalesLikeGraphicsfalse}{ +% Text drawn by all of Axodraws's text commands scales with the +% factor set by \name{SetTextScale}. +% See Sec.\ \ref{sec:text}. +%} +%% +%\descrL{PSTextScalesLikeGraphicstrue}{ +% (Default setting.) Text drawn by Axodraw's postscript-text +% commands scales with the same factor as graphics objects, as set +% by \name{SetScale}. Text drawn by Axodraw's \TeX{}-text +% commands is unscaled. +% See Sec.\ \ref{sec:text}. +%} +%\end{longtable} +%\end{center} +\begin{center} +\def\arraystretch{1.4} +% +% See preamble for definition of \name +\def\descr#1#2{% + % #1 = command-syntax, #2 = description + \name{#1} & #2\\ + \hline +} +\def\descrL#1#2{% + % #1 = command-syntax, #2 = description + % Set #1 on separate line + \multicolumn{2}{|l|}{\name{#1}} \\ + & #2\\ + \hline +} +\def\category#1{% + % #1 = name of category + \multicolumn{2}{l}{#1:} + \\ + \hline +} +\catcode`\#=13 +\def#{\#} +% +\begin{longtable}{|p{5cm}|p{10.2cm}|} +\hline +\endfirsthead + Command & Commentary +\\ +\hline +%==================== +\category{Lines} +% +\descr{SetDashSize\{\#1\}}{ + This sets the default size for the size of the dashes of dashed + lines. Its initial value is 3. +} +% +\descr{SetLineSep\{\#1\}}{ + This sets the default separation of double lines. Its initial value + is 2. +} +% +\descr{SetWidth\{\#1\}}{ + This sets the default width of lines. Its initial value is 0.5. +} +%==================== +\category{Arrows} +% +\descr{SetArrowAspect\{\#1\}}{ + See Sec.\ \ref{sec:arrows}. +} +% +\descr{SetArrowInset\{\#1\}}{ + See Sec.\ \ref{sec:arrows}. +} +% +\descr{SetArrowPosition\{\#1\}}{ + Determines where the +arrowhead is on a line. The position is the fraction of the length of the +line. +} +% +\descr{SetArrowScale\{\#1\}}{ + A scale parameter for the + entire head of an arrow. +} +% +\descr{SetArrowStroke\{\#1\}}{ + This parameter determines the linewidth of the arrowhead if it is just + outlined. Its initial value is zero (filled arrowhead). +} +%==================== +\category{Scaling} +% +\descr{canvasScaleOnept}{ + Sets canvas scale to $\unit[1]{pt}$. +} +% +\descr{canvasScaleObjectScale}{ + Sets canvas scale to equal the value set by \name{SetScale} in + units of points. This is the initial default of axodraw2, + unless overridden. +} +% +\descr{canvasScaleUnitLength}{ + The canvas scale is the same as \LaTeX's length parameter + \name{unitlength}. +} +% +\descr{SetScale\{\#1\}}{ + This sets a scale factor. + This factor applies a magnification factor to all + axodraw2 graphics objects. When the setting that + postscript-text-scales-like-graphics is set (as is true by + default), it also applies to axodraw2's ``postscript-text'' + writing commands (\name{PText}, \name{BText}, etc), but not to + its \TeX{}-text commands (\name{Text} etc). The initial scale + factor is unity. +} +% +\descr{SetTextScale\{\#1\}}{ + This factor applies a magnification factor to all + axodraw2 text objects, but \emph{only when} the setting that + postscript-text-scales-like-graphics is turned off. +} +% +\descrL{PSTextScalesLikeGraphicsfalse}{ + Text drawn by all of Axodraws's text commands scales with the + factor set by \name{SetTextScale}. + See Sec.\ \ref{sec:text}. +} +% +\descrL{PSTextScalesLikeGraphicstrue}{ + (Default setting.) Text drawn by Axodraw's postscript-text + commands scales with the same factor as graphics objects, as set + by \name{SetScale}. Text drawn by Axodraw's \TeX{}-text + commands is unscaled. + See Sec.\ \ref{sec:text}. +} +% +%==================== +\category{Offsets} +% +\descr{SetOffset(\#1,\#2)}{ + Sets an offset value + for all commands of + axodraw2. Its value is not affected by the scale variable. +} +% +\descr{SetScaledOffset(\#1,\#2)}{ + Sets an offset for + all commands of axodraw2. This + offset is affected by the scale factor. +} +% +%==================== +\category{Color} +% +\descr{SetColor\{\#1\}}{ + Sets the named color, + for both axodraw2 objects and regular text. See Sec.\ + \ref{sec:colors} for details on using color with axodraw2. +} +% +\descr{textRed}{ + Alternative command for setting named a color + for both axodraw2 objects and regular text. See Sec.\ + \ref{sec:colors} for details on using color with axodraw2. + There is one such command for each axodraw2 named color. +} +%==================== +\category{Font} +% +\descr{SetPFont\{\#1\}\{\#2\}}{ + Sets the Postscript + font, and its size in units of points. See Sec.\ \ref{sec:PSText} + for the commands that use this font, for a table of the names of + the fonts. An empty first argument, instead of a font name, (as in + \name{SetPFont\{\}\{20\}} indicates that the normal document font is + to be used at the indicated size. An empty second argument, + instead of the font size, (as in \name{SetPFont\{Helvetica\}\{\}} or + \name{SetPFont\{\}\{\}}) indicates that the font size is to be + \LaTeX's document font size at the time the text-making command is + executed. +} +% +\end{longtable} +\end{center} + + +%>>#] Settings : +%>>#[ Colors : + +\subsection{Colors} +\label{sec:colors} + +\TeX{} and \LaTeX{} by themselves do not provide any means to set +colors in a document. Instead, one must use a suitable package to +achieve the effect; the current standard one is \file{color.sty}. +Such a package performs its work by passing graphics commands to the +viewable output file. Since axodraw also works in a similar fashion, +there is a potentiality for conflicts. + +Axodraw version 1, released in 1994, used the package +\file{colordvi.sty} for applying color to normal textual material, +and its own separate methods for applying color to its graphical +objects. They both defined the same convenient set of named colors +that could be used, but they had to be set separately for text and +graphics\footnote{The named colors corresponded to ones defined by the + \program{dvips} program.}. The \file{colordvi.sty} package also had +an important disadvantage that its color settings did not respect +\TeX{} grouping and \LaTeX{} environments, so that a color setting +made for text in an environment continued to apply after the end of +the environment. + +Since then, the available tools, notably in the powerful +\file{color.sty}, have greatly improved. But this has introduced +both real and potential incompatibilities with the older methods. +Note that \file{color.sty} is currently the most standard way for +implementing color, and is a required part of \LaTeX{} distributions, +as part of the graphics bundle. + +In the new version of axodraw, we have arranged to have compatibility +with \file{color.sty}, while allowing as much backward compatibility +as we could with the user interface from v.\ 1. We fully rely on +\file{color.sty} for setting color\footnote{Except for certain hard + wired settings in double lines and stroked arrows.}. But to keep +the best of the old methods, we have defined all the named colors that +were defined in the old version, together with a few extra ones. We +have also defined color-setting commands in the style of +\file{colordvi.sty}, but they now apply uniformly to both text and +axodraw graphical objects, and they respect \TeX{} and \LaTeX{} +grouping and environments. + +This results in some changes in behavior in certain situations. We +think the new behavior is more natural from the user's point of view; +but it is a change. + +There are two classes of graphics-drawing command in axodraw. One +class has no explicit color argument, and uses the currently set +color; the line-drawing commands are typical of these. Other commands +have explicit color arguments, and these arguments are named colors. +The named colors are a union of those axodraw defines, with those +defined by \file{color.sty} together with any further ones defined +by the user. + +\subsubsection{How to use colors} + +Axodraw works with named colors --- see Sec.\ \ref{sec:defined.colors} +--- which are a standard set of 68 originally defined by the \program{dvips} +program and the \file{colordvi.sty}, plus 5 extra colors defined in +axodraw2. (In addition there are several named colors that are +normally defined by default by \file{color.sty}, and that can also +be used.) + +To use them we have several possibilities to specify colors. Which to +use is mostly a matter of user preference or convenience. +\begin{itemize} + +\item The axodraw command \verb+\SetColor{colorname}+: sets the color + to be the named color for everything until the end of the current + environment (or \TeX{} group, as relevant.) The initial default + color is Black, of course. An example: + \begin{center} + \begin{minipage}{4cm} + \SetColor{Red} + Now red is used:\\ + \begin{axopicture}(0,40) + \Line(0,10)(40,30) + \end{axopicture} + \end{minipage} + \begin{minipage}{7cm} + \label{SetColor} + \begin{verbatim} + \SetColor{Red} + Now red is used:\\ + \begin{axopicture}(0,40) + \Line(0,10)(40,30) + \end{axopicture} + \end{verbatim} + \end{minipage} + \end{center} + +\item Completely equivalently, one can use the command + \verb+\color{colorname}+ defined by the standard \file{color.sty} + package, with any of its options, e.g., \verb+\color{Red}+ or + \verb+\color[rgb]{1,0,0}+. In fact \verb+\SetColor+ is now a + synonym for \verb+\color+, retained for backward compatibility. + +\item The named colors defined by axodraw2 are listed in Sec.\ + \ref{sec:defined.colors}. Extra ones can be defined by axodraw2's + \verb+\newcolor+ command. + +\item For each of the named colors defined by axodraw2 (and others + defined by the use of the \verb+\newcolor+ command), there is a + macro whose name is ``text'' followed by the color name, e.g., + \verb+\textMagenta+. This behaves just like the corresponding call + to \verb+\SetColor+ or \verb+\color+. Thus we have + \begin{center} + \begin{minipage}{4cm} + \textMagenta + Now magenta is used: \hfill \\ + \begin{axopicture}(0,40) + \Line(0,10)(40,30) + \end{axopicture} + \end{minipage} + \begin{minipage}{7cm} + \label{textName} + \begin{verbatim} + \textMagenta + Now magenta is used:\\ + \begin{axopicture}(0,40) + \Line(0,10)(40,30) + \end{axopicture} + \end{verbatim} + \end{minipage} + \end{center} + These macros correspond to macros defined by the venerable + \file{colordvi.sty} package, but now have what is normally an advantage + that their scope is delimited by the enclosing environment. + \begin{center} + \begin{minipage}{5cm} + Normal text, then + \begin{center} + \Large \bf \color{Blue} + Large, bold blue\\ + \begin{axopicture}(40,20) + \Gluon(0,10)(40,10){4}{4} + \end{axopicture}\\ + \end{center} + And normal text afterward. + \end{minipage} + \begin{minipage}{7.7cm} + \label{scope} + \begin{verbatim} + Normal text, then + \begin{center} + \Large \bf \color{Blue} + Large, bold blue + \begin{axopicture}(40,20) + \Gluon(0,10)(40,10){4}{4} + \end{axopicture}\\ + \end{center} + And normal text afterward. + \end{verbatim} + \end{minipage} + \end{center} + +\item A delimited section of text can be set in a color by using a + macro named by the color (e.g., $\verb+\Red+$): + \begin{center} + \begin{minipage}{6cm} + In the middle of black text, + \textcolor{Red}{red text and + \begin{axopicture}(30,10) + \Gluon(0,5)(30,5){3}{4} + \end{axopicture}\ + gluon% + }. + Then continue \dots + \end{minipage} + \begin{minipage}{7.3cm} + \label{Red} + \begin{verbatim} + In the middle of black text, + \Red{red text and + \begin{axopicture}(30,10) + \Gluon(0,5)(30,5){3}{4} + \end{axopicture}\ + gluon% + }. + Then continue \dots + \end{verbatim} + \end{minipage} + \end{center} + These macros correspond to macros defined by the \file{colordvi.sty} + package, but they now apply to axodraw objects as well. + +\item The same effect, for named colors, can be achieved by + \file{color.sty}'s \verb+\textcolor+ macro. Thus + \verb+\textcolor{Red}{...}+ is equivalent to \verb+\Red{...}+. + +\end{itemize} + +It is also possible to define new named colors, in the CMYK +system. This means that each color is defined by four numbers. New +colors can be introduced with the \verb:\newcolor{#1}{#2}: command as +in \verb:\newcolor{LightRed}{0 0.75 0.7 0}:. This use of this command +defines a named color for use in axodraw, with corresponding macros +\verb:\LightRed: and \verb:\textLightRed{#1}:, and also makes the name +known to \file{color.sty}. (Use of \file{color.sty}'s +\verb:\definecolor: macro is not supported here: it will affect only +normal \LaTeX{} text, but not axodraw objects, and it will fail to +define the extra macros.) + +We define the CMYK values for the named colors in the +\file{axodraw2.sty} file. These override the definitions provided +by \file{color.sty} (in its file dvipsnam.def), which are the same +(at least currently). + +There can be differences in how colors render on different devices. +In principle, there should be compensations made by the driver to +compensate for individual device properties. Our experience is however +that such compensations are not always implemented well enough. Most +notorious are differences between the shades of green on the screen, +on projectors, and on output from a printer. These colors are usually +much too light on a projector and one way to correct this is to +redefine those colors when the output is prepared for a projector, +e.g., by use of axodraw's \verb:\newcolor{#1}{#2}: macro. An example +is illustrated by +\begin{center} + \color{green} + \begin{axopicture}(100,20) + \Text(25,15){color.sty's green} + \Line[width=2](0,0)(50,0) + \end{axopicture} +% + \color{Green} + \begin{axopicture}(100,20) + \Text(25,15){axodraw's Green} + \Line[width=2](0,0)(50,0) + \end{axopicture} +\end{center} +coded by +\begin{verbatim} + \color{green} + \begin{axopicture}(100,20) + \Text(25,15){color.sty's green} + \Line[width=2](0,0)(50,0) + \end{axopicture} +% + \color{Green} + \begin{axopicture}(100,20) + \Text(25,15){axodraw's Green} + \Line[width=2](0,0)(50,0) + \end{axopicture} +\end{verbatim} +On a typical screen or projector, we find that the two greens are +quite distinct, the ``green'' being much lighter than the +``Green''\footnote{The ``green'' is defined in the RGB scheme from the + values $(0,1,0)$, while ``Green'' is defined in the CMYK scheme from + the values $(1,0,1,0)$.}. But on the paper output from our +printers, they give close results. + + + +\subsubsection{Defined named colors} +\label{sec:defined.colors} + +The first set of predefined colors are those defined by dvips (and +defined in \file{colordvi.sty}, or in \file{color.sty} with the +use of both of its usenames and dvipsnames options). They are +\begin{quote} +\sloppy +\GreenYellow{GreenYellow}, +\Yellow{Yellow}, +\Goldenrod{Goldenrod}, +\Dandelion{Dandelion}, +\Apricot{Apricot}, +\Peach{Peach}, +\Melon{Melon}, +\YellowOrange{YellowOrange}, +\Orange{Orange}, +\BurntOrange{BurntOrange}, +\Bittersweet{Bittersweet}, +\RedOrange{RedOrange}, +\Mahogany{Mahogany}, +\Maroon{Maroon}, +\BrickRed{BrickRed}, +\Red{Red}, +\OrangeRed{OrangeRed}, +\RubineRed{RubineRed}, +\WildStrawberry{WildStrawberry}, +\Salmon{Salmon}, +\CarnationPink{CarnationPink}, +\Magenta{Magenta}, +\VioletRed{VioletRed}, +\Rhodamine{Rhodamine}, +\Mulberry{Mulberry}, +\RedViolet{RedViolet}, +\Fuchsia{Fuchsia}, +\Lavender{Lavender}, +\Thistle{Thistle}, +\Orchid{Orchid}, +\DarkOrchid{DarkOrchid}, +\Purple{Purple}, +\Plum{Plum}, +\Violet{Violet}, +\RoyalPurple{RoyalPurple}, +\BlueViolet{BlueViolet}, +\Periwinkle{Periwinkle}, +\CadetBlue{CadetBlue}, +\CornflowerBlue{CornflowerBlue}, +\MidnightBlue{MidnightBlue}, +\NavyBlue{NavyBlue}, +\RoyalBlue{RoyalBlue}, +\Blue{Blue}, +\Cerulean{Cerulean}, +\Cyan{Cyan}, +\ProcessBlue{ProcessBlue}, +\SkyBlue{SkyBlue}, +\Turquoise{Turquoise}, +\TealBlue{TealBlue}, +\Aquamarine{Aquamarine}, +\BlueGreen{BlueGreen}, +\Emerald{Emerald}, +\JungleGreen{JungleGreen}, +\SeaGreen{SeaGreen}, +\Green{Green}, +\ForestGreen{ForestGreen}, +\PineGreen{PineGreen}, +\LimeGreen{LimeGreen}, +\YellowGreen{YellowGreen}, +\SpringGreen{SpringGreen}, +\OliveGreen{OliveGreen}, +\RawSienna{RawSienna}, +\Sepia{Sepia}, +\Brown{Brown}, +\Tan{Tan}, +\Gray{Gray}, +\Black{Black}, +White. +\end{quote} +In addition \file{axodraw2.sty} defines the following extra colors: +\begin{quote} +\LightYellow{LightYellow}, +\LightRed{LightRed}, +\LightBlue{LightBlue}, +\LightGray{LightGray}, +\VeryLightBlue{VeryLightBlue}. +\end{quote} + +Note that \file{color.sty} by default also defines a set of other +named colors: black, white, red, green, blue, cyan, magenta, and +yellow (with purely lower-case names). Depending on properties of +your screen, projector or printer, these may or may not agree with the +similarly named axodraw colors (which have capitalized names). These +names can also be used in the \verb+\SetColor+ and \verb+\color+ +commands and for color names to those axodraw commands that take named +colors for arguments. + + +%\subsection{Background issues on color} +%\label{sec:color.issues} + + + + +%>>#] Colors : +%>>#[ Some examples : + +\section{Some examples} +\label{sec:examples} + +\subsection{A Feynman diagram} + +When computing the singlet part of structure functions in polarized Deep +Inelastic Scattering one approach is to use spin two currents to determine +all anomalous dimensions. At the three loop level this can give diagrams +like the following: +\begin{center} +\begin{axopicture}{(200,140)(0,0)} +\SetArrowStroke{0.5} +\SetArrowScale{0.8} +\Photon(7,70)(37,70){4}{3} +\Photon(7,70)(37,70){-4}{3} +\GluonArc(70,70)(30,90,270){3}{10} +\Line[arrow](100,100)(70,100) +\Line[arrow](130,100)(100,100) +\Line[arrow,arrowpos=0.25](70,100)(130,40) +\Line[arrow](100,40)(70,40) +\Line[arrow](130,40)(100,40) +\Line[arrow,arrowpos=0.75](70,40)(130,100) +\GluonArc(130,70)(30,270,450){3}{10} +\Photon(163,70)(193,70){4}{3} +\Photon(163,70)(193,70){-4}{3} +\Gluon(100,100)(100,130){3}{4} +\Gluon(100,40)(100,10){3}{4} +\Vertex(37,70){2} +\Vertex(163,70){2} +\Vertex(70,100){2} +\Vertex(70,40){2} +\Vertex(130,100){2} +\Vertex(130,40){2} +\Vertex(100,100){2} +\Vertex(100,40){2} +\end{axopicture} +\end{center} +for which the code is: +\begin{verbatim} + \begin{center} \begin{axopicture}{(200,140)(0,0)} + \SetArrowStroke{0.5} \SetArrowScale{0.8} + \Photon(7,70)(37,70){4}{3} + \Photon(7,70)(37,70){-4}{3} + \GluonArc(70,70)(30,90,270){3}{10} + \Line[arrow](100,100)(70,100) \Line[arrow](130,100)(100,100) + \Line[arrow,arrowpos=0.25](70,100)(130,40) + \Line[arrow](100,40)(70,40) \Line[arrow](130,40)(100,40) + \Line[arrow,arrowpos=0.75](70,40)(130,100) + \GluonArc(130,70)(30,270,450){3}{10} + \Photon(163,70)(193,70){4}{3} + \Photon(163,70)(193,70){-4}{3} + \Gluon(100,100)(100,130){3}{4} + \Gluon(100,40)(100,10){3}{4} + \Vertex(37,70){2} \Vertex(163,70){2} \Vertex(70,100){2} + \Vertex(70,40){2} \Vertex(130,100){2} \Vertex(130,40){2} + \Vertex(100,100){2} \Vertex(100,40){2} + \end{axopicture} \end{center} +\end{verbatim} +The diagrams can become a bit more complicated when more lines meet in a +single vertex. One could compose some lines from straight lines and arcs, +but in this case we selected some B\'ezier curves. The result is +\begin{center} +\begin{axopicture}{(200,140)(0,0)} +\SetArrowStroke{0.5} +\SetArrowScale{0.8} +\Photon(7,70)(40,70){4}{3} +\Photon(7,70)(40,70){-4}{3} +\GluonArc(70,70)(30,180,270){3}{5} +\Bezier[arrow](100,100)(55,100)(40,95)(40,70) +\Line[arrow](130,100)(100,100) +\Bezier[arrow,arrowpos=0.37](40,70)(110,70)(130,70)(130,40) +\Line[arrow](100,40)(70,40) +\Line[arrow](130,40)(100,40) +\Line[arrow,arrowpos=0.75](70,40)(130,100) +\GluonArc(130,70)(30,270,450){3}{10} +\Photon(163,70)(193,70){4}{3} +\Photon(163,70)(193,70){-4}{3} +\Gluon(100,100)(100,130){3}{4} +\Gluon(100,40)(100,10){3}{4} +\Vertex(40,70){2} +\Vertex(163,70){2} +\Vertex(70,40){2} +\Vertex(130,100){2} +\Vertex(130,40){2} +\Vertex(100,100){2} +\Vertex(100,40){2} +\end{axopicture} +\end{center} +for which the code is: +\begin{verbatim} + \begin{center} + \begin{axopicture}{(200,140)(0,0)} + \SetArrowStroke{0.5} \SetArrowScale{0.8} + \Photon(7,70)(40,70){4}{3} + \Photon(7,70)(40,70){-4}{3} + \GluonArc(70,70)(30,180,270){3}{5} + \Bezier[arrow](100,100)(55,100)(40,95)(40,70) + \Line[arrow](130,100)(100,100) + \Bezier[arrow,arrowpos=0.37](40,70)(100,70)(130,70)(130,40) + \Line[arrow](100,40)(70,40) \Line[arrow](130,40)(100,40) + \Line[arrow,arrowpos=0.75](70,40)(130,100) + \GluonArc(130,70)(30,270,450){3}{10} + \Photon(163,70)(193,70){4}{3} + \Photon(163,70)(193,70){-4}{3} + \Gluon(100,100)(100,130){3}{4} \Gluon(100,40)(100,10){3}{4} + \Vertex(40,70){2} \Vertex(163,70){2} \Vertex(70,40){2} + \Vertex(130,100){2} \Vertex(130,40){2} \Vertex(100,100){2} + \Vertex(100,40){2} + \end{axopicture} + \end{center} +\end{verbatim} + +%\subsection{A flowchart} + +%\subsection{A histogram} + +\subsection{A diagrammatic equation} + +This example is from ref~\cite{twopap}. The equations in that paper were +rather untransparent, because each Feynman diagram represents a complicated +two loop integral and to solve these integrals one needed many different +recursion relations in terms of the powers of the propagators. We defined a +number of macro's for the diagrams, each containing one picture. Here are +three of them: + +\begin{verbatim} + \def\TAA(#1,#2,#3,#4,#5,#6){ + \raisebox{-19.1pt}{ \hspace{-12pt} + \begin{axopicture}{(50,39)(0,-4)} + \SetScale{0.5}\SetColor{Blue}% + \CArc(40,35)(25,90,270) \CArc(60,35)(25,270,90) + \Line(40,60)(60,60) \Line(40,10)(60,10) \Line(50,10)(50,60) + \Line(0,35)(15,35) \Line(85,35)(100,35) + \SetColor{Black}\SetPFont{Helvetica}{14}% + \PText(55,39)(0)[lb]{#5} \PText(55,36)(0)[lt]{#6} + \PText(35,62)(0)[rb]{#1} \PText(65,62)(0)[lb]{#2} + \PText(65,8)(0)[lt]{#3} \PText(35,8)(0)[rt]{#4} + \SetColor{Red} \SetWidth{3} + \Line(50,35)(50,60) \Line(40,60)(50,60) + \CArc(40,35)(25,90,180) \Vertex(50,60){1.3} + \end{axopicture} + \hspace{-12pt} + } + } +\end{verbatim} +\def\TAA(#1,#2,#3,#4,#5,#6){ + \raisebox{-18.1pt}{ \hspace{-12pt} + \begin{axopicture}{(50,39)(0,-4)} + \SetScale{0.5}\SetColor{Blue}% + \CArc(40,35)(25,90,270) \CArc(60,35)(25,270,90) + \Line(40,60)(60,60) \Line(40,10)(60,10) \Line(50,10)(50,60) + \Line(0,35)(15,35) \Line(85,35)(100,35) + \SetColor{Black}\SetPFont{Helvetica}{14}% + \PText(55,39)(0)[lb]{#5} \PText(55,36)(0)[lt]{#6} + \PText(35,62)(0)[rb]{#1} \PText(65,62)(0)[lb]{#2} + \PText(65,8)(0)[lt]{#3} \PText(35,8)(0)[rt]{#4} + \SetColor{Red} \SetWidth{3} + \Line(50,35)(50,60) \Line(40,60)(50,60) + \CArc(40,35)(25,90,180) \Vertex(50,60){1.3} + \end{axopicture} + \hspace{-12pt} + } +} +\begin{verbatim} + \def\TABs(#1,#2,#3,#4,#5){ + \raisebox{-18.1pt}{ \hspace{-12pt} + \begin{axopicture}{(50,39)(0,-4)} + \SetScale{0.5}\SetColor{Blue}% + \CArc(40,35)(25,90,270) \CArc(60,35)(25,270,90) + \Line(40,60)(60,60) \Line(40,10)(60,10) \Line(50,10)(50,60) + \Line(0,35)(15,35) \Line(85,35)(100,35) + \SetColor{Black}\SetPFont{Helvetica}{14}% + \PText(55,38)(0)[l]{#5} + \PText(35,62)(0)[rb]{#1} \PText(65,62)(0)[lb]{#2} + \PText(65,8)(0)[lt]{#3} \PText(35,8)(0)[rt]{#4} + \SetColor{Red} \SetWidth{3} + \Line(50,10)(50,60) \Vertex(50,60){1.3} + \Line(40,60)(50,60) \CArc(40,35)(25,90,180) + \end{axopicture} + \hspace{-12pt} + } + } +\end{verbatim} +\def\TABs(#1,#2,#3,#4,#5){ + \raisebox{-18.1pt}{ \hspace{-12pt} + \begin{axopicture}{(50,39)(0,-4)} + \SetScale{0.5}\SetColor{Blue}% + \CArc(40,35)(25,90,270) \CArc(60,35)(25,270,90) + \Line(40,60)(60,60) \Line(40,10)(60,10) \Line(50,10)(50,60) + \Line(0,35)(15,35) \Line(85,35)(100,35) + \SetColor{Black}\SetPFont{Helvetica}{14}% + \PText(55,38)(0)[l]{#5} + \PText(35,62)(0)[rb]{#1} \PText(65,62)(0)[lb]{#2} + \PText(65,8)(0)[lt]{#3} \PText(35,8)(0)[rt]{#4} + \SetColor{Red} \SetWidth{3} + \Line(50,10)(50,60) \Vertex(50,60){1.3} + \Line(40,60)(50,60) \CArc(40,35)(25,90,180) + \end{axopicture} + \hspace{-12pt} + } +} +\begin{verbatim} + \def\TACs(#1,#2,#3,#4,#5){ + \raisebox{-19.1pt}{ \hspace{-12pt} + \begin{axopicture}{(50,39)(0,-4)} + \SetScale{0.5}\SetColor{Blue}% + \CArc(40,35)(25,90,270) \CArc(60,35)(25,270,90) + \Line(40,60)(60,60) \Line(40,10)(60,10) \Line(50,10)(50,60) + \Line(0,35)(15,35) \Line(85,35)(100,35) + \SetColor{Black}\SetPFont{Helvetica}{14}% + \PText(53,38)(0)[l]{#5} + \PText(35,62)(0)[rb]{#1} \PText(65,62)(0)[lb]{#2} + \PText(65,8)(0)[lt]{#3} \PText(35,8)(0)[rt]{#4} + \SetColor{Red} \SetWidth{3} + \Line(40,60)(50,60) \CArc(40,35)(25,90,180) + \end{axopicture} + \hspace{-12pt} + } + } +\end{verbatim} +\def\TACs(#1,#2,#3,#4,#5){ + \raisebox{-19.1pt}{ \hspace{-12pt} + \begin{axopicture}{(50,39)(0,-4)} + \SetScale{0.5}\SetColor{Blue}% + \CArc(40,35)(25,90,270) \CArc(60,35)(25,270,90) + \Line(40,60)(60,60) \Line(40,10)(60,10) \Line(50,10)(50,60) + \Line(0,35)(15,35) \Line(85,35)(100,35) + \SetColor{Black}\SetPFont{Helvetica}{14}% + \PText(53,38)(0)[l]{#5} + \PText(35,62)(0)[rb]{#1} \PText(65,62)(0)[lb]{#2} + \PText(65,8)(0)[lt]{#3} \PText(35,8)(0)[rt]{#4} + \SetColor{Red} \SetWidth{3} + \Line(40,60)(50,60) \CArc(40,35)(25,90,180) + \end{axopicture} + \hspace{-12pt} + } +} +and together with two extra little macro's +\begin{verbatim} +\def\plus{\!+\!} +\def\minus{\!-\!} +\end{verbatim} +\def\plus{\!+\!} +\def\minus{\!-\!} +the equations became rather transparent and easy to program. This is the +code +\begin{verbatim} + \begin{eqnarray} + \TAA({n,m},1,1,1,1,1) & = & \frac{1}{\tilde{N}\plus 5\plus n\minus + m\minus D}\ (\ n\ \ \TAA({n+1,m},0,1,1,1,1) + \ \ -n\ \ \TACs({n+1,m},1,1,1,1) \\ & & + +\ \ \TAA({n,m},1,0,2,1,1) + \ \ -\ \ \TABs({n,m},1,1,2,1) + \ \ +m\ \ \TACs({n,m-1},1,1,1,1) + \ \ -m\ \ \TABs({n,m-1},1,1,1,1)\ \ \ ) \, .\nonumber + \end{eqnarray} +\end{verbatim} +and the equation becomes +\begin{eqnarray} + \TAA({n,m},1,1,1,1,1) & = & \frac{1}{\tilde{N}\plus 5\plus n\minus + m\minus D}\ (\ n\ \ \TAA({n+1,m},0,1,1,1,1) + \ \ -n\ \ \TACs({n+1,m},1,1,1,1) \\ & & + +\ \ \TAA({n,m},1,0,2,1,1) + \ \ -\ \ \TABs({n,m},1,1,2,1) + \ \ +m\ \ \TACs({n,m-1},1,1,1,1) + \ \ -m\ \ \TABs({n,m-1},1,1,1,1)\ \ \ ) \, .\nonumber +\end{eqnarray} +The diagrams are actually four-point diagrams. A momentum $P$ flows through +the diagram (the fat red line), but because the method of computation +involves an expansion in terms of this momentum the remaining diagrams are +like two-point functions. Details are in the paper. + +%>>#] Some examples : +%>>#[ Acknowledgements : + +\section*{Acknowledgements} + +JAMV's work is part of the research program of the ``Stichting voor +Fundamenteel Onderzoek der Materie (FOM)'', which is financially supported +by the ``Nederlandse organisatie voor Wetenschappelijke Onderzoek (NWO)'' and +is also supported by the ERC Advanced Grant no.~320651, HEPGAME. +JCC is supported in part by the U.S. Department of Energy under Grant +No.\ DE-SC0008745. + +We like to thank Lucas Theussl for discussions during the development of +axodraw2. + +%>>#] Acknowledgements : +%--#[ Appendix : + +\appendix + +\section{The axohelp program: Information for developers} +\label{sec:axohelp.devel} + +This appendix provides some details on how the axohelp program works. +Most of the information is only relevant to people who wish to modify +or extend axodraw2 and therefore may need to modify axohelp as well. + +The reason for axohelp's existence is that axodraw needs to perform +substantial geometric calculations. When axodraw is used with +pdflatex to produce pdf output directly, suitable calculational +facilities are not available, neither within the PDF language nor +within \LaTeX{} itself. Therefore when axodraw is used under +pdflatex, we use our program axohelp to perform the calculations. + +The mode of operation is as follows. Let us assume that the .tex file +being compiled by the pdflatex program is called paper.tex. When one +issues the command +\begin{verbatim} + pdflatex paper +\end{verbatim} +the reaction of the system is of course to translate all \TeX{} +related objects into a PDF file. Most (but not all) axodraw objects +need non-trivial calculations and hence their +specifications are placed inside a file called paper.ax1. At the end +of the processing \program{pdflatex} will place a message on the screen +that mentions that the user should run the command +\begin{verbatim} + axohelp paper +\end{verbatim} +for the processing of this graphical information. In principle it is +possible to arrange for axohelp to be invoked automatically from +within pdflatex. But for this to be done, the running of general +external commands from pdflatex would have to be enabled. That is a +security risk, and is therefore normally disabled by default for +pdflatex. + +When run, axohelp reads the file paper.ax1, processes the contents, +and produces a file paper.ax2. For each axodraw object, it contains +both the code to be placed in the pdf file, and a copy of the +corresponding specification that was in paper.ax1. + +When pdflatex is run again, it sees that the file paper.ax2 is present +and reads it in to give essentially an array of objects, one for each +processed axodraw object. Then during the processing of the document, +whenever axodraw runs into an axodraw object in need of external +calculation, it determines whether an exactly corresponding +specification was present in the file paper.ax2. If not, it means that +the graphical information in the file paper.tex has changed since the +last run of axohelp and the graphics information is invalidated. In +that case, at the end of the program the message to run axohelp will +be printed again. But if instead there is an exact match between an +axodraw object in the current paper.tex and its specification in +paper.ax2, then the corresponding pdf code will be placed in the PDF +file. If all axodraw commands have a proper match in the paper.ax2 +file, there will be no message in the paper.log file and on the screen +about rerunning axohelp; then the PDF file should contain the correct +information for drawing the axodraw objects (at least if there are no +\TeX{} errors). + +In a sense the situation with axohelp is no different from the use of +makeindex when one prepares a document that contains an index. In that +case one also has to run \LaTeX{} once to prepare a file for the +makeindex program, then run this program which prepares another file +and finally run \LaTeX{} again. Note that if you submit a paper to +arXiv.org, it is likely that their automated system for processing the +file will not run axohelp. So together with paper.tex, you one should +also submit the .ax2 file. + +The complete source of the axohelp program can be found in the file +axohelp.c. This file contains a bit less than 4000 lines of C code but +should translate +without problems with any C compiler --- see Sec.\ \ref{sec:axohelp} +for an appropriate command line on typical Unix-like systems. + +The axohelp program functions as follows: +\begin{enumerate} +\item The .ax1 file is located, space is allocated for it and the complete +file is read and closed again. +\item The input is analysed and split in individual object + specifications, of which a list is made. +\item The list of object specifications is processed one by + one. Before the processing of each object specification, the system + is brought to a default state to avoid that there is a memory of the + previous object. +\item In the .ax2 file, for each object is written both the + corresponding pdf code and a copy of the specification of the object + as was earlier read from the .ax1 file. Before the output for an + object is written to the .ax2 file it is optimized a bit to avoid + superfluous spaces and linefeeds. +\end{enumerate} + +Processing an object from the input involves finding the proper routine for +it and testing that the number of parameters is correct. Some objects have +a special input (like the Curve, DashCurve, Polygon and FilledPolygon +commands). All relevant information is stored in an array of double +precision numbers. Then some generic action is taken (like setting the +linewidth and the color) and the right routine is +called. The output is written to an array of fixed (rather large) length. +Finally the array is optimized and written to file. + +A user who would like to extend the system with new objects should +take the above structure into account. There is an array that gives +the correspondence between axodraw object names and the corresponding +routine in axohelp. For each object, this array also gives the number +of parameters and whether the stroking or non-stroking color space +should be used. + +Naturally, when adding new kinds of object, it is necessary to add new +items to the just-mentioned array, and to add a corresponding +subroutine. One should also try to do all the writing of PDF code by +means of some routines like the ones sitting in the file in the +section named ``PDF utilities''. This is important from the viewpoint +of future action. When new graphical languages will be introduced and +it will be needed to modify axodraw2 such that it can produce code for +those languages, it should be much easier if code in the supporting +axohelp program needs to be changed in as few places as possible. +They form a set of graphics primitives used by other subroutines. +Some of these subroutines in the ``PDF utilities'' section of +axohelp.c have names similar to operators in the postscript language +that perform the same function. + +%--#] Appendix : +%>>#[ bibliography : + +\begin{thebibliography}{9} + +\bibitem{axodraw1} J.A.M. Vermaseren, + Comput.\ Phys.\ Commun.\ {\bf 83} (1994) 45--58 + +\bibitem{jaxodraw1} D. Binosi and L. Theussl, + Comput.\ Phys.\ Commun.\ {\bf 161} (2004) 76--86. + +\bibitem{jaxodraw2} +D. Binosi, J. Collins, C. Kaufhold, L. Theussl, + Comput.\ Phys.\ Commun.\ {\bf 180} (2009) 1709--1715 + +\bibitem{GPL} GNU General Public + License. \url{http://www.gnu.org/copyleft/gpl.html}. + +\bibitem{qcdbook} +J.C. Collins, ``Foundations of Perturbative QCD'' (Cambridge + University Press, 2011). + +\bibitem{twopap} S. Moch and J.A.M. Vermaseren, + Nucl.\ Phys.\ {\bf B573} (2000) 853. + %%CITATION = NUPHA,B573,853;%%. + +\end{thebibliography} + +%>>#] bibliography : +\end{document} + diff --git a/Master/texmf-dist/doc/latex/axodraw2/example.tex b/Master/texmf-dist/doc/latex/axodraw2/example.tex new file mode 100644 index 00000000000..3f87fb80185 --- /dev/null +++ b/Master/texmf-dist/doc/latex/axodraw2/example.tex @@ -0,0 +1,19 @@ +\documentclass{article} +\usepackage{axodraw2} +\begin{document} +Example of Feynman graph made by axodraw2: +\begin{center} + \begin{axopicture}(200,110) + \SetColor{Red} + \Arc[arrow](100,50)(40,0,180) + \Text(100,100)[]{$\alpha P_1 + \beta P_2 + k_\perp$} + \SetColor{Green} + \Arc[arrow](100,50)(40,180,360) + \SetColor{Blue} + \Gluon(0,50)(60,50){5}{4} + \Vertex(60,50){2} + \Gluon(140,50)(200,50){5}{4} + \Vertex(140,50){2} + \end{axopicture} +\end{center} +\end{document} diff --git a/Master/texmf-dist/source/latex/axodraw2/axohelp.c b/Master/texmf-dist/source/latex/axodraw2/axohelp.c new file mode 100644 index 00000000000..ca6b4f64df0 --- /dev/null +++ b/Master/texmf-dist/source/latex/axodraw2/axohelp.c @@ -0,0 +1,3699 @@ +/* + #[ License : + + (C) 2016 by authors: + John Collins (jcc8 at psu dot edu) + Jos Vermaseren (t68 at nikhef dot nl) + + axohelp is free software: you can redistribute it and/or modify it under + the terms of the GNU General Public License as published by the Free + Software Foundation, either version 3 of the License, or (at your option) + any later version. + + axohelp is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. See the GNU General Public License for more + details. + + For the GNU General Public License see <http://www.gnu.org/licenses/>. + + #] License : + #[ Commentary + Modifications : + + This file contains the source code of the axohelp program that is used + together with axopdf.sty and pdflatex. It is a conversion of the postscript + code of axodraw.sty. + + input file contains objects of the type + [number] axohelp input + the output contains objects: + \axo@setObject{label}% + {input data}% + {output} + There may be blank lines and commentary. + + #[ About folds : (this line starts with one blank and two tabs) + + The internals of the file have been organized in folds. + These are defined as a range of lines if which the first and last + lines have a special format. Each starts with any three characters + (may include tabs), then #[ for the start line and #] for the closing + line, then both lines need identical name fields, closed by a colon. + After the colon can be anything. When a fold is closed one should see + only the first line but with the #[ replaced by ## as in + ## About folds : (this line starts with one blank and two tabs) + Folds can be nested. + This fold concept comes originally from the occam compiler for the + transputer in the second half of the 1980's although there it was + implemented differently. It was taken over by the STedi editor in its + current form. The sources of this editor are available from the form + home site: http://www.nikhef.nl/~form + Some people have managed to emulate these folds in editors like emacs + and vim. + + #] About folds : + #] Commentary + Modifications : + #[ Includes : +*/ + +#include <stdio.h> +#include <stdlib.h> +#include <math.h> +#include <string.h> + +/* + #] Includes : + #[ Defines : +*/ + +#define NAME "axohelp" +#define VERSIONDATE "2016 May 23" +#define VERSION 1 +#define SUBVERSION 0 + +#define COMMENTCHAR '%' +#define TERMCHAR ';' + +#define STROKING 0 +#define NONSTROKING 1 + +char **inputs; +long *inputsizes; +double **inargs; +long numinputs = 0; +long inputallocations = 0; +char *axohelp; +FILE *outfile; +char *inname, *outname; +int VerboseFlag = 0; +char outputbuffer[1000000]; +char *outpos; +long numobject; +char *nameobject; +int witharrow = 0; +int identification = 0; + +static int lastlinefeed = 1; +static double axolinewidth = 0.5; +static struct aRRow { + double stroke; + double width; + double length; + double inset; + double where; + double scale; + double aspect; + int type; /* 0: old style arrow; 1: Jaxodraw style arrow */ + int adjust; /* whether the line length should be adjusted */ +} arrow; +double linesep = 0; +int flip = 0; +int clockwise = 0; + +void OutputString(char *); +void ArrowHead(); +void GetArrow(double *); +void BezierArrow(double *); +void ArcSegment(double,double,double); +double *ReadArray(char *,int *,int *); +double *ReadTail(char *,int *); +double LengthBezier(double,double,double,double,double,double,double); + +double M_pi; +double torad; +#define COS(x) cos((x)*torad) +#define SIN(x) sin((x)*torad) +#define TAN(x) tan((x)*torad) + +typedef void (*TFUN)(double *); + +typedef struct { + char *name; + TFUN func; + int numargs; + int colortype; +} KEYWORD; + +void GluonHelp(double *,double); +void DoubleGluonHelp(double *,double,double,double,double); +void GluonCircHelp(double *); +void GluonArcHelp(double *,double,double); +void PhotonHelp(double *,double); +void PhotonArcHelp(double *,double,int); +void ZigZagHelp(double *,double); +void ZigZagArcHelp(double *); +double ComputeDash(double *,double,double); +double ComputeDashCirc(double *,double); + +void ArrowArc(double *); +void ArrowArcn(double *); +void ArrowDoubleArc(double *); +void ArrowLine(double *); +void ArrowDoubleLine(double *); +void AxoArc(double *); +void AxoBezier(double *); +void AxoGluon(double *); +void AxoGluonArc(double *); +void AxoGluonCirc(double *); +void AxoLine(double *); +void AxoPhoton(double *); +void AxoPhotonArc(double *); +void AxoZigZag(double *); +void AxoZigZagArc(double *); +void BezierCurve(double *); +void Boxc(double *); +void CArc(double *); +void DashArrowArc(double *); +void DashArrowArcn(double *); +void DashArrowLine(double *); +void DashArrowDoubleArc(double *); +void DashArrowDoubleLine(double *); +void DashBezier(double *); +void DashCArc(double *); +void DashDoubleArc(double *); +void DashDoubleBezier(double *); +void DashDoubleLine(double *); +void DashDoublePhoton(double *); +void DashDoublePhotonArc(double *); +void DashDoubleZigZag(double *); +void DashDoubleZigZagArc(double *); +void DashGluon(double *); +void DashGluonArc(double *); +void DashGluonCirc(double *); +void DashPhoton(double *); +void DashPhotonArc(double *); +void DashZigZag(double *); +void DashZigZagArc(double *); +void DashLine(double *); +void DoubleArc(double *); +void DoubleBezier(double *); +void DoubleLine(double *); +void DoublePhoton(double *); +void DoublePhotonArc(double *); +void DoubleZigZag(double *); +void DoubleZigZagArc(double *); +void EBox(double *); +void EBoxc(double *); +void ECirc(double *); +void ETri(double *); +void FBox(double *); +void FBoxc(double *); +void FOval(double *); +void FTri(double *); +void GluonArc(double *); +void GluonCirc(double *); +void Gluon(double *); +void Grid(double *); +void LinAxis(double *); +void Line(double *); +void LogAxis(double *); +void Oval(double *); +void Photon(double *); +void PhotonArc(double *); +void Rotate(double *); +void Vertex(double *); +void ZigZag(double *); +void ZigZagArc(double *); + +void Curve(double *,int); +void DashCurve(double *,int); +void Polygon(double *,int,int); + +void Inivars(void); + +KEYWORD commands[] = { + { "Line", Line, 4, STROKING } + ,{ "ArrowArc", ArrowArc, 7, STROKING } + ,{ "ArrowArcn", ArrowArcn, 7, STROKING } + ,{ "ArrowDoubleArc", ArrowDoubleArc, 8, STROKING } + ,{ "ArrowLine", ArrowLine, 6, STROKING } + ,{ "ArrowDoubleLine", ArrowDoubleLine, 7, STROKING } + ,{ "AxoArc", AxoArc, 17, STROKING } + ,{ "AxoBezier", AxoBezier, 19, STROKING } + ,{ "AxoGluon", AxoGluon, 8, STROKING } + ,{ "AxoGluonArc", AxoGluonArc, 10, STROKING } + ,{ "AxoGluonCirc", AxoGluonCirc, 8, STROKING } + ,{ "AxoLine", AxoLine, 15, STROKING } + ,{ "AxoPhoton", AxoPhoton, 8, STROKING } + ,{ "AxoPhotonArc", AxoPhotonArc, 10, STROKING } + ,{ "AxoZigZag", AxoZigZag, 8, STROKING } + ,{ "AxoZigZagArc", AxoZigZagArc, 10, STROKING } + ,{ "Bezier", BezierCurve, 8, STROKING } + ,{ "Boxc", Boxc, 4, STROKING } + ,{ "CArc", CArc, 5, STROKING } + ,{ "DashArrowArc", DashArrowArc, 8, STROKING } + ,{ "DashArrowArcn", DashArrowArcn, 8, STROKING } + ,{ "DashArrowDoubleArc", DashArrowDoubleArc, 9, STROKING } + ,{ "DashArrowDoubleLine",DashArrowDoubleLine,8, STROKING } + ,{ "DashArrowLine", DashArrowLine, 7, STROKING } + ,{ "DashBezier", DashBezier, 9, STROKING } + ,{ "DashCArc", DashCArc, 6, STROKING } + ,{ "DashDoubleArc", DashDoubleArc, 7, STROKING } + ,{ "DashDoubleBezier", DashDoubleBezier, 10, STROKING } + ,{ "DashDoubleLine", DashDoubleLine, 6, STROKING } + ,{ "DashDoublePhoton", DashDoublePhoton, 8, STROKING } + ,{ "DashDoublePhotonArc",DashDoublePhotonArc,10, STROKING } + ,{ "DashDoubleZigZag", DashDoubleZigZag, 8, STROKING } + ,{ "DashDoubleZigZagArc",DashDoubleZigZagArc,10, STROKING } + ,{ "DashGluon", DashGluon, 7, STROKING } + ,{ "DashGluonArc", DashGluonArc, 10, STROKING } + ,{ "DashGluonCirc", DashGluonCirc, 7, STROKING } + ,{ "DashLine", DashLine, 5, STROKING } + ,{ "DashPhoton", DashPhoton, 7, STROKING } + ,{ "DashPhotonArc", DashPhotonArc, 10, STROKING } + ,{ "DashZigZag", DashZigZag, 7, STROKING } + ,{ "DashZigZagArc", DashZigZagArc, 10, STROKING } + ,{ "DoubleArc", DoubleArc, 6, STROKING } + ,{ "DoubleBezier", DoubleBezier, 9, STROKING } + ,{ "DoubleLine", DoubleLine, 5, STROKING } + ,{ "DoublePhoton", DoublePhoton, 7, STROKING } + ,{ "DoublePhotonArc", DoublePhotonArc, 8, STROKING } + ,{ "DoubleZigZag", DoubleZigZag, 7, STROKING } + ,{ "DoubleZigZagArc", DoubleZigZagArc, 8, STROKING } + ,{ "EBox", EBox, 4, STROKING } + ,{ "FBox", FBox, 4, STROKING } + ,{ "FBoxc", FBoxc, 4, STROKING } + ,{ "ECirc", ECirc, 3, STROKING } + ,{ "ETri", ETri, 6, STROKING } + ,{ "FOval", FOval, 5, NONSTROKING } + ,{ "FTri", FTri, 6, NONSTROKING } + ,{ "GluonArc", GluonArc, 7, STROKING } + ,{ "GluonCirc", GluonCirc, 6, STROKING } + ,{ "Gluon", Gluon, 6, STROKING } + ,{ "Grid", Grid, 6, STROKING } + ,{ "LinAxis", LinAxis, 8, STROKING } + ,{ "LogAxis", LogAxis, 7, STROKING } + ,{ "Oval", Oval, 5, STROKING } + ,{ "Photon", Photon, 6, STROKING } + ,{ "PhotonArc", PhotonArc, 7, STROKING } + ,{ "Rotate", Rotate, 7, NONSTROKING } + ,{ "Vertex", Vertex, 3, NONSTROKING } + ,{ "ZigZag", ZigZag, 6, STROKING } + ,{ "ZigZagArc", ZigZagArc, 7, STROKING } +}; + +/* + #] Defines : + #[ SetDefaults : +*/ + +void SetDefaults() +{ + lastlinefeed = 1; + axolinewidth = 0.5; + linesep = 0; + flip = 0; + clockwise = 0; + witharrow = 0; +} + +/* + #] SetDefaults : + #[ PDF utilities : + + These routines are included to make the program more readable and easier + to write. It also allows the easy use of the OutputString routine that + compactifies the output. +*/ + +#define Stroke outpos += sprintf(outpos," S") +#define CloseAndStroke outpos += sprintf(outpos," h S") +#define Fill outpos += sprintf(outpos," f") +#define CloseAndFill outpos += sprintf(outpos," h f") +#define SaveGraphicsState outpos += sprintf(outpos," q") +#define RestoreGraphicsState outpos += sprintf(outpos," Q") + +void Bezier(double x1,double y1,double x2,double y2,double x3,double y3) { + outpos += + sprintf(outpos,"\n %12.3f %12.3f %12.3f %12.3f %12.3f %12.3f c",x1,y1,x2,y2,x3,y3); +} + +void LineTo(double x1,double y1) { + outpos += + sprintf(outpos,"\n %12.3f %12.3f l",x1,y1); +} + +void MoveTo(double x1,double y1) { + outpos += + sprintf(outpos,"\n %12.3f %12.3f m",x1,y1); +} + +void SetLineWidth(double w) { + outpos += + sprintf(outpos," %12.3f w",w); +} + +void SetDashSize(double dashsize,double phase) { + if ( dashsize ) outpos += sprintf(outpos," [%12.3f] %12.3f d",dashsize,phase); + else outpos += sprintf(outpos," [] 0 d"); +} + +void SetTransferMatrix(double x11,double x12,double x21,double x22,double x,double y) +{ + if ( ( fabs(x11-1.) > 0.001 ) || ( fabs(x22-1.) > 0.001 ) + || ( fabs(x12) > 0.001 ) || ( fabs(x21) > 0.001 ) + || ( fabs(x) > 0.001 ) || ( fabs(y) > 0.001 ) ) { + outpos += + sprintf(outpos,"%12.3f %12.3f %12.3f %12.3f %12.3f %12.3f cm\n",x11,x12,x21,x22,x,y); + } +} + +static double BzK; + +void BezierCircle(double r,char *action) +{ + outpos += + sprintf(outpos," %12.3f 0 m %12.3f %12.3f %12.3f %12.3f 0 %12.3f c\n",-r,-r,r*BzK,-r*BzK,r,r); + outpos += + sprintf(outpos," %12.3f %12.3f %12.3f %12.3f %12.3f 0 c\n",r*BzK,r,r,r*BzK,r); + outpos += + sprintf(outpos," %12.3f %12.3f %12.3f %12.3f 0 %12.3f c\n",r,-r*BzK,r*BzK,-r,-r); + outpos += + sprintf(outpos," %12.3f %12.3f %12.3f %12.3f %12.3f 0 c %s\n",-r*BzK,-r,-r,-r*BzK,-r,action); +} + +void BezierOval(double w, double h, char *action) +{ + outpos += + sprintf(outpos," %12.3f 0 m %12.3f %12.3f %12.3f %12.3f 0 %12.3f c\n",-w,-w,h*BzK,-w*BzK,h,h); + outpos += + sprintf(outpos," %12.3f %12.3f %12.3f %12.3f %12.3f 0 c\n",w*BzK,h,w,h*BzK,w); + outpos += + sprintf(outpos," %12.3f %12.3f %12.3f %12.3f 0 %12.3f c\n",w,-h*BzK,w*BzK,-h,-h); + outpos += + sprintf(outpos," %12.3f %12.3f %12.3f %12.3f %12.3f 0 c %s\n",-w*BzK,-h,-w,-h*BzK,-w,action); +} + +void SetGray(double grayscale,int par) +{ + if ( par == STROKING ) { + outpos += sprintf(outpos," %12.3f G",grayscale); + } + else { + outpos += sprintf(outpos," %12.3f g",grayscale); + } +} + +void SetColor(double c, double m, double y, double k,int par) +{ + if ( par == STROKING ) { + outpos += sprintf(outpos," %12.3f %12.3f %12.3f %12.3f K",c,m,y,k); + } + else { + outpos += sprintf(outpos," %12.3f %12.3f %12.3f %12.3f k",c,m,y,k); + } +} + +void SetBackgroundColor(int par) +{ + if ( par == STROKING ) { outpos += sprintf(outpos," 0 0 0 0 K"); } + else { outpos += sprintf(outpos," 0 0 0 0 k"); } +} + +void Rectangle(double x,double y,double w,double h) { + outpos += sprintf(outpos,"\n %12.3f %12.3f %12.3f %12.3f re",x,y,w,h); +} + +void Triangle(double x1,double y1,double x2,double y2,double x3,double y3) { + outpos += + sprintf(outpos,"\n %12.3f %12.3f m %12.3f %12.3f l %12.3f %12.3f l h",x1,y1,x2,y2,x3,y3); +} + +/* + #] PDF utilities : + #[ Service routines : + #[ GetArrow : +*/ + +void GetArrow(double *args) +{ + witharrow = args[7]; + arrow.stroke = args[0]; + arrow.width = args[1]; + arrow.length = args[2]; + arrow.inset = args[3]; + arrow.scale = args[4]; + arrow.aspect = args[5]; + arrow.where = args[6]; + arrow.type = 1; + arrow.adjust = 0; + if ( args[8] ) flip = 1; + if ( witharrow ) { + if ( arrow.length == 0 && arrow.width == 0 ) { + arrow.width = (axolinewidth + 0.7*linesep + 1 ) * 1.2; + if (arrow.width < 2.5) arrow.width = 2.5; + arrow.length = 2*arrow.width*arrow.aspect; + } + else if ( arrow.width == 0 ) { + arrow.width = arrow.length/(2*arrow.aspect); + } + else if ( arrow.length == 0 ) { + arrow.length = 2*arrow.width*arrow.aspect; + } + arrow.width *= arrow.scale; + arrow.length *= arrow.scale; + if ( arrow.where > 1 ) { arrow.where = 1; arrow.adjust = 1; } + if ( arrow.where < 0 ) { arrow.where = 0; arrow.adjust = 1; } + } +} + +/* + #] GetArrow : + #[ ArrowHead : + + Places an arrowhead of a given size at 0 in the +x direction + The size: Full width is 2*size and full length is also 2*size. +*/ + +void ArrowHead() +/* + Jaxodraw style arrows +*/ +{ + int k; + double length; + SaveGraphicsState; + if ( flip ) length = -arrow.length; + else length = arrow.length; + SetDashSize(0,0); + if ( arrow.stroke ) { + SetLineWidth(arrow.stroke); + for (k = 1; k <= 2; k++ ) { + SaveGraphicsState; + MoveTo(length*0.5,0); + LineTo(-length*0.5,arrow.width); + LineTo(-length*0.5+length*arrow.inset,0); + LineTo(-length*0.5,-arrow.width); + if (k == 1) { + SetBackgroundColor(NONSTROKING); + outpos += sprintf(outpos," h f"); + } + else { + outpos += sprintf(outpos," s"); + } + RestoreGraphicsState; + } + } + else { + MoveTo(length*0.5,0); + LineTo(-length*0.5,arrow.width); + LineTo(-length*0.5+length*arrow.inset,0); + LineTo(-length*0.5,-arrow.width); + outpos += sprintf(outpos," h f"); + } + RestoreGraphicsState; +} + +/* + #] ArrowHead : + #[ BezierArrow : + + We compute the length of the curve. + Then we try to find the t value for which holds: + Length(t)/Length(1) = arrow.where +*/ + +void BezierArrow(double *args) +{ + double t,u,x,y,dx,dy,dr,len,tlen,tmin=0,tmax=1.0; + double x1=args[2]-args[0],x2=args[4]-args[0],x3=args[6]-args[0]; + double y1=args[3]-args[1],y2=args[5]-args[1],y3=args[7]-args[1]; + len = LengthBezier(x1,y1,x2,y2,x3,y3,1.0); + t = arrow.where; + tlen = LengthBezier(x1,y1,x2,y2,x3,y3,t); + while ( fabs(tlen/len-arrow.where) > 0.0001 ) { + if ( tlen/len > arrow.where ) { + tmax = t; + t = 0.5*(tmin+t); + } + else { + tmin = t; + t = 0.5*(tmax+t); + } + tlen = LengthBezier(x1,y1,x2,y2,x3,y3,t); + } + u = 1-t; + x = args[0]*u*u*u+(3*args[2]*u*u+(3*args[4]*u+args[6]*t)*t)*t; + y = args[1]*u*u*u+(3*args[3]*u*u+(3*args[5]*u+args[7]*t)*t)*t; + dx = 3*(-args[0]*u*u+args[2]*u*(1-3*t)+args[4]*t*(2-3*t)+args[6]*t*t); + dy = 3*(-args[1]*u*u+args[3]*u*(1-3*t)+args[5]*t*(2-3*t)+args[7]*t*t); + dr = sqrt(dx*dx+dy*dy); + SetTransferMatrix(1,0,0,1,x,y); + SetTransferMatrix(dx/dr,dy/dr,-dy/dr,dx/dr,0,0); + ArrowHead(); +} + +/* + #] BezierArrow : + #[ ArcSegment : +*/ + +void ArcSegment(double r, double phi1, double dphi) +{ + double xphi, d, x, y, phia, phib, x1,y1,x2,y2,x3,y3; + int num, i; + + num = dphi/90.0001+1.; /* number of segments we should use. */ + xphi = dphi/num; /* arc size of each segment */ + d = 4.*TAN(xphi/4.)/3.; /* the magic distance for the control points */ + + x = r*COS(phi1); y = r*SIN(phi1); + MoveTo(x,y); + for ( i = 0; i < num; i++ ) { + phia = phi1+i*xphi; /* Start of segment */ + phib = phia+xphi; /* End of segment */ + x3 = r*COS(phib); y3 = r*SIN(phib); + x1 = x - y*d; y1 = y + x*d; + x2 = x3+y3*d; y2 = y3-x3*d; + + Bezier(x1,y1,x2,y2,x3,y3); + + x = x3; y = y3; + } +} + +/* + #] ArcSegment : + #[ ReadNumber : +*/ + +char *ReadNumber(char *s,double *num) +{ + double x3,minus = 1; + int x1,x2; + while ( *s == '+' || *s == '-' ) { + if ( *s == '-' ) minus = -minus; + s++; + } + x1 = x2 = 0; x3 = 1; + while ( *s <= '9' && *s >= '0' ) { x1 = 10*x1 + *s++ - '0'; } + if ( *s == 0 ) { *num = x1*minus; return(s); } + if ( *s == '.' ) { + s++; + while ( *s >= '0' && *s <= '9' ) { x2 = 10*x2 + *s++ - '0'; x3 *= 10; } + } + *num = minus*((double)x1 + x2/x3); + return(s); +} + +/* + #] ReadNumber : + #[ ReadArray : + + Reads a tail of floats of the type (x1,y1)(x2,y2),...,(xn,yn) or + (x1,y1)(x2,y2),...,(xn,yn) f1 ... fm + The floats may be written as integers. + Normally they are in the format ####.### + In num1 we return the number of coordinates encountered. + In num2 we return the number of extra floats encountered. + The array of the return value should be freed after it has been used. +*/ + +double *ReadArray(char *inbuf, int *num1, int *num2) +{ + int argsize = 0, newsize, num = 0, i; + double *args = 0, *newargs = 0, *extraargs, x, y; + char *s; + *num2 = 0; + s = inbuf; + while ( *s == ' ' || *s == '\t' || *s == '\n' ) s++; + if ( *s == '"' ) { + s++; + while ( *s == ' ' || *s == '\t' || *s == '\n' ) s++; + } + while ( *s == '(' ) { /* We need to read (x,y) */ + s++; + while ( *s == ' ' || *s == '\n' || *s == '\t' ) s++; + s = ReadNumber(s,&x); + while ( *s == ' ' ) s++; + if ( *s != ',' ) { + fprintf(stderr,"%s: Illegal format for array of numbers in object %ld of type %s in file %s\n" + ,axohelp,numobject,nameobject,inname); + free(args); + return(0); + } + s++; + while ( *s == ' ' || *s == '\n' || *s == '\t' ) s++; + s = ReadNumber(s,&y); + while ( *s == ' ' || *s == '\n' || *s == '\t' ) s++; + if ( *s != ')' ) { + fprintf(stderr,"%s: Illegal format for array of numbers in object %ld of type %s in file %s\n" + ,axohelp,numobject,nameobject,inname); + free(args); + return(0); + } + s++; + while ( *s == ' ' ) s++; + num += 2; + if ( num >= argsize ) { + if ( argsize == 0 ) newsize = 20; + else newsize = 2*argsize; + newargs = (double *)malloc(sizeof(double)*newsize); + if ( args == 0 ) { args = newargs; argsize = newsize; } + else { + for ( i = 0; i < argsize; i++ ) newargs[i] = args[i]; + free(args); + args = newargs; argsize = newsize; + } + } + args[num-2] = x; args[num-1] = y; + } + if ( *s == '"' ) s++; + while ( *s == ' ' || *s == '\t' || *s == '\n' ) s++; + *num1 = num/2; + + if ( *s ) { + if ( ( extraargs = ReadTail(s,num2) ) == 0 ) { + return(0); + } + if ( num+*num2 > argsize ) { + newargs = (double *)malloc(sizeof(double)*(num+*num2)); + for ( i = 0; i < num; i++ ) newargs[i] = args[i]; + free(args); + args = newargs; + argsize = num+*num2; + } + for ( i = 0; i < *num2; i++ ) args[num+i] = extraargs[i]; + free(extraargs); + } + return(args); +} + +/* + #] ReadArray : + #[ ReadTail : + + Reads a command tail that consists of floating point numbers in the + notation xxx.yyy or just as integers without even the decimal point. + The output array is allocated and should be returned in a well behaved + program. +*/ + +double *ReadTail(char *buff,int *number) +{ + char *s; + int num = 1, i; + double *outargs; + s = buff; + while ( *s ) { + if ( *s == ' ' || *s == '\t' || *s == '\n' ) { + num++; *s++ = 0; + while ( *s == ' ' || *s == '\t' || *s == '\n' ) *s++ = 0; + } + else s++; + } + outargs = (double *)malloc(num*sizeof(double)); + s = buff; + for ( i = 0; i < num; i++ ) { + while ( *s == 0 ) s++; + s = ReadNumber(s,outargs+i); + if ( *s == 'p' && s[1] == 't' ) s += 2; + if ( *s != 0 ) { + fprintf(stderr,"%s: Illegal format for number in command %ld (%s) in file %s.\n" + ,axohelp,numobject,nameobject,inname); + free(outargs); + return(0); + } + } + *number = num; + return(outargs); +} + +/* + #] ReadTail : + #[ DoCurve : + + Interpolation curve expressed as a Bezier curve. +*/ + +void DoCurve(double x0, double y0, double x1, double y1, + double x2, double y2, double x3, double y3) +{ + double xx1, yy1, xx2, yy2; + xx1 = (2*x1+x2)/3; + yy1 = ((y1-y0)/(x1-x0)*(x2-x0)+(y2-y0)/(x2-x0)*(x1-x0)+y1+2*y0)/3; + xx2 = (x1+2*x2)/3; + yy2 = ((y2-y3)/(x2-x3)*(x1-x3)+(y1-y3)/(x1-x3)*(x2-x3)+y2+2*y3)/3; + + Bezier(xx1,yy1,xx2,yy2,x2,y2); +} + +/* + #] DoCurve : + #[ LengthBezier : + + Routine computes the length of a Bezier curve. + Method: + x = x0*(1-t)^3+3*x1*t*(1-t)^2+3*x2*t^2*(1-t)+x3*t^3 + y = y0*(1-t)^3+3*y1*t*(1-t)^2+3*y2*t^2*(1-t)+y3*t^3 + We assume that x0=y0=0. (Hence call with x1-x0 etc) + --> dx/dt = 3*x1*(1-t)*(1-3*t)+3*x2*t*(2-3*t)+3*x3*t^2 + = 3*(x1+2*t*(x2-2*x1)+t^2*(x3-3*x2+3*x1)) + --> L = int_0^1 dt * sqrt(dx^2+dy^2) + We use ordinary Gaussian quadratures over the domain -1,...,+1 + + We have here quadratures for 8, 16 or 32 points. + For the moment we use the 16 point quadrature. It seems to work well. + The numbers were taken from Abramowitz and Stegun. +*/ + +typedef struct quad { + double x; + double w; +} QUAD; + +QUAD g8[4] = { + { 0.183434642495650, 0.362683783378362 } + ,{ 0.525532409916329, 0.313706645877887 } + ,{ 0.796666477413627, 0.222381034453374 } + ,{ 0.960289856497536, 0.101228536290376 } + }; +QUAD g16[8] = { + { 0.095012509837637440185, 0.189450610455068496285 } + ,{ 0.281603550779258913230, 0.182603415044923588867 } + ,{ 0.458016777657227386342, 0.169156519395002538189 } + ,{ 0.617876244402643748447, 0.149595988816576732081 } + ,{ 0.755404408355003033895, 0.124628971255533872052 } + ,{ 0.865631202387831743880, 0.095158511682492784810 } + ,{ 0.944575023073232576078, 0.062253523938647892863 } + ,{ 0.989400934991649932596, 0.027152459411754094852 } + }; +QUAD g32[16] = { + { 0.048307665687738316235, 0.096540088514727800567 } + ,{ 0.144471961582796493485, 0.095638720079274859419 } + ,{ 0.239287362252137074545, 0.093844399080804565639 } + ,{ 0.331868602282127649780, 0.091173878695763884713 } + ,{ 0.421351276130635345364, 0.087652093004403811143 } + ,{ 0.506899908932229390024, 0.083311924226946755222 } + ,{ 0.587715757240762329041, 0.078193895787070306472 } + ,{ 0.663044266930215200975, 0.072345794108848506225 } + ,{ 0.732182118740289680387, 0.065822222776361846838 } + ,{ 0.794483795967942406963, 0.058684093478535547145 } + ,{ 0.849367613732569970134, 0.050998059262376176196 } + ,{ 0.896321155766052123965, 0.042835898022226680657 } + ,{ 0.934906075937739689171, 0.034273862913021433103 } + ,{ 0.964762255587506430774, 0.025392065309262059456 } + ,{ 0.985611511545268335400, 0.016274394730905670605 } + ,{ 0.997263861849481563545, 0.007018610009470096600 } + }; + +double LengthBezier(double x1,double y1,double x2,double y2,double x3,double y3,double tmax) +{ + double xa = 3*x1, xb = 6*(x2-2*x1), xc = 3*(x3-3*x2+3*x1); + double ya = 3*y1, yb = 6*(y2-2*y1), yc = 3*(y3-3*y2+3*y1); + double t, sum = 0, dx, dy; + int j; + + for ( j = 0; j < 8; j++ ) { + t = 0.5*(1+g16[j].x)*tmax; + dx = xa+t*(xb+t*xc); + dy = ya+t*(yb+t*yc); + sum += 0.5*g16[j].w*sqrt(dx*dx+dy*dy); + t = 0.5*(1-g16[j].x)*tmax; + dx = xa+t*(xb+t*xc); + dy = ya+t*(yb+t*yc); + sum += 0.5*g16[j].w*sqrt(dx*dx+dy*dy); + } + return(sum*tmax); +} + +/* + #] LengthBezier : + #] Service routines : + #[ ScanForObjects : + + Routine reads the input buffer and sets up pointers to the commands. + Basically it is responsible for checking the input syntax and making + sure all commands will have the proper number of arguments. +*/ + +long ScanForObjects(char *buffer) +{ + char *s = buffer, *t; + if ( *s == COMMENTCHAR ) { while ( *s && *s != '\n' ) s++; } + while ( *s ) { /* here we are to look for a new command */ + if ( *s != '[' ) { /* for the case of the very first character */ + while ( *s && ( *s != '[' || ( *s == '[' && s[-1] == '\\' ) ) ) { + if ( *s == ' ' || *s == '\n' ) { + while ( *s == ' ' || *s == '\n' ) s++; /* Skip blank lines */ + } + else if ( *s == COMMENTCHAR && s[-1] != '\\' ) { + while ( *s && *s != '\n' ) s++; + } + else s++; + } + } + if ( *s == 0 ) break; +/* + if everything is correct we are now on a [ + a: look for matching ] in the same line. This defines the label. +*/ + t = s+1; + while ( *t && *t != ']' && *t != '\n' && ( *t != COMMENTCHAR || + ( *t == COMMENTCHAR && t[-1] != '\\' ) ) ) t++; + if ( *t == 0 ) { + fprintf(stderr,"%s: irregular end of file %s.\n",axohelp,inname); + return(-1); + } + else if ( *t == '\n' ) { + fprintf(stderr,"%s: a label in file %s should inside a single line.\n",axohelp,inname); + return(-1); + } + else if ( *t == COMMENTCHAR ) { + fprintf(stderr,"%s: illegal comment character inside a label in file %s.\n",axohelp,inname); + return(-1); + } + else if ( *t != ']' ) { + fprintf(stderr,"%s: internal error reading a label in file %s.\n",axohelp,inname); + return(-1); + } +/* + Store the address of this command +*/ + if ( numinputs >= inputallocations ) { /* we need more space */ + long newnum, i; + char **newadd; + if ( inputallocations == 0 ) { newnum = 100; } + else { newnum = 2*inputallocations; } + if ( ( newadd = (char **)malloc(newnum*sizeof(char *)) ) == 0 ) { + fprintf(stderr,"%s: memory error reading file %s\n",axohelp,inname); + return(-1); + } + for ( i = 0; i < inputallocations; i++ ) { newadd[i] = inputs[i]; } + if ( inputs != 0 ) free(inputs); + inputs = newadd; + inputallocations = newnum; + } + inputs[numinputs++] = s; +/* + Now scan for the first comment character. That is the end of the object. +*/ + while ( *t && ( *t != TERMCHAR || ( *t == TERMCHAR && t[-1] == '\\' ) ) + && *t != '[' ) t++; + if ( *t != '[' ) { + while ( t[-1] == ' ' || t[-1] == '\n' ) t--; + *t++ = 0; + } + s = t; + } + return(numinputs); +} + +/* + #] ScanForObjects : + #[ ReadInput : +*/ + +char *ReadInput(char *filename) +{ + FILE *finput; + long filesize, num; + char *buffer; + if ( ( finput = fopen(filename,"r") ) == 0 ) { + fprintf(stderr,"%s: Cannot open file %s\n",axohelp,filename); + exit(-1); + } + if ( ( fseek(finput,0,SEEK_END) != 0 ) + || ( ( filesize = ftell(finput) ) < 0 ) + || ( fseek(finput,0,SEEK_SET) != 0 ) ) { + fprintf(stderr,"%s: File error in file %s\n",axohelp,filename); + exit(-1); + } + if ( ( buffer = malloc((filesize+1)*sizeof(char)) ) == 0 ) { + fprintf(stderr,"%s: Error allocating %ld bytes of memory",axohelp,filesize+1); + exit(-1); + } +/* + Assume character in file is 1 byte, which is true for all cases + we currently encounter. +*/ + num = fread( buffer, 1, filesize, finput ); + if ( ferror(finput) ) { + fprintf(stderr,"%s: Error reading file %s\n",axohelp,filename); + exit(-1); + } +/* + By definition, fread reads ALL the items specified, or it gets to + end-of-file, or there is an error. + It returns the actual number of items successfully read, which + is less than the number given in the 3rd argument ONLY if a + read error or end-of-file is encountered. + We have already tested for an error. + But num could legitimately be less than filesize, because of + translation of CRLF to LF (on MSWindows with MSWindows text file). +*/ + buffer[num] = 0; + fclose(finput); + return(buffer); +} + +/* + #] ReadInput : + #[ CleanupOutput : +*/ + +void CleanupOutput(char *str) +{ + char *s, *t; + int period = 0; + s = t = str; + while ( *s && *s != '}' ) { + if ( *s == '\n' ) *s = ' '; + if ( ( *s == ' ' || *s == '\n' ) && ( s[1] == ' ' || s[1] == '\n' ) ) s++; + else *t++ = *s++; + } + while ( *s ) *t++ = *s++; + *t = 0; + s = t = str; + while ( *s ) { + if ( *s == '.' ) { period = 1; *t++ = *s++; } + else if ( *s == '-' && s[1] == '0' && s[2] == ' ' ) { s++; } + else if ( *s <= '9' && *s >= '0' ) { *t++ = *s++; } + else if ( *s == '\n' && ( t > str && t[-1] == '\n' ) ) { s++; } + else if ( period ) { + while ( t > str && t[-1] == '0' ) t--; + if ( t > str && t[-1] == '.' ) t--; + while ( *s == ' ' && s[1] == ' ' ) s++; + period = 0; *t++ = *s++; + } + else if ( *s == ' ' && s[1] == ' ' ) s++; + else { + period = 0; *t++ = *s++; + } + } + *t = 0; + s = t = str; + while ( *s ) { + if ( *s == '-' && s[1] == '0' && s[2] == ' ' ) { s++; } + else *t++ = *s++; + } + *t = 0; +} + +/* + #] CleanupOutput : + #[ DoOneObject : +*/ + +int DoOneObject(char *cinput) +{ + int num, i, num1, num2; + char *s, *t, *StartClean; + double *argbuf = 0; + SetDefaults(); + s = cinput; while ( *s != '[' ) s++; + s++; t = s; while ( *t != ']' ) t++; + *t++ = 0; while ( *t == ' ' || *t == '\t' || *t == '\n' ) t++; + outpos = outputbuffer; + outpos += sprintf(outpos,"\\axo@setObject{%s}%%\n{%s%c}%%\n{",s,t,TERMCHAR); + if ( *s == '0' && s[1] == ']' ) { +/* + The identification line. + In due time we might add more options here. +*/ + if ( strcmp(nameobject,"AxodrawWantsPDF") == 0 ) { + identification = 1; + outpos += sprintf(outpos,"Axohelp version %d.%d. PDF output.}",VERSION,SUBVERSION); + fprintf(outfile,"%s",outputbuffer); + return(0); + } + else { + fprintf(stderr,"%s: Illegal request in identification string [0]: %s\n" + ,axohelp,nameobject); + if ( argbuf ) free(argbuf); + return(-1); + } + } +/* + if ( identification == 0 ) { + fprintf(stderr,"%s: No identification string. Check versions.\n",axohelp); + if ( argbuf ) free(argbuf); + return(-1); + } +*/ + StartClean = outpos; + + nameobject = t; while ( *t != ' ' && *t != '\t' && *t != '\n' && *t ) t++; + *t++ = 0; while ( *t == ' ' || *t == '\t' || *t == '\n' ) t++; +/* + Now nameobject is the name of the command and t points at the first parameter. +*/ + if ( ( strcmp(nameobject,"Curve") == 0 ) + || ( strcmp(nameobject,"Polygon") == 0 ) + || ( strcmp(nameobject,"FilledPolygon") == 0 ) ) { +/* + #[ Curve,Polygons : +*/ + if ( ( argbuf = ReadArray(t,&num1,&num2) ) == 0 ) return(-1); + if ( num2-1 != 0 ) { + fprintf(stderr,"%s: Command %s should have no extra numbers in %s.\n", + axohelp,nameobject,inname); + free(argbuf); + return(-1); + } + else { +/* + First some 'fixed' operations to set the state right + 1: scale 2: linewidth 3: color + Then the function. + Finally the trailer and cleanup. +*/ + axolinewidth = argbuf[2*num1+num2-1]; + SetLineWidth(axolinewidth); + if ( strcmp(nameobject,"Curve") == 0 ) { + Curve(argbuf,num1); + } + else if ( strcmp(nameobject,"Polygon") == 0 ) { + Polygon(argbuf,num1,0); + } + else if ( strcmp(nameobject,"FilledPolygon") == 0 ) { + Polygon(argbuf,num1,1); + } + free(argbuf); + } +/* + #] Curve,Polygons : +*/ + } + else if ( strcmp(nameobject,"DashCurve") == 0 ) { +/* + #[ DashCurve : +*/ + if ( ( argbuf = ReadArray(t,&num1,&num2) ) == 0 ) return(-1); + if ( num2 != 2 ) { + fprintf(stderr,"%s: Command %s does not have two numbers after the coordinates\n in file %s.\n", + axohelp,nameobject,inname); + free(argbuf); + return(-1); + } + else { +/* + First some 'fixed' operations to set the state right + 1: scale 2: linewidth 3: color + Then the function. + Finally the trailer and cleanup. +*/ + axolinewidth = argbuf[2*num1+num2-1]; + SetLineWidth(axolinewidth); + DashCurve(argbuf,num1); + free(argbuf); + } +/* + #] DashCurve : +*/ + } + else { +/* + #[ Regular command : +*/ + if ( ( argbuf = ReadTail(t,&num) ) == 0 ) return(-1); + for ( i = 0; i < sizeof(commands)/sizeof(KEYWORD); i++ ) { + if ( strcmp(nameobject,commands[i].name) == 0 ) { + if ( num == commands[i].numargs+1 ) { +/* + First some 'fixed' operations to set the state right + 1: scale 2: linewidth 3: color + Then the function. + Finally the trailer and cleanup. +*/ + axolinewidth = argbuf[num-1]; + SetLineWidth(axolinewidth); + (*(commands[i].func))(argbuf); + free(argbuf); + break; + } + else { + fprintf(stderr,"%s: Command %s should have %d(+1) arguments in %s.\n" + ,axohelp,nameobject,commands[i].numargs,inname); + free(argbuf); + return(-1); + } + } + } +/* + #] Regular command : +*/ + if ( i >= sizeof(commands)/sizeof(KEYWORD) ) { + fprintf(stderr,"%s: Command %s not recognized in file %s.\n", + axohelp,nameobject,inname); + free(argbuf); + return(-1); + } + } + outpos += sprintf(outpos,"}\n"); + CleanupOutput(StartClean); + fprintf(outfile,"%s",outputbuffer); + return(0); +} + +/* + #] DoOneObject : + #[ PrintHelp : +*/ + +void PrintHelp(char *name) +{ + fprintf(stderr,"This is %s v. %d.%d of %s\n", NAME, VERSION, SUBVERSION, VERSIONDATE); + fprintf(stderr,"Proper use is: %s [-h] [-v] filename\n",name); + fprintf(stderr,"Input will then be from filename.ax1, output to filename.ax2\n"); + fprintf(stderr,"-h : prints this help information and terminates.\n"); + fprintf(stderr,"-v : prints information about each function treated in stdout.\n"); + exit(-1); +} + +/* + #] PrintHelp : + #[ Inivars : +*/ + +void Inivars() +{ + M_pi = acos(-1.); + torad = M_pi/180.; + BzK = 4.*(sqrt(2.)-1.)/3.; +} + +/* + #] Inivars : + #[ main : +*/ + +int main(int argc,char **argv) +{ + char *s, *inbuffer; + int length, error = 0; + long num,i; + + Inivars(); + argc--; + axohelp = *argv++; + if ( argc <= 0 ) PrintHelp(axohelp); + s = *argv; + while ( *s == '-' ) { /* we have arguments */ + if ( s[1] == 'h' && s[2] == 0 ) PrintHelp(axohelp); + else if ( s[1] == 'v' && s[2] == 0 ) { + VerboseFlag = 1; + } + else { + fprintf(stderr,"Illegal option %s in call to %s\n",s,axohelp); + PrintHelp(axohelp); + } + argc--; argv++; + if ( argc <= 0 ) { + fprintf(stderr,"Not enough arguments in call to %s\n",axohelp); + PrintHelp(axohelp); + } + s = *argv; + } + if ( argc != 1 ) { + fprintf(stderr,"Too many arguments in call to %s\n",axohelp); + PrintHelp(axohelp); + } +/* + The filename is now in s. We should copy it to a separate string and + paste on the extension .ax1 (if needed). We should also construct the + name of the output file. +*/ + length = strlen(s); + inname = strcpy(malloc((length+5)*sizeof(char)),s); + outname = strcpy(malloc((length+5)*sizeof(char)),s); + s = inname + length; + if ( length > 4 && s[-4] == '.' && s[-3] == 'a' && s[-2] == 'x' && s[-1] == '1' ) { + outname[length-1] = '2'; + } + else { + inname[length] = '.'; inname[length+1] = 'a'; + inname[length+2] = 'x'; inname[length+3] = '1'; inname[length+4] = 0; + outname[length] = '.'; outname[length+1] = 'a'; + outname[length+2] = 'x'; outname[length+3] = '2'; outname[length+4] = 0; + } + if ( ( inbuffer = ReadInput(inname) ) == 0 ) return(-1); + if ( ( outfile = fopen(outname,"w") ) == 0 ) { + fprintf(stderr,"%s: Cannot create file %s\n",axohelp,outname); + exit(-1); + } + num = ScanForObjects(inbuffer); + for ( i = 0; i < num; i++ ) { + numobject = i+1; + if ( DoOneObject(inputs[i]) < 0 ) { error++; } + } + fclose(outfile); + if ( error > 0 ) { + fprintf(stderr,"%s: %d objects in %s were not translated correctly.\n", + axohelp,error,inname); + return(-1); + } + return(0); +} + +/* + #] main : + #[ routines : + #[ Line routines : + #[ Line : * + + Line(x1,y1)(x2,y2) +*/ + +void Line(double *args) +{ + MoveTo(args[0],args[1]); + LineTo(args[2],args[3]); + Stroke; +} + +/* + #] Line : + #[ DoubleLine : * + + DoubleLine(x1,y1)(x2,y2){sep} +*/ + +void DoubleLine(double *args) +{ + SaveGraphicsState; + if ( args[4] > 0 ) { + SetLineWidth(args[4]+axolinewidth); + Line(args); + SetLineWidth(args[4]-axolinewidth); + SetBackgroundColor(STROKING); + } + Line(args); + RestoreGraphicsState; +} + +/* + #] DoubleLine : + #[ DashLine : * + + DashLine(x1,y1)(x2,y2){dashsize} +*/ + +void DashLine(double *args) +{ + double dx = args[2]-args[0], dy = args[3]-args[1], dr = sqrt(dx*dx+dy*dy); + double dashsize = args[4]; + int num; + num = dr/dashsize; + if ( ( num%2 ) == 1 ) num++; + dashsize = dr/num; + SetDashSize(dashsize,dashsize/2); + Line(args); +} + +/* + #] DashLine : + #[ DashDoubleLine : * + + DashDoubleLine(x1,y1)(x2,y2){sep}{dashsize} +*/ + +void DashDoubleLine(double *args) +{ + double dx = args[2]-args[0], dy = args[3]-args[1], dr = sqrt(dx*dx+dy*dy); + double dashsize = args[5]; + int num; + num = dr/dashsize; + if ( ( num%2 ) == 1 ) num++; + dashsize = dr/num; + SetDashSize(dashsize,dashsize/2); + DoubleLine(args); +} + +/* + #] DashDoubleLine : + #[ ArrowLine : * + + ArrowLine(x1,y1)(x2,y2){size}{where} + + where: x of arrowhead is x1+where*(x2-x1). Same for y. + serves both ArrowLine and LongArrowLine +*/ + +void ArrowLine(double *args) +{ + double dx, dy, dr, where; + Line(args); + if ( arrow.type == 0 ) where = args[5]; + else where = arrow.where; + dx = args[2]-args[0]; + dy = args[3]-args[1]; + dr = sqrt(dx*dx+dy*dy); + SetTransferMatrix(1,0,0,1,args[0],args[1]); + SetTransferMatrix(dx/dr,dy/dr,-dy/dr,dx/dr,0,0); + SetTransferMatrix(1,0,0,1,dr*where,0); + if ( arrow.type == 0 ) arrow.width = args[4]; + ArrowHead(); +} + +/* + #] ArrowLine : + #[ ArrowDoubleLine : * + + ArrowDoubleLine(x1,y1)(x2,y2){sep}{size}{where} + + where: x of arrowhead is x1+where*(x2-x1). Same for y. + serves both ArrowLine and LongArrowLine +*/ + +void ArrowDoubleLine(double *args) +{ + double dx, dy, dr, where; + DoubleLine(args); + if ( arrow.type == 0 ) where = args[6]; + else where = arrow.where; + dx = args[2]-args[0]; + dy = args[3]-args[1]; + dr = sqrt(dx*dx+dy*dy); + SetTransferMatrix(1,0,0,1,args[0],args[1]); + SetTransferMatrix(dx/dr,dy/dr,-dy/dr,dx/dr,0,0); + SetTransferMatrix(1,0,0,1,dr*where,0); + if ( arrow.type == 0 ) arrow.width = args[5]+args[4]; + ArrowHead(); +} + +/* + #] ArrowDoubleLine : + #[ DashArrowLine : * + + DashArrowLine(x1,y1)(x2,y2){dashsize}{amplitude}{where} + + where: x of arrowhead is x1+where*(x2-x1). Same for y. + we re-adjust the position of the arrow to place it on a dash. +*/ + +void DashArrowLine(double *args) +{ + double dx = args[2]-args[0], dy = args[3]-args[1], dr = sqrt(dx*dx+dy*dy); + double dashsize = args[4], where; + int num, nw; + if ( arrow.type == 0 ) where = args[6]; + else where = arrow.where; + num = dr/dashsize; + if ( ( num%2 ) == 1 ) num++; + if ( num%4 != 0 && where > 0.499 && where < 0.501 ) num += 2; + dashsize = dr/num; + SetDashSize(dashsize,dashsize/2); + Line(args); + nw = where*(num/2)+0.5; + where = (2.0*nw)/num; + SetTransferMatrix(1,0,0,1,args[0],args[1]); + SetTransferMatrix(dx/dr,dy/dr,-dy/dr,dx/dr,0,0); + SetTransferMatrix(1,0,0,1,dr*where,0); + if ( arrow.type == 0 ) arrow.width = args[5]; + ArrowHead(); +} + +/* + #] DashArrowLine : + #[ DashArrowDoubleLine : * + + DashArrowDoubleLine(x1,y1)(x2,y2){sep}{dashsize}{amplitude}{where} + + where: x of arrowhead is x1+where*(x2-x1). Same for y. + we re-adjust the position of the arrow to place it on a dash. +*/ + +void DashArrowDoubleLine(double *args) +{ + double dx = args[2]-args[0], dy = args[3]-args[1], dr = sqrt(dx*dx+dy*dy); + double dashsize = args[5], where; + int num, nw; + if ( arrow.type == 0 ) where = args[7]; + else where = arrow.where; + num = dr/dashsize; + if ( ( num%2 ) == 1 ) num++; + if ( num%4 != 0 && where > 0.499 && where < 0.501 ) num += 2; + dashsize = dr/num; + SetDashSize(dashsize,dashsize/2); + DoubleLine(args); + nw = where*(num/2)+0.5; + where = (2.0*nw)/num; + SetTransferMatrix(1,0,0,1,args[0],args[1]); + SetTransferMatrix(dx/dr,dy/dr,-dy/dr,dx/dr,0,0); + SetTransferMatrix(1,0,0,1,dr*where,0); + if ( arrow.type == 0 ) arrow.width = args[6]+args[4]; + ArrowHead(); +} + +/* + #] DashArrowDoubleLine : + #] Line routines : + #[ Arc routines : + #[ CArc : * + + CArc(x1,y1)(r,phi1,phi2) + + The arc segment runs anticlockwise + + We divide the segment into a number of equal segments, each less + than 90 degrees. Then the control points are at distance + 4*tan(90/n)/3 from the endpoints, in which n=360/(phi2-phi1) + (note that if n=4 we get tan(22.5)=sqrt(2)-1). +*/ + +void CArc(double *args) +{ + double phi1 = args[3], phi2 = args[4], r = args[2]; + double dphi; + while ( phi2 < phi1 ) phi2 += 360; + dphi = phi2-phi1; + if ( dphi <= 0 ) { return; } + if ( dphi >= 360 ) { ECirc(args); return; } + SetTransferMatrix(1,0,0,1,args[0],args[1]); + ArcSegment(r,phi1,dphi); + Stroke; +} + +/* + #] CArc : + #[ DoubleArc : * + + DoubleArc(x1,y1)(r,phi1,phi2){sep} + + The arc segment runs anticlockwise + + We divide the segment into a number of equal segments, each less + than 90 degrees. Then the control points are at distance + 4*tan(90/n)/3 from the endpoints, in which n=360/(phi2-phi1) + (note that if n=4 we get tan(22.5)=sqrt(2)-1). +*/ + +void DoubleArc(double *args) +{ + double phi1 = args[3], phi2 = args[4], r = args[2]; + double dphi, sep = args[5]; + while ( phi2 < phi1 ) phi2 += 360; + dphi = phi2-phi1; + if ( dphi <= 0 ) { return; } + SetTransferMatrix(1,0,0,1,args[0],args[1]); + ArcSegment(r+sep/2,phi1,dphi); + Stroke; + ArcSegment(r-sep/2,phi1,dphi); + Stroke; +} + +/* + #] DoubleArc : + #[ DashCArc : * + + DashCArc(x1,y1)(r,phi1,phi2){dashsize} + + The arc segment runs anticlockwise +*/ + +void DashCArc(double *args) +{ + double arcsize = args[4]-args[3]; + double r = args[2], dr, dashsize = args[5]; + int num; + if ( arcsize <= 0 ) arcsize += 360; + if ( arcsize > 360 ) arcsize = 360; + dr = 2*M_pi*r*(arcsize/360); + num = dr/dashsize; + if ( (num%2) == 1 ) num++; + dashsize = dr/num; + SetDashSize(dashsize,dashsize/2); + CArc(args); +} + +/* + #] DashCArc : + #[ DashDoubleArc : * + + DashDoubleArc(x1,y1)(r,phi1,phi2){sep}{dashsize} + + The arc segment runs anticlockwise + The trouble here is to synchronize the two dash patterns. + This is done by a rescaling. We assume that the rescaling is + sufficiently small that the linewidth does not suffer from it. +*/ + +void DashDoubleArc(double *args) +{ + double phi1 = args[3], r = args[2]; + double arcsize = args[4]-args[3]; + double dr, dashsize = args[6], sep = args[5]; + int num; + linesep = sep; + SetTransferMatrix(1,0,0,1,args[0],args[1]); + if ( arcsize <= 0 ) arcsize += 360; + if ( arcsize > 360 ) arcsize = 360; + dr = 2*M_pi*r*(arcsize/360); + num = dr/dashsize; + if ( (num%2) == 1 ) num++; + dashsize = dr/num; + SetDashSize(dashsize,dashsize/2); + SaveGraphicsState; + SetTransferMatrix(1+0.5*sep/r,0,0,1+0.5*sep/r,0,0); + ArcSegment(r,phi1,arcsize); + Stroke; + RestoreGraphicsState; + SaveGraphicsState; + SetTransferMatrix(1-0.5*sep/r,0,0,1-0.5*sep/r,0,0); + ArcSegment(r,phi1,arcsize); + Stroke; + RestoreGraphicsState; +} + +/* + #] DashDoubleArc : + #[ ArrowArc : * + + ArrowArc(x1,y1)(r,phi1,phi2){amplitude}{where} + + where: phi of arrowhead is phi1+where*(phi2-phi1) + The arc segment runs anticlockwise + serves both ArrowArc and LongArrowArc and ... (Jaxodraw addition) +*/ + +void ArrowArc(double *args) +{ + double phi1 = args[3], phi2 = args[4], r = args[2]; + double dphi, x, y, phi; + if ( arrow.type == 0 ) { + arrow.width = args[5]; + arrow.where = args[6]; + } + + while ( phi2 < phi1 ) phi2 += 360; + dphi = phi2-phi1; + SetTransferMatrix(1,0,0,1,args[0],args[1]); + + if ( dphi <= 0 ) { return; } + ArcSegment(r,phi1,dphi); + Stroke; +/* + Now compute the position and angle of the arrowhead +*/ + phi = phi1 + arrow.where*dphi; + x = r*COS(phi); y = r*SIN(phi); + SetTransferMatrix(1,0,0,1,x,y); + SetTransferMatrix(COS(phi+90),SIN(phi+90),-SIN(phi+90),COS(phi+90),0,0); + ArrowHead(); +} + +/* + #] ArrowArc : + #[ ArrowDoubleArc : * + + ArrowDoubleArc(x1,y1)(r,phi1,phi2){sep}{amplitude}{where} + + where: phi of arrowhead is phi1+where*(phi2-phi1) + The arc segment runs anticlockwise + serves both ArrowArc and LongArrowArc and ... (Jaxodraw addition) +*/ + +void ArrowDoubleArc(double *args) +{ + double phi1 = args[3], phi2 = args[4], r = args[2]; + double dphi, x, y, phi; + linesep = args[5]; + while ( phi2 < phi1 ) phi2 += 360; + dphi = phi2-phi1; + if ( dphi <= 0 ) { return; } + SetTransferMatrix(1,0,0,1,args[0],args[1]); + ArcSegment(r+linesep/2,phi1,dphi); + Stroke; + ArcSegment(r-linesep/2,phi1,dphi); + Stroke; +/* + Now compute the position and angle of the arrowhead +*/ + if ( arrow.type == 0 ) { + arrow.width = args[6]; + arrow.where = args[7]; + } + phi = phi1 + arrow.where*dphi; + x = r*COS(phi); y = r*SIN(phi); + SetTransferMatrix(1,0,0,1,x,y); + SetTransferMatrix(COS(phi+90),SIN(phi+90),-SIN(phi+90),COS(phi+90),0,0); + ArrowHead(); +} + +/* + #] ArrowDoubleArc : + #[ DashArrowArc : + + + DashArrowArc(x1,y1)(r,phi1,phi2){dashsize}{amplitude}{where} + + where: phi of arrowhead is phi1+where*(phi2-phi1) + The arc segment runs anticlockwise +*/ + +void DashArrowArc(double *args) +{ + double dphi, x, y, phi, phi1 = args[3], phi2 = args[4]; + double r = args[2], dr, dashsize = args[5]; + int num; + if ( arrow.type == 0 ) { + arrow.width = args[6]; + arrow.where = args[7]; + } + + while ( phi2 < phi1 ) phi2 += 360; + dphi = phi2-phi1; + if ( dphi > 360 ) dphi = 360; + dr = 2*M_pi*r*(dphi/360); + num = dr/dashsize; + if ( (num%2) == 1 ) num++; + if ( num%4 != 0 && arrow.where > 0.499 && arrow.where < 0.501 ) num += 2; + dashsize = dr/num; + SetDashSize(dashsize,dashsize/2); + SetTransferMatrix(1,0,0,1,args[0],args[1]); + if ( dphi <= 0 ) { return; } + ArcSegment(r,phi1,dphi); + Stroke; +/* + Now compute the position and angle of the arrowhead +*/ + phi = phi1 + arrow.where*dphi; + x = r*COS(phi); y = r*SIN(phi); + SetTransferMatrix(1,0,0,1,x,y); + SetTransferMatrix(COS(phi+90),SIN(phi+90),-SIN(phi+90),COS(phi+90),0,0); + ArrowHead(); +} + +/* + #] DashArrowArc : + #[ DashArrowDoubleArc : + + + DashArrowDoubleArc(x1,y1)(r,phi1,phi2){sep}{dashsize}{amplitude}{where} + + where: phi of arrowhead is phi1+where*(phi2-phi1) + The arc segment runs anticlockwise +*/ + +void DashArrowDoubleArc(double *args) +{ + double dphi, x, y, phi, phi1 = args[3], phi2 = args[4]; + double r = args[2], dr, dashsize = args[6]; + int num; + linesep = args[5]; + if ( arrow.type == 0 ) { + arrow.width = args[7]; + arrow.where = args[8]; + } + + while ( phi2 < phi1 ) phi2 += 360; + dphi = phi2-phi1; + if ( dphi > 360 ) dphi = 360; + dr = 2*M_pi*r*(dphi/360); + num = dr/dashsize; + if ( (num%2) == 1 ) num++; + if ( num%4 != 0 && arrow.where > 0.499 && arrow.where < 0.501 ) num += 2; + dashsize = dr/num; + SetDashSize(dashsize,dashsize/2); + SetTransferMatrix(1,0,0,1,args[0],args[1]); + if ( dphi <= 0 ) { return; } + SaveGraphicsState; + SetTransferMatrix(1+0.5*linesep/r,0,0,1+0.5*linesep/r,0,0); + ArcSegment(r,phi1,dphi); + Stroke; + RestoreGraphicsState; + SaveGraphicsState; + SetTransferMatrix(1-0.5*linesep/r,0,0,1-0.5*linesep/r,0,0); + ArcSegment(r,phi1,dphi); + Stroke; + RestoreGraphicsState; +/* + Now compute the position and angle of the arrowhead +*/ + phi = phi1 + arrow.where*dphi; + x = r*COS(phi); y = r*SIN(phi); + SetTransferMatrix(1,0,0,1,x,y); + SetTransferMatrix(COS(phi+90),SIN(phi+90),-SIN(phi+90),COS(phi+90),0,0); + ArrowHead(); +} + +/* + #] DashArrowDoubleArc : + #[ ArrowArcn : + + + ArrowArcn(x1,y1)(r,phi1,phi2){amplitude}{where} + + where: phi of arrowhead is phi1+where*(phi2-phi1) + The arc segment runs clockwise +*/ + +void ArrowArcn(double *args) +{ + double newargs[7], a; + int i; + for ( i = 0; i < 7; i++ ) newargs[i] = args[i]; + newargs[6] = 1-newargs[6]; + a = newargs[3]; newargs[3] = newargs[4]; newargs[4] = a; + ArrowArc(newargs); +} + +/* + #] ArrowArcn : + #[ DashArrowArcn : + + + DashArrowArc(x1,y1)(r,phi1,phi2){amplitude}{where}{dashsize} + + where: phi of arrowhead is phi1+where*(phi2-phi1) + The arc segment runs clockwise +*/ + +void DashArrowArcn(double *args) +{ + double newargs[8], a; + int i; + for ( i = 0; i < 8; i++ ) newargs[i] = args[i]; + newargs[6] = 1-newargs[6]; + a = newargs[3]; newargs[3] = newargs[4]; newargs[4] = a; + DashArrowArc(newargs); +} + +/* + #] DashArrowArcn : + #] Arc routines : + #[ Circle routines : + #[ ECirc : + + + ECirc(x,y){radius} + Draws a circle +*/ + +void ECirc(double *args) +{ + SetTransferMatrix(1,0,0,1,args[0],args[1]); + BezierCircle(args[2],"S"); +} + +/* + #] ECirc : + #[ FOval : + + + FOval(x1,y1)(h,w) filled oval in default color + +*/ + +void FOval(double *args) +{ + SetTransferMatrix(1,0,0,1,args[0],args[1]); /* Move to center of oval */ + SetTransferMatrix(COS(args[4]),SIN(args[4]),-SIN(args[4]),COS(args[4]),0,0); + BezierOval(args[3],args[2],"f"); + BezierOval(args[3],args[2],"S"); +} + +/* + #] COval : + #[ Oval : + + + Oval(x1,y1)(h,w)(phi) + + One way would be with different scales in the x and y direction, + but that messes up the linewidth. + We need to describe quarter ovals with Bezier curves. The proper + parameters for the curves we can obtain from the circle with scaling. +*/ + +void Oval(double *args) +{ + SetTransferMatrix(1,0,0,1,args[0],args[1]); /* Move to center of oval */ + SetTransferMatrix(COS(args[4]),SIN(args[4]),-SIN(args[4]),COS(args[4]),0,0); + BezierOval(args[3],args[2],"S"); +} + +/* + #] Oval : + #] Circle routines : + #[ Box routines : + #[ EBox : * + + \EBox(#1,#2)(#3,#4) + + Draws a box with the left bottom at (x1,y1) and the right top + at (x2,y2). + Transparent interior. Current color for edge. +*/ + +void EBox(double *args) +{ + Rectangle(args[0],args[1],args[2]-args[0],args[3]-args[1]); + Stroke; +} + +/* + #] EBox : + #[ FBox : * + + \FBox(#1,#2)(#3,#4) + + Draws a filled box with the left bottom at (x1,y1) and + the right top at (x2,y2). + Current color. +*/ + +void FBox(double *args) +{ + Rectangle(args[0],args[1],args[2]-args[0],args[3]-args[1]); + Fill; +} + +/* + #] FBox : + #[ Boxc : * + + \Boxc(#1,#2)(#3,#4) + + Draws a transparent box with the center at (x1,y1). + The width and height are (3,4). Uses current color. +*/ + +void Boxc(double *args) +{ + Rectangle(args[0]-args[2]/2,args[1]-args[3]/2,args[2],args[3]); + Stroke; +} + +/* + #] Boxc : + #[ FBoxc : * + + \FBoxc(#1,#2)(#3,#4) + + Draws a filled box with the center at (x1,y1). + The width and height are (3,4). Uses current color. +*/ + +void FBoxc(double *args) +{ + Rectangle(args[0]-args[2]/2,args[1]-args[3]/2,args[2],args[3]); + Fill; +} + +/* + #] FBoxc : + #] Box routines : + #[ Triangle routines : + #[ ETri : * + + \ETri(#1,#2)(#3,#4)(#5,#6) + + Draws a triangle with the three corners. +*/ + +void ETri(double *args) +{ + Triangle(args[0],args[1],args[2],args[3],args[4],args[5]); + Stroke; +} + +/* + #] ETri : + #[ FTri : * + + \FTri(#1,#2)(#3,#4)(#5,#6) + + Draws a triangle with the three corners. +*/ + +void FTri(double *args) +{ + Triangle(args[0],args[1],args[2],args[3],args[4],args[5]); + Fill; +} + +/* + #] FTri : + #] Triangle routines : + #[ Particle routines : + #[ Vertex : + + + Vertex(x,y){radius} + Draws a filled circle +*/ + +void Vertex(double *args) +{ + SetTransferMatrix(1,0,0,1,args[0],args[1]); + BezierCircle(args[2],"f"); +} + +/* + #] Vertex : + #[ ComputeDash : +*/ + +double ComputeDash(double *args,double dr,double indash) +{ + int numwindings = args[5]+0.5, numdashes; + int numhalfwindings = 2*numwindings+2.1; + double onehalfwinding = dr/numhalfwindings; + double amp8 = fabs(args[4])*0.9; + double size = LengthBezier(-amp8,0, -amp8,2*args[4], onehalfwinding,2*args[4],1.0); + + numdashes = size/(2*indash); + if ( numdashes == 0 ) numdashes = 1; + if ( fabs(size-2*indash*numdashes) > fabs(size-2*indash*(numdashes+1)) ) + numdashes++; + return(size/(2*numdashes)); +} + +/* + #] ComputeDash : + #[ ComputeDashCirc : +*/ + +double ComputeDashCirc(double *args,double indash) +{ + int num = args[5]+0.5, numdashes; + double ampi = args[4], radius = args[2]; + double darc; + double dr,conv,inc; + double amp1,amp2,amp4,amp5,amp8; + double x0,x1,x2,x3,y0,y1,y2,y3,xx,size; + darc = 360.; + dr = darc*torad*radius; + conv = 1.0/radius; + inc = dr/(2*num); /* increment per half winding */ + amp8 = ampi*0.9; + amp1 = radius+ampi; + amp2 = radius-ampi; + amp4 = amp1/cos((inc+amp8)*conv); + amp5 = amp2/cos(amp8*conv); + if ( amp8 < 0 ) amp8 = -amp8; + xx = 2*inc; + x0 = amp1*cos(inc*conv); + y0 = amp1*sin(inc*conv); + x1 = amp4*cos((xx+amp8)*conv)-x0; + y1 = amp4*sin((xx+amp8)*conv)-y0; + x2 = amp5*cos((xx+amp8)*conv)-x0; + y2 = amp5*sin((xx+amp8)*conv)-y0; + x3 = amp2*cos(xx*conv)-x0; + y3 = amp2*sin(xx*conv)-y0; + size = LengthBezier(x1,y1,x2,y2,x3,y3,1.0); + numdashes = size/(2*indash); + if ( numdashes == 0 ) numdashes = 1; + if ( fabs(size-2*indash*numdashes) > fabs(size-2*indash*(numdashes+1)) ) + numdashes++; + return(size/(2*numdashes)); +} + +/* + #] ComputeDashCirc : + #[ ComputeDashPhotonArc : +*/ + +double ComputeDashPhotonArc(double *args,double darc,double dashsize,double *dashstart) +{ + int numdashes, numd; + double len1, len2, size, size2, ampli = args[5], radius = args[2]; + double cp = cos(darc); + double sp = sin(darc); + double cp2 = cos(darc/2.); + double sp2 = sin(darc/2.); + double beta = radius*darc/(M_pi*ampli); + double tt = (sp-cp*beta)/(cp+sp*beta); + double x2 = ((radius+ampli)*8*(beta*cp2-sp2)-(beta*(4+cp) + +(tt*cp*3.-sp*4.))*radius)/((beta-tt)*3.); + double x1 = ((radius+ampli)*8.*cp2-(1+cp)*radius)/3.-x2; + double y1 = (x1-radius)*beta; + double y2 = (x2-radius*cp)*tt+radius*sp; + double x3 = radius*cp; + double y3 = radius*sp; + len1 = LengthBezier(x1-radius,y1,x2-radius,y2,x3-radius,y3,1.0); + ampli = -ampli; + beta = radius*darc/(M_pi*ampli); + tt = (sp-cp*beta)/(cp+sp*beta); + x2 = ((radius+ampli)*8*(beta*cp2-sp2)-(beta*(4+cp) + +(tt*cp*3.-sp*4.))*radius)/((beta-tt)*3.); + x1 = ((radius+ampli)*8.*cp2-(1+cp)*radius)/3.-x2; + y1 = (x1-radius)*beta; + y2 = (x2-radius*cp)*tt+radius*sp; + x3 = radius*cp; + y3 = radius*sp; + len2 = LengthBezier(x1-radius,y1,x2-radius,y2,x3-radius,y3,1.0); + size = (len1+len2)/2; + size2 = len1/2; + numdashes = size/(2*dashsize); + if ( numdashes == 0 ) numdashes = 1; + if ( fabs(size-2*dashsize*numdashes) > fabs(size-2*dashsize*(numdashes+1)) ) + numdashes++; + dashsize = size/(2*numdashes); + numd = size2/(2*dashsize); + *dashstart = -(size2 - 2*numd*dashsize) + dashsize/2; + if ( *dashstart < 0 ) *dashstart += 2*dashsize; + return(dashsize); +} + +/* + #] ComputeDashPhotonArc : + #[ ComputeDashGluonArc : +*/ + +double ComputeDashGluonArc(double *args,double darc,double dashsize) +{ + int numdashes, num = args[6]; + double radius = args[2], ampi = args[5]; + double dr,conv,inc, size; + double amp1,amp2,amp4,amp5,amp8; + double x1,x2,x3,y1,y2,y3,xx,x3p,y3p; + dr = darc*torad*radius; + conv = 1.0/radius; + inc = dr/(2*num+2); /* increment per half winding */ + amp8 = ampi*0.9; + amp1 = radius+ampi; + amp2 = radius-ampi; + amp4 = amp1/cos((inc+amp8)*conv); + amp5 = amp2/cos(amp8*conv); + if ( amp8 < 0 ) amp8 = -amp8; + + xx = 2*inc; + x3p = amp2*cos(xx*conv); + y3p = amp2*sin(xx*conv); + x1 = amp5*cos((xx-amp8)*conv)-x3p; + y1 = amp5*sin((xx-amp8)*conv)-y3p; + x2 = amp4*cos((xx-amp8)*conv)-x3p; + y2 = amp4*sin((xx-amp8)*conv)-y3p; + x3 = amp1*cos((xx+inc)*conv)-x3p; + y3 = amp1*sin((xx+inc)*conv)-y3p; + size = LengthBezier(x1,y1,x2,y2,x3,y3,1.0); + + numdashes = size/(2*dashsize); + if ( numdashes == 0 ) numdashes = 1; + if ( fabs(size-2*dashsize*numdashes) > fabs(size-2*dashsize*(numdashes+1)) ) + numdashes++; + dashsize = size/(2*numdashes); + return(dashsize); +} + +/* + #] ComputeDashGluonArc : + #[ GluonHelp : + + We draw the gluon in two strokes. This is due to the possibility + of a dash pattern. We want the dashes to be nicely symmetric on + the central windings. That means that either the start and end need + a different size dashes, or we draw the start 'backwards'. + We have chosen for the last solution. +*/ + +void GluonHelp(double *args,double dr) +{ + int numwindings = args[5]+0.5; + int numhalfwindings = 2*numwindings+2.1; + double onehalfwinding = dr/numhalfwindings; + double amp8 = fabs(args[4])*0.9; + double xx = 2*onehalfwinding; + int i; + MoveTo(xx,-args[4]); + Bezier(xx+amp8,-args[4],xx+amp8,args[4],1.4*onehalfwinding,args[4]); + Bezier(0.5*onehalfwinding,args[4], + 0.1*onehalfwinding,args[4]*0.5,0,0); + Stroke; + MoveTo(xx,-args[4]); + for ( i = 0; i < numwindings-1; i++ ) { + Bezier(xx-amp8,-args[4], xx-amp8,args[4], xx+onehalfwinding,args[4]); + xx += 2*onehalfwinding; + Bezier(xx+amp8,args[4], xx+amp8,-args[4], xx,-args[4]); + } + Bezier(xx-amp8,-args[4], xx-amp8,args[4], xx+onehalfwinding*0.6,args[4]); + Bezier(dr-onehalfwinding*0.5,args[4], + dr-onehalfwinding*0.1,args[4]*0.5, + dr,0); + Stroke; +} + +/* + #] GluonHelp : + #[ GluonCircHelp : +*/ + +void GluonCircHelp(double *args) +{ + int num = args[5], i; + double ampi = args[4], radius = args[2]; + double darc; + double dr,conv,inc; + double amp1,amp2,amp4,amp5,amp8; + double x1,x2,x3,y1,y2,y3,xx; + darc = 360.; + dr = darc*torad*radius; + conv = 1.0/radius; + inc = dr/(2*num); /* increment per half winding */ + amp8 = ampi*0.9; + amp1 = radius+ampi; + amp2 = radius-ampi; + amp4 = amp1/cos((inc+amp8)*conv); + amp5 = amp2/cos(amp8*conv); + if ( amp8 < 0 ) amp8 = -amp8; + xx = 2*inc; + x3 = amp1*cos(inc*conv); + y3 = amp1*sin(inc*conv); + MoveTo(x3,y3); +/* + Now the loop +*/ + for ( i = 0; i < num; i++ ) { + x1 = amp4*cos((xx+amp8)*conv); + y1 = amp4*sin((xx+amp8)*conv); + x2 = amp5*cos((xx+amp8)*conv); + y2 = amp5*sin((xx+amp8)*conv); + x3 = amp2*cos(xx*conv); + y3 = amp2*sin(xx*conv); + Bezier(x1,y1,x2,y2,x3,y3); + x1 = amp5*cos((xx-amp8)*conv); + y1 = amp5*sin((xx-amp8)*conv); + x2 = amp4*cos((xx-amp8)*conv); + y2 = amp4*sin((xx-amp8)*conv); + x3 = amp1*cos((xx+inc)*conv); + y3 = amp1*sin((xx+inc)*conv); + Bezier(x1,y1,x2,y2,x3,y3); + xx += 2*inc; + } + Stroke; +} + +/* + #] GluonCircHelp : + #[ GluonArcHelp : +*/ + +void GluonArcHelp(double *args, double darc, double ampi) +{ + int num = args[6], i; + double radius = args[2]; + double dr,conv,inc; + double amp1,amp2,amp3,amp4,amp5,amp6,amp7,amp8; + double x1,x2,x3,y1,y2,y3,xx,x1p,y1p,x2p,y2p,x3p,y3p; + dr = darc*torad*radius; + conv = 1.0/radius; + inc = dr/(2*num+2); /* increment per half winding */ + amp8 = ampi*0.9; + amp1 = radius+ampi; + amp2 = radius-ampi; + amp3 = radius+ampi/2; + amp4 = amp1/cos((inc+amp8)*conv); + amp5 = amp2/cos(amp8*conv); + amp6 = amp1/cos((inc*0.6+amp8)*conv); + amp7 = amp1/cos(inc*0.9*conv); + if ( amp8 < 0 ) amp8 = -amp8; + xx = 2*inc; +/* + First the starting part. We draw it separately because there could + be a dashing pattern. This way the windings come out best. +*/ + x1 = amp3*cos(inc*0.1*conv); + y1 = amp3*sin(inc*0.1*conv); + x2 = amp7*cos(inc*0.5*conv); + y2 = amp7*sin(inc*0.5*conv); + x3 = amp1*cos(inc*1.4*conv); + y3 = amp1*sin(inc*1.4*conv); + x1p = amp6*cos((xx+amp8)*conv); + y1p = amp6*sin((xx+amp8)*conv); + x2p = amp5*cos((xx+amp8)*conv); + y2p = amp5*sin((xx+amp8)*conv); + x3p = amp2*cos(xx*conv); + y3p = amp2*sin(xx*conv); + MoveTo(x3p,y3p); + Bezier(x2p,y2p,x1p,y1p,x3,y3); + Bezier(x2,y2,x1,y1,radius,0); + Stroke; +/* + Now the loop +*/ + MoveTo(x3p,y3p); + for ( i = 1; i < num; i++ ) { + x1 = amp5*cos((xx-amp8)*conv); + y1 = amp5*sin((xx-amp8)*conv); + x2 = amp4*cos((xx-amp8)*conv); + y2 = amp4*sin((xx-amp8)*conv); + x3 = amp1*cos((xx+inc)*conv); + y3 = amp1*sin((xx+inc)*conv); + Bezier(x1,y1,x2,y2,x3,y3); + xx += 2*inc; + x1 = amp4*cos((xx+amp8)*conv); + y1 = amp4*sin((xx+amp8)*conv); + x2 = amp5*cos((xx+amp8)*conv); + y2 = amp5*sin((xx+amp8)*conv); + x3 = amp2*cos(xx*conv); + y3 = amp2*sin(xx*conv); + Bezier(x1,y1,x2,y2,x3,y3); + } +/* + And now the end point +*/ + x1 = amp5*cos((xx-amp8)*conv); + y1 = amp5*sin((xx-amp8)*conv); + x2 = amp6*cos((xx-amp8)*conv); + y2 = amp6*sin((xx-amp8)*conv); + x3 = amp1*cos((xx+inc*0.6)*conv); + y3 = amp1*sin((xx+inc*0.6)*conv); + Bezier(x1,y1,x2,y2,x3,y3); + x1 = amp7*cos((xx+inc*1.5)*conv); + y1 = amp7*sin((xx+inc*1.5)*conv); + x2 = amp3*cos((dr-inc*0.1)*conv); + y2 = amp3*sin((dr-inc*0.1)*conv); + x3 = radius*cos(dr*conv); + y3 = radius*sin(dr*conv); + + Bezier(x1,y1,x2,y2,x3,y3); + + Stroke; +} + +/* + #] GluonArcHelp : + #[ PhotonHelp : +*/ + +void PhotonHelp(double *args, double dr) +{ + int numhalfwindings = args[5]*2+0.5; + double onehalfwinding = dr/numhalfwindings; + double y = 4.*args[4]/3; + double x, xx; + int i; + MoveTo(0,0); +/* + Now loop over the half windings, alternating the sign of the y's +*/ + x = (4*onehalfwinding)/3/M_pi; xx = 0; + for ( i = 0; i < numhalfwindings; i++, y = -y ) { + Bezier(xx+x,y, xx+onehalfwinding-x,y, xx+onehalfwinding,0); + xx += onehalfwinding; + } + Stroke; +} +/* + #] PhotonHelp : + #[ PhotonArcHelp : +*/ + +void PhotonArcHelp(double *args,double arcend,int num) +{ + int i; + double ampli = args[5], radius = args[2]; + double cp,sp,cp2,sp2,cpi,spi; + double x1,x2,x3,y1,y2,y3,beta,tt; + + cp = cos(arcend); + sp = sin(arcend); + cp2 = cos(arcend/2.); + sp2 = sin(arcend/2.); + + MoveTo(radius,0); + for ( i = 0; i < num; i++, ampli = -ampli ) { + cpi = cos(i*arcend); + spi = sin(i*arcend); + beta = radius*arcend/(M_pi*ampli); + tt = (sp-cp*beta)/(cp+sp*beta); + x2 = ((radius+ampli)*8*(beta*cp2-sp2)-(beta*(4+cp) + +(tt*cp*3.-sp*4.))*radius)/((beta-tt)*3.); + x1 = ((radius+ampli)*8.*cp2-(1+cp)*radius)/3.-x2; + y1 = (x1-radius)*beta; + y2 = (x2-radius*cp)*tt+radius*sp; + x3 = radius*cp; + y3 = radius*sp; + Bezier(cpi*x1-spi*y1,cpi*y1+spi*x1, + cpi*x2-spi*y2,cpi*y2+spi*x2, + cpi*x3-spi*y3,cpi*y3+spi*x3); + } + Stroke; +} + +/* + #] PhotonArcHelp : + #[ ZigZagHelp : +*/ + +void ZigZagHelp(double *args, double dr) +{ + int numhalfwindings = args[5]*2+0.5; + double onehalfwinding = dr/numhalfwindings; + double x = onehalfwinding, y = args[4]; + int i; + MoveTo(0,0); +/* + Now loop over the half windings, alternating the sign of the y's +*/ + for ( i = 0; i < numhalfwindings; i++, y = -y ) { + LineTo(x-onehalfwinding/2.,y); LineTo(x,0); + x += onehalfwinding; + } + Stroke; +} + +/* + #] ZigZagHelp : + #[ ZigZagArcHelp : +*/ + +void ZigZagArcHelp(double *args) +{ + int num = 2*args[6]-0.5, i; + double amp = args[5], r = args[2]; + double arcstart = args[3], arcend = args[4], darc; + if ( arcend < arcstart ) arcend += 360.; + darc = (arcend-arcstart)/(num+1); + MoveTo(r*COS(arcstart),r*SIN(arcstart)); + arcstart += darc/2; + for ( i = 0; i <= num; i++, amp = -amp ) { + LineTo((r+amp)*COS(arcstart+darc*i),(r+amp)*SIN(arcstart+darc*i)); + } + LineTo(r*COS(arcend),r*SIN(arcend)); + Stroke; +} + +/* + #] ZigZagArcHelp : + #[ Gluon : * + + Gluon(x1,y1)(x2,y2){amplitude}{windings} + + Each half winding is one cubic Bezier curve. + In addition the end points are different Bezier curves. +*/ + +void Gluon(double *args) +{ + double dx = args[2] - args[0]; + double dy = args[3] - args[1]; + double dr = sqrt(dx*dx+dy*dy); + + SetTransferMatrix(1,0,0,1,args[0],args[1]); + SetTransferMatrix(dx/dr,dy/dr,-dy/dr,dx/dr,0,0); + GluonHelp(args,dr); +} + +/* + #] Gluon : + #[ DashGluon : * + + DashGluon(x1,y1)(x2,y2){amplitude}{windings}{dashsize} + + Each half winding is one cubic Bezier curve. + In addition the end points are different Bezier curves. +*/ + +void DashGluon(double *args) +{ + double dx = args[2] - args[0]; + double dy = args[3] - args[1]; + double dr = sqrt(dx*dx+dy*dy); + double dashsize; + + SetTransferMatrix(1,0,0,1,args[0],args[1]); + SetTransferMatrix(dx/dr,dy/dr,-dy/dr,dx/dr,0,0); + + dashsize = ComputeDash(args,dr,args[6]); + SetDashSize(dashsize,dashsize/2); + GluonHelp(args,dr); +} + +/* + #] DashGluon : + #[ GluonCirc : * + + GluonCirc(x1,y1)(r,phi){amplitude}{windings} + + Draws a gluon on a circle + x_center,y_center,radius,phase_angle,gluon_radius,num + in which num is the number of windings of the gluon. + Method: Same as GluonArc, but without special start and end +*/ + +void GluonCirc(double *args) +{ + int num = args[5]; + double arcstart = args[3]; + + SetTransferMatrix(1,0,0,1,args[0],args[1]); /* Move to center of circle */ + + arcstart += 360./(2*num); /* extra phase to make 0 angle more accessible */ + + SetTransferMatrix(COS(arcstart),SIN(arcstart) + ,-SIN(arcstart),COS(arcstart),0,0); + + GluonCircHelp(args); +} + +/* + #] GluonCirc : + #[ DashGluonCirc : * + + DashGluonCirc(x1,y1)(r,phi){amplitude}{windings}{dashsize} + + Draws a gluon on a circle + x_center,y_center,radius,phase_angle,gluon_radius,num + in which num is the number of windings of the gluon. + Method: Same as GluonArc, but without special start and end +*/ + +void DashGluonCirc(double *args) +{ + int num = args[5]; + double arcstart = args[3], dashsize; + + SetTransferMatrix(1,0,0,1,args[0],args[1]); /* Move to center of circle */ + + arcstart += 360./(2*num); /* extra phase to make 0 angle more accessible */ + + SetTransferMatrix(COS(arcstart),SIN(arcstart) + ,-SIN(arcstart),COS(arcstart),0,0); + + dashsize = ComputeDashCirc(args,args[6]); + + SetDashSize(dashsize,dashsize/2); + GluonCircHelp(args); +} + +/* + #] DashGluonCirc : + #[ GluonArc : * + + GluonArc(x1,y1)(r,phi1,phi2){amplitude}{windings} + + Draws a gluon on an arcsegment + x_center,y_center,radius,stat_angle,end_angle,gluon_radius,num + in which num is the number of windings of the gluon. + Method: + 1: compute length of arc. + 2: generate gluon in x and y as if the arc is a straight line + 3: x' = (radius+y)*cos(x*const) + y' = (radius+y)*sin(x*const) +*/ + +void GluonArc(double *args) +{ + double darc, arcstart = args[3],arcend = args[4], ampi = args[5]; +/* + When arcend comes before arcstart we have a problem. The solution is + to flip the order and change the sign on ampi +*/ + if ( arcend < arcstart ) { + darc = arcstart; arcstart = arcend; arcend = darc; ampi = -ampi; + } + + SetTransferMatrix(1,0,0,1,args[0],args[1]); /* Move to center of circle */ + + SetTransferMatrix(COS(arcstart),SIN(arcstart) + ,-SIN(arcstart),COS(arcstart),0,0); + darc = arcend-arcstart; + GluonArcHelp(args,darc,ampi); +} + +/* + #] GluonArc : + #[ DashGluonArc : * + + DashGluonArc(x1,y1)(r,phi1,phi2){amplitude}{windings}{dashsize} + + Draws a gluon on an arcsegment + x_center,y_center,radius,stat_angle,end_angle,gluon_radius,num + in which num is the number of windings of the gluon. + Method: + 1: compute length of arc. + 2: generate gluon in x and y as if the arc is a straight line + 3: x' = (radius+y)*cos(x*const) + y' = (radius+y)*sin(x*const) +*/ + +void DashGluonArc(double *args) +{ + double darc, arcstart = args[3],arcend = args[4], ampi = args[5]; + double dashsize = args[7]; +/* + When arcend comes before arcstart we have a problem. The solution is + to flip the order and change the sign on ampi +*/ + if ( arcend < arcstart ) { + darc = arcstart; arcstart = arcend; arcend = darc; ampi = -ampi; + } + + SetTransferMatrix(1,0,0,1,args[0],args[1]); /* Move to center of circle */ + + SetTransferMatrix(COS(arcstart),SIN(arcstart) + ,-SIN(arcstart),COS(arcstart),0,0); + darc = arcend-arcstart; + dashsize = ComputeDashGluonArc(args,darc,dashsize); + SetDashSize(dashsize,dashsize/2); + GluonArcHelp(args,darc,ampi); +} + +/* + #] DashGluonArc : + #[ Photon : * + + Photon(x1,y1)(x2,y2){amplitude}{windings} + + Each half winding is one cubic Bezier curve. +*/ + +void Photon(double *args) +{ + double dx = args[2] - args[0]; + double dy = args[3] - args[1]; + double dr = sqrt(dx*dx+dy*dy); + + SetTransferMatrix(1,0,0,1,args[0],args[1]); + SetTransferMatrix(dx/dr,dy/dr,-dy/dr,dx/dr,0,0); + + PhotonHelp(args,dr); +} + +/* + #] Photon : + #[ DoublePhoton : * + + DoublePhoton(x1,y1)(x2,y2){amplitude}{windings}{sep} + + Each half winding is one cubic Bezier curve. +*/ + +void DoublePhoton(double *args) +{ + double dx = args[2] - args[0]; + double dy = args[3] - args[1]; + double dr = sqrt(dx*dx+dy*dy); + linesep = args[6]; + + SetTransferMatrix(1,0,0,1,args[0],args[1]); + SetTransferMatrix(dx/dr,dy/dr,-dy/dr,dx/dr,0,0); + + SaveGraphicsState; + SetLineWidth(linesep+axolinewidth); + PhotonHelp(args,dr); + RestoreGraphicsState; + + SaveGraphicsState; + SetLineWidth(linesep-axolinewidth); + SetBackgroundColor(STROKING); + PhotonHelp(args,dr); + RestoreGraphicsState; +} + +/* + #] DoublePhoton : + #[ DashPhoton : * + + DashPhoton(x1,y1)(x2,y2){amplitude}{windings}{dashsize} + + Each half winding is one cubic Bezier curve. +*/ + +void DashPhoton(double *args) +{ + double dx = args[2] - args[0]; + double dy = args[3] - args[1]; + double dr = sqrt(dx*dx+dy*dy); + int numdashes, numhalfwindings = args[5]*2+0.5; + double x, y, size; + double dashsize = args[6], onehalfwinding = dr/numhalfwindings; + x = (4*onehalfwinding)/3/M_pi; y = 4.*args[4]/3; + size = 0.5*LengthBezier(x,y, onehalfwinding-x,y, onehalfwinding,0,1.0); + numdashes = size/(2*args[6]); + if ( numdashes == 0 ) numdashes = 1; + if ( fabs(size-2*dashsize*numdashes) > fabs(size-2*dashsize*(numdashes+1)) ) + numdashes++; + dashsize = size/(2*numdashes); + + SetTransferMatrix(1,0,0,1,args[0],args[1]); + SetTransferMatrix(dx/dr,dy/dr,-dy/dr,dx/dr,0,0); + + SetDashSize(dashsize,dashsize/2); + PhotonHelp(args,dr); +} + +/* + #] DashPhoton : + #[ DashDoublePhoton : * + + DashDoublePhoton(x1,y1)(x2,y2){amplitude}{windings}{sep}{dashsize} + + Each half winding is one cubic Bezier curve. +*/ + +void DashDoublePhoton(double *args) +{ + double dx = args[2] - args[0]; + double dy = args[3] - args[1]; + double dr = sqrt(dx*dx+dy*dy); + int numdashes, numhalfwindings = args[5]*2+0.5; + double x, y, size; + double dashsize = args[7], onehalfwinding = dr/numhalfwindings; + x = (4*onehalfwinding)/3/M_pi; y = 4.*args[4]/3; + size = 0.5*LengthBezier(x,y, onehalfwinding-x,y, onehalfwinding,0,1.0); + numdashes = size/(2*args[6]); + if ( numdashes == 0 ) numdashes = 1; + if ( fabs(size-2*dashsize*numdashes) > fabs(size-2*dashsize*(numdashes+1)) ) + numdashes++; + dashsize = size/(2*numdashes); + + linesep = args[6]; + + SetTransferMatrix(1,0,0,1,args[0],args[1]); + SetTransferMatrix(dx/dr,dy/dr,-dy/dr,dx/dr,0,0); + SetDashSize(dashsize,dashsize/2); + + SaveGraphicsState; + SetLineWidth(linesep+axolinewidth); + PhotonHelp(args,dr); + RestoreGraphicsState; + +/* SetDashSize(0,0); */ + SaveGraphicsState; + SetLineWidth(linesep-axolinewidth); + SetBackgroundColor(STROKING); + PhotonHelp(args,dr); + RestoreGraphicsState; +} + +/* + #] DashDoublePhoton : + #[ PhotonArc : * + + PhotonArc(x1,y1)(r,phi1,phi2){amplitude}{windings} + + This routine follows the Postscript routine closely, except for that + we do not put a transfer matrix inside the loop. The corresponding + moveto messes up the path. One would have to put stroking operations + in there each time. +*/ + +void PhotonArc(double *args) +{ + double arcstart = args[3],arcend = args[4]; + int num = 2*args[6]+0.5; + + if ( arcend < arcstart ) arcend += 360.; + + SetTransferMatrix(1,0,0,1,args[0],args[1]); /* Move to center of circle */ + + arcend = torad*(arcend-arcstart)/num; + + SetTransferMatrix(COS(arcstart),SIN(arcstart) + ,-SIN(arcstart),COS(arcstart),0,0); + + PhotonArcHelp(args,arcend,num); +} + +/* + #] PhotonArc : + #[ DoublePhotonArc : * + + DoublePhotonArc(x1,y1)(r,phi1,phi2){amplitude}{windings}{sep} +*/ + +void DoublePhotonArc(double *args) +{ + double arcstart = args[3],arcend = args[4]; + int num = 2*args[6]+0.5; + linesep = args[7]; + + if ( arcend < arcstart ) arcend += 360.; + + SetTransferMatrix(1,0,0,1,args[0],args[1]); /* Move to center of circle */ + + arcend = torad*(arcend-arcstart)/num; + + SetTransferMatrix(COS(arcstart),SIN(arcstart) + ,-SIN(arcstart),COS(arcstart),0,0); + + SaveGraphicsState; + SetLineWidth(linesep+axolinewidth); + PhotonArcHelp(args,arcend,num); + RestoreGraphicsState; + + SaveGraphicsState; + SetLineWidth(linesep-axolinewidth); + SetBackgroundColor(STROKING); + PhotonArcHelp(args,arcend,num); + RestoreGraphicsState; +} + +/* + #] DoublePhotonArc : + #[ DashPhotonArc : * + + DashPhotonArc(x1,y1)(r,phi1,phi2){amplitude}{windings}{dashsize} +*/ + +void DashPhotonArc(double *args) +{ + double arcstart = args[3],arcend = args[4]; + double dashsize = args[7], dashstart; + int num = 2*args[6]+0.5; + + if ( arcend < arcstart ) arcend += 360.; + + SetTransferMatrix(1,0,0,1,args[0],args[1]); /* Move to center of circle */ + + arcend = torad*(arcend-arcstart)/num; + + SetTransferMatrix(COS(arcstart),SIN(arcstart) + ,-SIN(arcstart),COS(arcstart),0,0); + + dashsize = ComputeDashPhotonArc(args,arcend,dashsize,&dashstart); + SetDashSize(dashsize,dashstart); + PhotonArcHelp(args,arcend,num); +} + +/* + #] DashPhotonArc : + #[ DashDoublePhotonArc : * + + DashDoublePhotonArc(x1,y1)(r,phi1,phi2){amplitude}{windings}{sep}{dashsize} +*/ + +void DashDoublePhotonArc(double *args) +{ + double arcstart = args[3],arcend = args[4]; + double dashsize = args[8], dashstart; + int num = 2*args[6]+0.5; + linesep = args[7]; + + if ( arcend < arcstart ) arcend += 360.; + + SetTransferMatrix(1,0,0,1,args[0],args[1]); /* Move to center of circle */ + + arcend = torad*(arcend-arcstart)/num; + + SetTransferMatrix(COS(arcstart),SIN(arcstart) + ,-SIN(arcstart),COS(arcstart),0,0); + dashsize = ComputeDashPhotonArc(args,arcend,dashsize,&dashstart); + + SaveGraphicsState; + SetDashSize(dashsize,dashstart); + SetLineWidth(linesep+axolinewidth); + PhotonArcHelp(args,arcend,num); + RestoreGraphicsState; + + SaveGraphicsState; + SetDashSize(0,0); + SetLineWidth(linesep-axolinewidth); + SetBackgroundColor(STROKING); + PhotonArcHelp(args,arcend,num); + RestoreGraphicsState; +} + +/* + #] DashDoublePhotonArc : + #[ ZigZag : * + + ZigZag(x1,y1)(x2,y2){amplitude}{windings} + + We draw each half winding as two straight lines. + This can be done better! +*/ + +void ZigZag(double *args) +{ + double dx = args[2] - args[0]; + double dy = args[3] - args[1]; + double dr = sqrt(dx*dx+dy*dy); + + SetTransferMatrix(1,0,0,1,args[0],args[1]); + SetTransferMatrix(dx/dr,dy/dr,-dy/dr,dx/dr,0,0); + ZigZagHelp(args,dr); +} + +/* + #] ZigZag : + #[ DoubleZigZag : * + + DoubleZigZag(x1,y1)(x2,y2){amplitude}{windings}{sep} + + We draw each half winding as two straight lines. + This can be done better! +*/ + +void DoubleZigZag(double *args) +{ + double dx = args[2] - args[0]; + double dy = args[3] - args[1]; + double dr = sqrt(dx*dx+dy*dy); + linesep = args[6]; + + SetTransferMatrix(1,0,0,1,args[0],args[1]); + SetTransferMatrix(dx/dr,dy/dr,-dy/dr,dx/dr,0,0); + + SaveGraphicsState; + SetLineWidth(linesep+axolinewidth); + ZigZagHelp(args,dr); + RestoreGraphicsState; + + SaveGraphicsState; + SetLineWidth(linesep-axolinewidth); + SetBackgroundColor(STROKING); + ZigZagHelp(args,dr); + RestoreGraphicsState; +} + +/* + #] DoubleZigZag : + #[ DashZigZag : * + + DashZigZag(x1,y1)(x2,y2){amplitude}{windings}{dashsize} + + We should recalculate the size of the dashes. Otherwise the points + of the teeth can become messy. +*/ + +void DashZigZag(double *args) +{ + double dx = args[2] - args[0]; + double dy = args[3] - args[1]; + double dr = sqrt(dx*dx+dy*dy); + double dashsize = args[6]; + int n = args[5]*2+0.5; + double size = dr/(n*2); + + SetTransferMatrix(1,0,0,1,args[0],args[1]); + SetTransferMatrix(dx/dr,dy/dr,-dy/dr,dx/dr,0,0); + + size = sqrt(size*size+args[4]*args[4]); + n = size/(2*dashsize); /* number of complete dash patterns rounded down */ +/* + Now test what is closer to dash: size/n or size/(n+1) +*/ + if ( n == 0 ) n = 1; + if ( fabs(size-2*dashsize*n) > fabs(size-2*dashsize*(n+1)) ) n++; + dashsize = size/(2*n); + + SetDashSize(dashsize,dashsize/2); + ZigZagHelp(args,dr); +} + +/* + #] DashZigZag : + #[ DashDoubleZigZag : * + + DashDoubleZigZag(x1,y1)(x2,y2){amplitude}{windings}{sep}{dashsize} + + We draw each half winding as two straight lines. + This can be done better! +*/ + +void DashDoubleZigZag(double *args) +{ + double dx = args[2] - args[0]; + double dy = args[3] - args[1]; + double dr = sqrt(dx*dx+dy*dy); + double dashsize = args[7]; + int n = args[5]*2+0.5; + double size = dr/(n*2); + linesep = args[6]; + + SetTransferMatrix(1,0,0,1,args[0],args[1]); + SetTransferMatrix(dx/dr,dy/dr,-dy/dr,dx/dr,0,0); + + size = sqrt(size*size+args[4]*args[4]); + n = size/(2*dashsize); /* number of complete dash patterns rounded down */ +/* + Now test what is closer to dash: size/n or size/(n+1) +*/ + if ( n == 0 ) n = 1; + if ( fabs(size-2*dashsize*n) > fabs(size-2*dashsize*(n+1)) ) n++; + dashsize = size/(2*n); + + SetDashSize(dashsize,dashsize/2); + + SaveGraphicsState; + SetLineWidth(linesep+axolinewidth); + ZigZagHelp(args,dr); + RestoreGraphicsState; + + SetDashSize(0,0); + + SaveGraphicsState; + SetLineWidth(linesep-axolinewidth); + SetBackgroundColor(STROKING); + ZigZagHelp(args,dr); + RestoreGraphicsState; +} + +/* + #] DashDoubleZigZag : + #[ ZigZagArc : * + + ZigZagArc(x1,y1)(r,phi1,phi2){amplitude}{windings} +*/ + +void ZigZagArc(double *args) +{ + SetTransferMatrix(1,0,0,1,args[0],args[1]); /* Move to center of circle */ + ZigZagArcHelp(args); +} + +/* + #] ZigZagArc : + #[ DoubleZigZagArc : * + + DoubleZigZagArc(x1,y1)(r,phi1,phi2){amplitude}{windings}{sep} +*/ + +void DoubleZigZagArc(double *args) +{ + SetTransferMatrix(1,0,0,1,args[0],args[1]); /* Move to center of circle */ + linesep = args[7]; + + SaveGraphicsState; + SetLineWidth(linesep+axolinewidth); + ZigZagArcHelp(args); + RestoreGraphicsState; + + SaveGraphicsState; + SetLineWidth(linesep-axolinewidth); + SetBackgroundColor(STROKING); + ZigZagArcHelp(args); + RestoreGraphicsState; +} + +/* + #] DoubleZigZagArc : + #[ DashZigZagArc : * + + DashZigZagArc(x1,y1)(r,phi1,phi2){amplitude}{windings}{dashsize} +*/ + +void DashZigZagArc(double *args) +{ + double dashsize = args[7], dashstart; + SetTransferMatrix(1,0,0,1,args[0],args[1]); /* Move to center of circle */ + { + int num = 2*args[6]-0.5, numdashes; + double amp = args[5], r = args[2], size, size2; + double arcstart = args[3], arcend = args[4], darc; + if ( arcend < arcstart ) arcend += 360.; + darc = (arcend-arcstart)/(num+1); + size = sqrt(0.5*(amp*amp+r*r-(r*r-amp*amp)*COS(darc))); + size2 = sqrt(amp*amp+2*(amp+r)*r*(1-COS(darc/2))); + numdashes = size/(2*dashsize); + if ( numdashes == 0 ) numdashes = 1; + if ( fabs(size-2*dashsize*numdashes) > fabs(size-2*dashsize*(numdashes+1)) ) + numdashes++; + dashsize = size/(2*numdashes); + num = size2/(2*dashsize); + dashstart = -(size2 - 2*num*dashsize) + dashsize/2; + if ( dashstart < 0 ) dashstart += 2*dashsize; + } + SetDashSize(dashsize,dashstart); + ZigZagArcHelp(args); +} + +/* + #] DashZigZagArc : + #[ DashDoubleZigZagArc : * + + DashDoubleZigZagArc(x1,y1)(r,phi1,phi2){amplitude}{windings}{sep}{dashsize} +*/ + +void DashDoubleZigZagArc(double *args) +{ + double dashsize = args[8], dashstart; + SetTransferMatrix(1,0,0,1,args[0],args[1]); /* Move to center of circle */ + linesep = args[7]; + { + int num = 2*args[6]-0.5, numdashes; + double amp = args[5], r = args[2], size, size2; + double arcstart = args[3], arcend = args[4], darc; + if ( arcend < arcstart ) arcend += 360.; + darc = (arcend-arcstart)/(num+1); + size = sqrt(0.5*(amp*amp+r*r-(r*r-amp*amp)*COS(darc))); + size2 = sqrt(amp*amp+2*(amp+r)*r*(1-COS(darc/2))); + numdashes = size/(2*dashsize); + if ( numdashes == 0 ) numdashes = 1; + if ( fabs(size-2*dashsize*numdashes) > fabs(size-2*dashsize*(numdashes+1)) ) + numdashes++; + dashsize = size/(2*numdashes); + num = size2/(2*dashsize); + dashstart = -(size2 - 2*num*dashsize) + dashsize/2; + if ( dashstart < 0 ) dashstart += 2*dashsize; + } + + SaveGraphicsState; + SetDashSize(dashsize,dashstart); + SetLineWidth(linesep+axolinewidth); + ZigZagArcHelp(args); + RestoreGraphicsState; + + SaveGraphicsState; + SetDashSize(0,0); + SetLineWidth(linesep-axolinewidth); + SetBackgroundColor(STROKING); + ZigZagArcHelp(args); + RestoreGraphicsState; +} + +/* + #] DashDoubleZigZagArc : + #] Particle routines : + #[ Drawing routines : + #[ Polygon : +*/ + +void Polygon(double *args,int num,int type) +{ + int i; + MoveTo(args[0],args[1]); + args += 2; + for ( i = 1; i < num; i++, args += 2 ) { + LineTo(args[0],args[1]); + } + if ( type == 0 ) { CloseAndStroke; } + else if ( type == 1 ) { CloseAndFill; } +} + +/* + #] Polygon : + #[ Curve : + + + Curve{(x1,y1),...,(xn,yn)} + + num is the number of pairs in points. +*/ + +void Curve(double *points,int num) +{ + int i, ss; + double x0,y0,x1,y1,x2,y2,x3,y3; + + if ( num < 2 ) return; + if ( num == 2 ) { Line(points); return; } + + ss = 2*num; + + x1 = points[0]; y1 = points[1]; + x2 = points[2]; y2 = points[3]; + x3 = points[4]; y3 = points[5]; + x0 = 2*x1-x2; + y0 = 2*((y3-y2)/(x3-x2)-(y2-y1)/(x2-x1))*((x2-x1)*(x2-x1)/(x3-x1))+2*y1-y2; + + MoveTo(x1,y1); + DoCurve(x0,y0,x1,y1,x2,y2,x3,y3); + + for ( i = 0; i < ss-6; i += 2 ) { + DoCurve(points[i ],points[i+1],points[i+2],points[i+3], + points[i+4],points[i+5],points[i+6],points[i+7]); + } + if ( ss > 6 ) { + x0 = points[ss-6]; y0 = points[ss-5]; + x1 = points[ss-4]; y1 = points[ss-3]; + x2 = points[ss-2]; y2 = points[ss-1]; + x3 = 2*x2-x1; + y3 = 2*((y2-y1)/(x2-x1)-(y1-y0)/(x1-x0))*((x2-x1)*(x2-x1)/(x2-x0))+2*y2-y1; + + DoCurve(x0,y0,x1,y1,x2,y2,x3,y3); + } + Stroke; +} + +/* + #] Curve : + #[ DashCurve : + + + DashCurve{(x1,y1),...,(xn,yn)}{dashsize} +*/ + +void DashCurve(double *args,int num1) +{ + double dashsize = args[2*num1]; + if ( num1 == 2 ) { + DashLine(args); + } + else if ( num1 > 2 ) { + SetDashSize(dashsize,dashsize/2); + Curve(args,num1); + } +} + +/* + #] DashCurve : + #[ LogAxis : + + Draws a line with logarithmic hash marks along it. + LogAxis(x1,y1)(x2,y2)(num_logs,hashsize,offset,width) + The line is from (x1,y1) to (x2,y2) and the marks are on the left side + when hashsize is positive, and right when it is negative. + num_logs is the number of orders of magnitude and offset is the number + at which one starts at (x1,y1) (like if offset=2 we start at 2) + When offset is 0 we start at 1. Width is the linewidth. +*/ + +void LogAxis(double *args) +{ + double dx = args[2]-args[0], dy = args[3]-args[1], dr = sqrt(dx*dx+dy*dy); + double width = args[7], size, nlogs = args[4], hashsize = args[5]; + double offset = args[6], x; + int i, j; + SetTransferMatrix(1,0,0,1,args[0],args[1]); + SetTransferMatrix(dx/dr,dy/dr,-dy/dr,dx/dr,0,0); + MoveTo(0,0); LineTo(dr,0); Stroke; +/* + Now compute the hash marks. +*/ + size = dr/nlogs; + if ( offset <= 0 ) { offset = 0; } + else { offset = log10(offset); } +/* + Big hash marks +*/ + for ( i = 1; i <= nlogs; i++ ) { + MoveTo((i-offset)*size,0); + LineTo((i-offset)*size,hashsize*1.2); + Stroke; + } +/* + Little hash marks +*/ + SetLineWidth(0.6*width); + for ( i = 0; i <= nlogs; i++ ) { + for ( j = 2; j < 10; j++ ) { + x = (i-offset+log10(j))*size; + if ( x >= 0 && x <= dr ) { + MoveTo(x,0); LineTo(x,hashsize*0.8); Stroke; + } + } + } +} + +/* + #] LogAxis : + #[ LinAxis : + + Draws a line with linear hash marks along it. + LinAxis(x1,y1)(x2,y2)(num_decs,per_dec,hashsize,offset,width) + The line is from (x1,y1) to (x2,y2) and the marks are on the left side + when hashsize is positive, and right when it is negative. + num_decs is the number of accented marks, per_dec the number of + divisions between them and offset is the number + at which one starts at (x1,y1) (like if offset=2 we start at the second + small mark) Width is the linewidth. +*/ + +void LinAxis(double *args) +{ + double width = args[8], hashsize = args[6], x; + double dx = args[2]-args[0], dy = args[3]-args[1], dr = sqrt(dx*dx+dy*dy); + double num_decs = args[4], per_dec = args[5], size, size2; + int i, j, numperdec = per_dec+0.5, offset = args[7]; + SetTransferMatrix(1,0,0,1,args[0],args[1]); + SetTransferMatrix(dx/dr,dy/dr,-dy/dr,dx/dr,0,0); + MoveTo(0,0); LineTo(dr,0); Stroke; + size = dr/num_decs; + if ( numperdec > 1 ) size2 = size / numperdec; + else { size2 = size; numperdec = 1; } + if ( offset > numperdec ) offset = numperdec; + else if ( offset <= 0 ) offset = 0; +/* + Big hashes +*/ + for ( i = 0; i <= num_decs; i++ ) { + x = i*size-offset*size2; + if ( x >= 0 && x <= dr ) { + MoveTo(x,0); LineTo(x,hashsize*1.2); Stroke; + } + } +/* + Little hash marks. +*/ + j = num_decs*numperdec+0.5; + SetLineWidth(0.6*width); + for ( i = 0; i <= j; i++ ) { + if ( (i+offset)%numperdec != 0 ) { + x = i*size2; + if ( x >= 0 && x <= dr ) { + MoveTo(x,0); LineTo(x,hashsize*0.8); Stroke; + } + } + } +} + +/* + #] LinAxis : + #[ BezierCurve : + + Draws a Bezier curve. Starts at (x1,y1). + The control points are (x2,y2),(x3,y3),(x4,y4) +*/ + +void BezierCurve(double *args) +{ + MoveTo(args[0],args[1]); + Bezier(args[2],args[3],args[4],args[5],args[6],args[7]); + Stroke; + if ( witharrow ) BezierArrow(args); +} + +/* + #] BezierCurve : + #[ DoubleBezier : + + Draws a Bezier curve. Starts at (x1,y1). + The control points are (x2,y2),(x3,y3),(x4,y4) +*/ + +void DoubleBezier(double *args) +{ + linesep = args[8]; + SaveGraphicsState; + SetLineWidth(linesep+axolinewidth); + MoveTo(args[0],args[1]); + Bezier(args[2],args[3],args[4],args[5],args[6],args[7]); + Stroke; + RestoreGraphicsState; + SaveGraphicsState; + SetLineWidth(linesep-axolinewidth); + SetBackgroundColor(STROKING); + MoveTo(args[0],args[1]); + Bezier(args[2],args[3],args[4],args[5],args[6],args[7]); + Stroke; + RestoreGraphicsState; + if ( witharrow ) BezierArrow(args); +} + +/* + #] DoubleBezier : + #[ DashBezier : + + Draws a Bezier curve. Starts at (x1,y1). + The control points are (x2,y2),(x3,y3),(x4,y4) +*/ + +void DashBezier(double *args) +{ + int numdashes; + double size, dashsize = args[8]; + size = LengthBezier(args[2]-args[0],args[3]-args[1] + ,args[4]-args[0],args[5]-args[1],args[6]-args[0],args[7]-args[1],1.0); + + numdashes = size/(2*dashsize); + if ( numdashes == 0 ) numdashes = 1; + if ( fabs(size-2*dashsize*numdashes) > fabs(size-2*dashsize*(numdashes+1)) ) + numdashes++; + dashsize = (size/(2*numdashes)); + + SetDashSize(dashsize,dashsize/2); + MoveTo(args[0],args[1]); + Bezier(args[2],args[3],args[4],args[5],args[6],args[7]); + Stroke; + if ( witharrow ) BezierArrow(args); +} + +/* + #] DashBezier : + #[ DashDoubleBezier : + + Draws a Bezier curve. Starts at (x1,y1). + The control points are (x2,y2),(x3,y3),(x4,y4) +*/ + +void DashDoubleBezier(double *args) +{ + int numdashes; + double size, dashsize = args[9]; + size = LengthBezier(args[2]-args[0],args[3]-args[1] + ,args[4]-args[0],args[5]-args[1],args[6]-args[0],args[7]-args[1],1.0); + + numdashes = size/(2*dashsize); + if ( numdashes == 0 ) numdashes = 1; + if ( fabs(size-2*dashsize*numdashes) > fabs(size-2*dashsize*(numdashes+1)) ) + numdashes++; + dashsize = (size/(2*numdashes)); + + SetDashSize(dashsize,dashsize/2); + linesep = args[8]; + SaveGraphicsState; + SetLineWidth(linesep+axolinewidth); + MoveTo(args[0],args[1]); + Bezier(args[2],args[3],args[4],args[5],args[6],args[7]); + Stroke; + RestoreGraphicsState; + SaveGraphicsState; + SetLineWidth(linesep-axolinewidth); + SetBackgroundColor(STROKING); + MoveTo(args[0],args[1]); + Bezier(args[2],args[3],args[4],args[5],args[6],args[7]); + Stroke; + RestoreGraphicsState; + if ( witharrow ) BezierArrow(args); +} + +/* + #] DashDoubleBezier : + #] Drawing routines : + #[ Wrapper routines : + #[ AxoArc : + + Draws arc centered at (#1,#2), radius #3, starting and ending + angles #4, #5. + Double, dashing, arrow, flip, clockwise +*/ + +void AxoArc(double *args) +{ + double dashsize = args[6]; + linesep = args[5]; + GetArrow(args+7); + if ( args[16] ) { /* If clockwise: reverse the angles and the arrow */ + double e; + clockwise = 1; /* In principle not needed */ + flip = 1-flip; + arrow.where = 1-arrow.where; + e = args[3]; args[3] = args[4]; args[4] = e; + } + + if ( witharrow ) { + if ( arrow.where > 1 ) arrow.where = 1; + if ( arrow.where < 0 ) arrow.where = 0; + if ( dashsize > 0 ) { + if ( linesep > 0 ) { + DashArrowDoubleArc(args); + } + else { + args[5] = args[6]; + DashArrowArc(args); + } + } + else { + if ( linesep > 0 ) { + ArrowDoubleArc(args); + } + else { + ArrowArc(args); + } + } + } + else { + if ( dashsize > 0 ) { + if ( linesep > 0 ) { + DashDoubleArc(args); + } + else { + args[5] = args[6]; + DashCArc(args); + } + } + else { + if ( linesep > 0 ) { + DoubleArc(args); + } + else { + CArc(args); + } + } + } +} + +/* + #] AxoArc : + #[ AxoBezier : +*/ + +void AxoBezier(double *args) +{ + linesep = args[8]; + GetArrow(args+10); + if ( witharrow ) { + if ( arrow.where > 1 ) arrow.where = 1; + if ( arrow.where < 0 ) arrow.where = 0; + } + if ( args[9] ) { /* dashes */ + if ( args[8] ) { /* double */ + DashDoubleBezier(args); + } + else { + args[8] = args[9]; + DashBezier(args); + } + } + else { + if ( args[8] ) { /* double */ + DoubleBezier(args); + } + else { + BezierCurve(args); /* The name Bezier was already taken */ + } + } +} + +/* + #] AxoBezier : + #[ AxoGluon : +*/ + +void AxoGluon(double *args) +{ + SetLineWidth(axolinewidth + args[6]); + if ( args[7] ) { /* dashes */ + args[6] = args[7]; + DashGluon(args); + } + else { + Gluon(args); + } +} + +/* + #] AxoGluon : + #[ AxoGluonArc : +*/ + +void AxoGluonArc(double *args) +{ + SetLineWidth(axolinewidth + args[7]); + if ( args[9] ) { /* Clockwise */ + double a = args[3]; args[3] = args[4]; args[4] = a; + } + if ( args[8] ) { /* Dashes */ + args[7] = args[8]; + DashGluonArc(args); + } + else { + GluonArc(args); + } +} + +/* + #] AxoGluonArc : + #[ AxoGluonCirc : +*/ + +void AxoGluonCirc(double *args) +{ + SetLineWidth(axolinewidth + args[6]); + if ( args[7] ) { /* dashes */ + args[6] = args[7]; + DashGluonCirc(args); + } + else { + GluonCirc(args); + } +} + +/* + #] AxoGluonCirc : + #[ AxoLine : + + AxoLine(x1,y1)(x2,y2){sep}{dashsize}{stroke width length inset}{where} + + Generic switchyard to the various routines for compatibility + with Jaxodraw and axodraw4j + + Note: because the specific routines can be called either in the + direct way or by means of the generic routine, they have to know + what arrow to use. This is regulated by arrow.type. 0=old arrows. +*/ + +void AxoLine(double *args) +{ + linesep = args[4]; + GetArrow(args+6); + if ( witharrow ) { + if ( arrow.where > 1 ) arrow.where = 1; + if ( arrow.where < 0 ) arrow.where = 0; + if ( args[5] == 0 ) { + if ( linesep == 0 ) ArrowLine(args); + else { ArrowDoubleLine(args); } + } + else { + if ( linesep == 0 ) { + args[4] = args[5]; + DashArrowLine(args); + } + else { DashArrowDoubleLine(args); } + } + } + else { + if ( args[5] == 0 ) { /* No dashing */ + if ( linesep == 0 ) Line(args); + else DoubleLine(args); + } + else { + if ( linesep == 0 ) { + args[4] = args[5]; DashLine(args); + } + else DashDoubleLine(args); + } + } +} + +/* + #] AxoLine : + #[ AxoPhoton : +*/ + +void AxoPhoton(double *args) +{ + if ( args[7] ) { /* dashes */ + if ( args[6] ) { /* double */ + DashDoublePhoton(args); + } + else { + args[6] = args[7]; + DashPhoton(args); + } + } + else { + if ( args[6] ) { /* double */ + DoublePhoton(args); + } + else { + Photon(args); + } + } +} + +/* + #] AxoPhoton : + #[ AxoPhotonArc : +*/ + +void AxoPhotonArc(double *args) +{ + if ( args[9] ) { /* Clockwise */ + int num = 2*args[6]+0.5; + double a = args[3]; args[3] = args[4]; args[4] = a; + if ( ( num & 1 ) == 0 ) args[5] = -args[5]; + } + if ( args[8] ) { /* dash */ + if ( args[7] ) { /* double */ + DashDoublePhotonArc(args); + } + else { + args[7] = args[8]; + DashPhotonArc(args); + } + } + else { + if ( args[7] ) { /* double */ + DoublePhotonArc(args); + } + else { + PhotonArc(args); + } + } +} + +/* + #] AxoPhotonArc : + #[ AxoZigZag : +*/ + +void AxoZigZag(double *args) +{ + if ( args[7] ) { /* dashes */ + if ( args[6] ) { /* double */ + DashDoubleZigZag(args); + } + else { + args[6] = args[7]; + DashZigZag(args); + } + } + else { + if ( args[6] ) { /* double */ + DoubleZigZag(args); + } + else { + ZigZag(args); + } + } +} + +/* + #] AxoZigZag : + #[ AxoZigZagArc : +*/ + +void AxoZigZagArc(double *args) +{ + if ( args[9] ) { /* Clockwise */ + int num = 2*args[6]+0.5; + double a = args[3]; args[3] = args[4]; args[4] = a; + if ( ( num & 1 ) == 0 ) args[5] = -args[5]; + } + if ( args[8] ) { /* dash */ + if ( args[7] ) { /* double */ + DashDoubleZigZagArc(args); + } + else { + args[7] = args[8]; + DashZigZagArc(args); + } + } + else { + if ( args[7] ) { /* double */ + DoubleZigZagArc(args); + } + else { + ZigZagArc(args); + } + } +} + +/* + #] AxoZigZagArc : + #] Wrapper routines : + #[ Various routines : + #[ Rotate : + + + Rotate: x y angle hmode vmode textwidth textheight + Note, the textwidth/textheight have been scaled already; +*/ + +void Rotate(double *args) +{ + double textheight = args[6]*args[4]/2/65536.; + double textwidth = args[5]*args[3]/2/65536.; + SetTransferMatrix(1,0,0,1,args[0],args[1]); + SetTransferMatrix(COS(args[2]),SIN(args[2]),-SIN(args[2]),COS(args[2]),0,0); + SetTransferMatrix(1,0,0,1,-textwidth,textheight); +} + +/* + #] Rotate : + #[ Grid : + + Makes a coordinate grid in the indicated color. + (x0,y0)(incx,incy)(nx,ny){color}{linewidth} +*/ + +void Grid(double *args) +{ + int i, nx = args[4]+0.01, ny = args[5]+0.01; + double maxx = args[2]*args[4]; + double maxy = args[3]*args[5]; + SetTransferMatrix(1,0,0,1,args[0],args[1]); + for ( i = 0; i <= nx; i++ ) { + MoveTo(i*args[2],0); + LineTo(i*args[2],maxy); + Stroke; + } + for ( i = 0; i <= ny; i++ ) { + MoveTo(0,i*args[3]); + LineTo(maxx,i*args[3]); + Stroke; + } +} + +/* + #] Grid : + #] Various routines : + #] routines : +*/ diff --git a/Master/texmf-dist/tex/latex/axodraw2/axodraw2.sty b/Master/texmf-dist/tex/latex/axodraw2/axodraw2.sty new file mode 100644 index 00000000000..b8dba9b5aad --- /dev/null +++ b/Master/texmf-dist/tex/latex/axodraw2/axodraw2.sty @@ -0,0 +1,4728 @@ +% This is axodraw2.sty +% +% (C) 1994-2016 by authors: +% John Collins (jcc8 at psu dot edu) +% Jos Vermaseren (t68 at nikhef dot nl) +% +% +% Conditions of use: +% +% axodraw is free software: you can redistribute it and/or modify it under +% the terms of the GNU General Public License as published by the Free +% Software Foundation, either version 3 of the License, or (at your option) +% any later version. +% +% axodraw is distributed in the hope that it will be useful, but WITHOUT ANY +% WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +% FOR A PARTICULAR PURPOSE. See the GNU General Public License for more +% details. +% +% For the GNU General Public License see <http://www.gnu.org/licenses/>. +% +% Code necessities: +% +% 1. \ignorespaces at end of commands that draw things. Often it won't +% matter, but occasionally a command in a picture environment +% will set material and a following uncommented end-of-line in +% the user's code will shift the insertion point. +% 2. Use end-of-line comments whereever TeX might use the end-of-line as +% a space to be typeset. +% +% Conventions +% +% 1. Any font and color changes that are supposed to be local should +% be made local, either by explicit TeX grouping or by being +% inside commands (e.g., box-making commands) that enforce groups. +% Braces work, but \begingroup and \endgroup are easier to see in +% multiline groups. +% 2. Scaling: +% \unitlength is the unit for the canvas (as in picture environment). +% \axoscale is for the unit for coordinates, widths, etc +% \axotextscale is for all text objects, BUT only when +% PSText is NOT set to scale as graphics objects +% When PSText is set to scale as graphics objects, PSText +% scales by \axoscale, but TeX-text has unit scaling. +% Given a specification of a position (x,y) as in a call to \Line, +% the position of the point relative to the origin is +% x_act = (x + \axoxo ) \axoscale pt + \axoxoffset \unitlength +% y_act = (y + \axoyo ) \axoscale pt + \axoyoffset \unitlength +% Widths and the like for lines are in units of \axoscale pt +% +% #[ About folds : (this line starts with one % and two tabs) +% +% The internals of the file have been organized in folds. +% These are defined as a range of lines if which the first and last +% lines have a special format. Each starts with any three characters +% (may include tabs), then #[ for the start line and #] for the closing +% line, then both lines need identical name fields, closed by a colon. +% After the colon can be anything. When a fold is closed one should see +% only the first line but with the #[ replaced by ## as in +% ## About folds : (this line starts with one % and two tabs) +% Folds can be nested. +% This fold concept comes originally from the occam compiler for the +% transputer in the second half of the 1980's although there it was +% implemented differently. It was taken over by the STedi editor in its +% current form. The sources of this editor are available from the form +% home site: http://www.nikhef.nl/~form +% Some people have managed to emulate these folds in editors like emacs +% and vim. +% +% #] About folds : +% +\ProvidesPackage{axodraw2}[2016/06/02 v2.1.0b] +% +% axodraw.sty file, both for .tex -> .dvi -> .ps and for .tex -> .pdf +% +% #[ Common LaTeX code : +% #[ Variables : +% +% +\RequirePackage{keyval} +\RequirePackage{ifthen} +\RequirePackage{graphicx} +\RequirePackage{color} +\RequirePackage{ifxetex} +% +% +\DeclareOption{v1compatible}{ + \def\B2Text{\BTwoText} + \def\G2Text{\GTwoText} + \def\C2Text{\CTwoText} +} +\DeclareOption{canvasScaleIs1pt}{\canvasScaleOnept} +\DeclareOption{canvasScaleIsObjectScale}{\canvasScaleObjectScale} +\DeclareOption{canvasScaleIsUnitLength}{\canvasScaleUnitLength} +\DeclareOption{PSTextScalesIndependently}{\PSTextScalesLikeGraphicsfalse} +\DeclareOption{PSTextScalesLikeGraphics}{\PSTextScalesLikeGraphicstrue} + +% N.B. Option processing is deferred to end of this file, so that all +% definitions and initializations have been done first. + +% Settings for pdf v. dvi/ps output: +% We need to be able to run under latex, pdflatex, lualatex, and +% xelatex, and use (if possible) \pdfoutput and \pdfliteral +% +% latex: Initially \pdfoutput is 0, and \pdfliteral is defined but +% not usable. +% pdflatex: Initially \pdfoutput is 1, and \pdfliteral is defined and +% usable. +% lualatex: same as pdflatex in versions up to 0.80 +% But in versions from 0.85, pdfouput and pdfliteral aren't +% defined; instead \outputmode, \pdfextension literal{...} +% are available instead. +% xelatex: Both \pdfoutput and \pdfliteral are undefined +% but special{pdf:literal ...} gives same effect as +% \pdfliteral would, and we can assume pdf mode always. +% When \pdfoutput is defined, the user can change its value to change +% the type of output. This must be done before the first page is +% created. But various packages (including graphics and ifpdf, as +% well as axodraw) take actions when the package is loaded that depend +% on current state of \pdfoutput (or its equivalent). So it is +% reasonable to require that \pdfoutput be set only before packages +% are loaded and not set later. +% +% We define \axo@pdfoutput and \axo@pdfliteral for our uses to have +% function of \pdfoutput and \pdfliteral, but to be defined always. +% We initialize them to a default suitable for dvi mode, and override +% these definitions to cover the situations listed above. This needs +% tests for whether \pdfoutput, \outputmode, etc are undefined of +% defined. We put these inside a group, to evade the side effect that +% \@ifundefined defines the object being tested. +% +% Default values: +\newcount\axo@pdfoutput +\axo@pdfoutput=0 +\def\axo@pdfliteral#1% + {\PackageWarning{axo}{Bug: pdfliteral accessed but not available}} +\bgroup + \@ifundefined{pdfoutput}% + {}% + {\global\axo@pdfoutput=\pdfoutput}% + % + \@ifundefined{pdfliteral}% + {}% + {% Define \axo@pdfliteral to call \pdfliteral, so that if the + % definition of \pdfliteral were to be overridden, we get to + % use the changed definition + \gdef\axo@pdfliteral#1{\pdfliteral{#1}}}% + \@ifundefined{outputmode}% + {}% + {\global\axo@pdfoutput=\outputmode} + \@ifundefined{pdfextension}% + {}% + {\gdef\axo@pdfliteral#1{\pdfextension literal{#1}}} +\egroup +\ifxetex + \axo@pdfoutput=1 + \def\axo@pdfliteral#1{\special{pdf:literal #1}} +\fi + +% +% For communicating with axohelp with global file +% +\newif\ifaxo@axohelpRerun +\axo@axohelpRerunfalse +% +\newcounter{axo@objectIndex} +\setcounter{axo@objectIndex}{0} +\newwrite\axo@spec +\newread\axo@axohelpFile +% +\newcommand\axo@setObject[3]{ + \expandafter\gdef\csname axo@input@#1\endcsname{#2} + \expandafter\gdef\csname axo@output@#1\endcsname{#3} +} +% +\ifcase\axo@pdfoutput +\else + \IfFileExists{\jobname.ax2}% + {{% For comparisons between current definition of object + % and previously processed definition, spaces must be preserved. + \obeyspaces + \openin\axo@axohelpFile=\jobname.ax2 + }}% + {% + \PackageWarning{axo}{File `\jobname.ax2' not found.} + \axo@axohelpReruntrue + } + \AtBeginDocument{\immediate\openout\axo@spec\jobname.ax1} + \AtEndDocument{\immediate\closeout\axo@spec + \ifaxo@axohelpRerun + \PackageWarning{axodraw2}{Run `axohelp \jobname' + and then rerun pdflatex.} + \fi + } +\fi + +% Commands to set parameters +% +% Arrow scale: +\newcommand{\AXO@DefaultArrowScale}{1} +\newcommand\SetArrowScale[1]{% + \renewcommand\AXO@DefaultArrowScale{#1}% +} +% Alternative name +\newcommand\DefaultArrowScale[1]{\SetArrowScale{#1}} +\SetArrowScale{1} + +% Arrow inset: +\newcommand\AXO@ArrowInset{0.2} +%\renewcommand\AXO@ArrowInset{-1 } +\newcommand\SetArrowInset[1]{% + \renewcommand\AXO@ArrowInset{#1}% +} + +% Arrow aspect: +\newcommand\AXO@DefaultArrowAspect{1.25} +\newcommand\SetArrowAspect[1]{% + \renewcommand\AXO@DefaultArrowAspect{#1}% +} + +% Arrow position (fractional position along line): +\newcommand\AXO@ArrowPos{0.5} +\newcommand\SetArrowPosition[1]{% + \renewcommand\AXO@ArrowPos{#1}% +} + +% Arrow stroke width +\newcommand{\AXO@DefaultArrowStroke}{0 } +\newcommand\SetArrowStroke[1]{% + \renewcommand\AXO@DefaultArrowStroke{#1}% +} + +\newlength{\axounitlength} +% The next two are scratch registers +\newlength\axo@x +\newlength\axo@y +% Initializations +\axounitlength=\unitlength +\def\axocanvas{1} % How unitlength is set in axopicture environment + % 0 => 1 pt + % 1 => \axoscale pt + % 2 => Don't set it +\def\axominusone{-1} +\def\axoone{1} +\def\axozero{0} +\def\axowidth{0.5} +\def\axoscale{1.0} +\def\axotextscale{1.0} +\newif\ifPSTextScalesLikeGraphics +\PSTextScalesLikeGraphicstrue +\def\axoxoff{0} +\def\axoyoff{0} +\def\axoxo{0} +\def\axoyo{0} +\def\axoarrowsize{2} +% +% +% Now the user callable routines, and their immediate helpers +% +% Commands for setting parameters applicable to subsequent graphical objects: +% +\def\SetLineSep#1{\def\AXO@Sep{#1}\ignorespaces}\relax +\let\SetSep=\SetLineSep\relax +\def\SetDashSize#1{\def\AXO@DashSize{#1}\ignorespaces}\relax +\def\SetWidth#1{\def\axowidth{#1}\ignorespaces} +\def\SetArrowSize#1{\def\axoarrowsize{#1}} + +\def\SetObjectScale#1{\def\axoscale{#1}\ignorespaces} +\def\SetCanvasScale#1{\unitlength = #1 pt\ignorespaces} +\def\SetTextScale#1{\def\axotextscale{#1}\ignorespaces} +\let\SetScale = \SetObjectScale + +\def\SetOffset(#1,#2){\def\axoxoff{#1}\def\axoyoff{#2}\ignorespaces} +\def\SetScaledOffset(#1,#2){\def\axoxo{#1}\def\axoyo{#2}\ignorespaces} + +\def\canvasScaleOnept{\def\axocanvas{0}} +\def\canvasScaleObjectScale{\def\axocanvas{1}} +\def\canvasScaleUnitLength{\def\axocanvas{2}} + +% +% +% #] Variables : +% #[ Defining commands with optional arguments : +% +\def\defWithOption#1#2#3{% + \@namedef{#1}% + {% + \@ifnextchar[%] + {\@nameuse{#1@A}}% + {\@nameuse{#1@A}[]}% + }% + \@namedef{#1@A}[##1]#2% + {#3}% +} +% +% #] Defining commands with optional arguments : +% #[ axopicture : +% +% Version of picture environment with unitlength set to 1pt +% as assumed by axodraw. We also store some variables and reset them +% afterwards. This makes the picture environment also local from the +% axodraw viewpoint. To change the global settings one should issue +% the corresponding command from outside the axopicture environment. +% Use: \begin{axopicture}(width,height)(xshift,yshift) +% \end{axopicture} +% The old use with the regular picture environment will still work, +% but it will have the old shortcomings connected to it. +% +\let\OLDpicture=\picture +\let\endOLDpicture=\endpicture +\newenvironment{axopicture} +{% + \ifcase \axocanvas + \setlength{\unitlength}{1 pt}% + \or + \setlength{\unitlength}{\axoscale\space pt}% + \else + % Leave \unitlength as whatever the user set + \fi + \begin{OLDpicture}% +} +{% + \end{OLDpicture}% + \ignorespacesafterend +} +% +% #] axopicture : +% #[ AXO@keys : +% + +% Diagnostics for unimplemented features: +\newif\ifAXONotImplemented +\AXONotImplementedfalse +\def\AXO@NOTIMPLEMENTED#1{% + \global\AXONotImplementedtrue + \PackageWarning{axodraw2}{#1}% +} +\AtEndDocument{% + \ifAXONotImplemented + \PackageWarningNoLine{axodraw2}{unimplemented features used + somewhere in document}% + \fi +} + +% The next is used temporarily, it gives the result of parsing an +% arrow-using command to give the Postscript code for setting the +% arrow. +% +% Keys for optional arguments: +% First the variables used, with some defaults. +\newif\ifAXO@arrow +\AXO@arrowfalse +\newif\ifAXO@clock +\AXO@clockfalse +\newif\ifAXO@dash +\AXO@dashfalse +\newif\ifAXO@double +\AXO@doublefalse +\newif\ifAXO@flip % Flip arrow orientation, as in JaxoDraw +\AXO@flipfalse +\newif\ifAXO@linecolor % Option sets color for current line +\AXO@linecolorfalse + +\def\AXO@Sep{2} % Double line separation +\def\AXO@DashSize{3} + +% Then the definitions of the keys +\define@key{axo}{arrowscale}{% + \def\AXO@CurrentArrowScale{#1}% +} +\define@key{axo}{arrowwidth}{% + \def\AXO@CurrentArrowWidth{#1}% +} +\define@key{axo}{arrowlength}{% + \def\AXO@CurrentArrowLength{#1}% +} +% Make arrowheight a synonym for arrowlength +\let\KV@axo@arrowheight=\KV@axo@arrowlength +% +\define@key{axo}{arrowpos}{% + \def\AXO@CurrentArrowPos{#1 } +} +% +\define@key{axo}{arrowaspect}{% + \def\AXO@CurrentArrowAspect{#1 } +} +% +\define@key{axo}{arrowinset}{% + \def\AXO@CurrentArrowInset{#1 } +} +% Make inset a synonym for arrowinset +\let\KV@axo@inset=\KV@axo@arrowinset +% +\define@key{axo}{arrowstroke}{% + \def\AXO@CurrentArrowStroke{#1 } +} +% +\define@key{axo}{arrow}[true]{% + \AXO@boolkey{#1}{arrow}% +} +\define@key{axo}{clock}[true]{% + \AXO@boolkey{#1}{clock}% +} +\define@key{axo}{clockwise}[true]{% + \AXO@boolkey{#1}{clock}% +} +\define@key{axo}{color}{% + \def\AXO@CurrentColor{#1}% + \AXO@linecolortrue +} +% Make colour a synonym for color +\let\KV@axo@colour=\KV@axo@color +% +\define@key{axo}{dash}[true]{% + \AXO@boolkey{#1}{dash}% +} +\define@key{axo}{dashsize}{% + \def\AXO@CurrentDashSize{#1 } +} +\define@key{axo}{dsize}{% + \def\AXO@CurrentDashSize{#1 } +} +\define@key{axo}{double}[true]{% + \AXO@boolkey{#1}{double}% +} +\define@key{axo}{flip}[true]{% + \AXO@boolkey{#1}{flip}% +} +\define@key{axo}{linesep}{% + \def\AXO@CurrentSep{#1} +} +\define@key{axo}{sep}{% + \def\AXO@CurrentSep{#1} +} +\define@key{axo}{width}{% + \def\AXO@CurrentWidth{#1}% +} +% +% #] AXO@keys : +% #[ AXO@Parse : +% +% Parsing of optional arguments, etc +% +\def\AXO@Parse#1#2{% + % Usage: \AXO@Parse#1#2 or \AXO@Parse#1#2[#3] + % #1 is a command for setting an object, that takes no optional argument + % #2 and the optional #3 are keyword settings. + % There then follow the compulsory arguments for the command in #1. + % + % E.g., \AXO@Parse{\AXO@Line}{double}(x1,y1)(x2,y2) + % \AXO@Parse{\AXO@Line}{double}[arrow](x1,y1)(x2,y2) + % + % I will + % (a) Set standard initial settings (arrows, etc) + % (b) Parse the keyword settings in #2 and #3, e.g., scale = 3, + % (c) Call #1 to make the object + \AXO@arrowfalse + \AXO@clockfalse + \AXO@dashfalse + \AXO@doublefalse + \AXO@flipfalse + \AXO@linecolorfalse + \let\AXO@CurrentWidth\axowidth + \let\AXO@CurrentArrowPos\AXO@ArrowPos + \let\AXO@CurrentArrowWidth\relax + \let\AXO@CurrentArrowLength\relax + \let\AXO@CurrentArrowInset\AXO@ArrowInset + \let\AXO@CurrentArrowScale\AXO@DefaultArrowScale + \let\AXO@CurrentArrowStroke\AXO@DefaultArrowStroke + \let\AXO@CurrentArrowAspect\AXO@DefaultArrowAspect + \let\AXO@CurrentDashSize\AXO@DashSize + \let\AXO@CurrentSep=\AXO@Sep + \@ifnextchar[{\AXO@Options{#1}{#2}}% + {\AXO@Options{#1}{#2}[]}% +} +% +% #] AXO@Parse : +% #[ AXO@Options : +% +\def\AXO@Options#1#2[#3]{% + % #1 is command to execute, #2 and #3 are options. + \setkeys{axo}{#2}% + \setkeys{axo}{#3}% + \ifx\AXO@CurrentArrowLength\relax + \def\AXO@CurrentArrowLength{0 }% + \fi + \ifx\AXO@CurrentArrowWidth\relax + \def\AXO@CurrentArrowWidth{0 }% + \fi + \ifAXO@arrow + \def\AXO@ArrowArg{ + \AXO@CurrentArrowStroke \space % + \AXO@CurrentArrowWidth \space % + \AXO@CurrentArrowLength \space % + \AXO@CurrentArrowInset \space % + \AXO@CurrentArrowScale \space % + \AXO@CurrentArrowAspect \space % + \AXO@CurrentArrowPos \space % + \ifcase\axo@pdfoutput + true \space % Indicates that an arrow should be drawn. + \else + 1 \space % Indicates that an arrow should be drawn. + \fi + }% + \else + \ifcase\axo@pdfoutput + \def\AXO@ArrowArg{ 0 0 0 0 0 0 0 false }% + \else + \def\AXO@ArrowArg{ 0 0 0 0 0 0 0 0 }% + \fi + \fi + #1% +} +% +\def\AXO@useopts{% + % Override global settings by those from options + % HACK: The \@killglue solves problem that setting color + % causes a shift in horizontal position. + % Motivation: From definition of \put. + \@killglue + \ifAXO@linecolor \SetColor{\AXO@CurrentColor}\fi +} +% +% Now ensure there is a setting for the current arrow +\AXO@Parse{}{} +% +% #] AXO@Options : +% #[ AXO@varia : +% +% Now ensure there is a setting for the current arrow +\AXO@Parse{}{} + +\def\AXO@PrependOption#1#2{% + % Run command #1, which has an optional argument, with #2 prepended + % to the command's optional arguments. If there are no optional + % arguments, just run the command with #2 as the optional arguments + \@ifnextchar[{\AXO@TwoOption{#1}{#2}}% + {#1[#2]}% +} +\def\AXO@TwoOption#1#2[#3]{% + #1[#2,#3]% +} +% +% Copied from graphicx.sty, for use with boolean keys +% Modified to do lower casing here +\def\AXO@boolkey#1#2{% + \lowercase{\AXO@boolkeyA{#1}}{#2}% +} +\def\AXO@boolkeyA#1#2{% + \csname AXO@#2\ifx\relax#1\relax true\else#1\fi\endcsname +} +% +% #] AXO@varia : +% #[ Colors : +% +% Here we make an interface, compatible with both: color.sty, +% with the commands of axodraw v. 1, and with the commands of +% colordvi.sty (used by axodraw v. 1). +% +% 1. We make a set of named colors suitable for use with both +% axodraw's commands that take color arguments and with +% color.sty's \color command. +% 2. We define a command \SetColor to set a named color as the +% current color. It is now identical to \color. +% 3. For each of the colors that we define here, we make +% named color setting commands, e.g., \Red +% \textRed. \Red sets its (one) argument in Red, \textRed +% is a "declaration" that changes the current color. +% All the commands for setting color apply to both regular LaTeX +% material and to axodraw objects. Their setting of color +% respects LaTeX environments and TeX groups. +% +% We also define +% a. Named-color commands like \textRed and \Red for named +% colors to give the same interface as the colordvi +% package (and hence axodraw v. 1). +% b. \SetColor command to set a named color. + + +\let\SetColor=\color + +% For v. 1 compatibility: +\def\IfColor#1#2{#1} + +\newcommand\newcolor[2]{% + % Define a named color both in the color.sty style + % and in the colordvi.sty, with also a command giving the CMYK value. + % #1 is the color's name, #2 is its CMYK definition, space + % separated. + % + % Invoke color.sty's \definecolor after change of argument format: + \axo@new@color #1 #2\@% + % Define commands to use this color, + % E.g., if #1 is Red, then define \Red and \textRed: + \expandafter\def\csname #1\endcsname##1{{\SetColor{#1}##1}\ignorespaces} + \expandafter\def\csname text#1\endcsname{\SetColor{#1}\ignorespaces} + % The following to give the cmyk value of a color, e.g., \cmykRed, + % is no longer needed, since we no longer do color setting in + % postscript and pdf code: +%% \expandafter\def\csname cmyk#1\endcsname{#2} +} + +% Command to invoke color.sty's \definecolor, which needs a translation +% of our space-separated CMYK vector to a comma-separated vector: +\def\axo@new@color #1 #2 #3 #4 #5\@{\definecolor{#1}{cmyk}{#2,#3,#4,#5}} + + +% For consistency we define our named colors here, rather than +% using color.sty's mechanisms. The +% first 68 are standard colors, as defined by dvips, and +% implemented in both colordvi.ps, and in color.sty with its +% usenames and dvipsnames options (in the file dvipsnam.def +% provided by the LaTeX graphics package). +% +% We define an extra 5 colors at the end +% +% The 68 dvips-defined colors are: +% +\newcolor{GreenYellow}{0.15 0 0.69 0} +\newcolor{Yellow}{0 0 1 0} +\newcolor{Goldenrod}{0 0.10 0.84 0} +\newcolor{Dandelion}{0 0.29 0.84 0} +\newcolor{Apricot}{0 0.32 0.52 0} +\newcolor{Peach}{0 0.50 0.70 0} +\newcolor{Melon}{0 0.46 0.50 0} +\newcolor{YellowOrange}{0 0.42 1 0} +\newcolor{Orange}{0 0.61 0.87 0} +\newcolor{BurntOrange}{0 0.51 1 0} +\newcolor{Bittersweet}{0 0.75 1 0.24} +\newcolor{RedOrange}{0 0.77 0.87 0} +\newcolor{Mahogany}{0 0.85 0.87 0.35} +\newcolor{Maroon}{0 0.87 0.68 0.32} +\newcolor{BrickRed}{0 0.89 0.94 0.28} +\newcolor{Red}{0 1 1 0} +\newcolor{OrangeRed}{0 1 0.50 0} +\newcolor{RubineRed}{0 1 0.13 0} +\newcolor{WildStrawberry}{0 0.96 0.39 0} +\newcolor{Salmon}{0 0.53 0.38 0} +\newcolor{CarnationPink}{0 0.63 0 0} +\newcolor{Magenta}{0 1 0 0} +\newcolor{VioletRed}{0 0.81 0 0} +\newcolor{Rhodamine}{0 0.82 0 0} +\newcolor{Mulberry}{0.34 0.90 0 0.02} +\newcolor{RedViolet}{0.07 0.90 0 0.34} +\newcolor{Fuchsia}{0.47 0.91 0 0.08} +\newcolor{Lavender}{0 0.48 0 0} +\newcolor{Thistle}{0.12 0.59 0 0} +\newcolor{Orchid}{0.32 0.64 0 0} +\newcolor{DarkOrchid}{0.40 0.80 0.20 0} +\newcolor{Purple}{0.45 0.86 0 0} +\newcolor{Plum}{0.50 1 0 0} +\newcolor{Violet}{0.79 0.88 0 0} +\newcolor{RoyalPurple}{0.75 0.90 0 0} +\newcolor{BlueViolet}{0.86 0.91 0 0.04} +\newcolor{Periwinkle}{0.57 0.55 0 0} +\newcolor{CadetBlue}{0.62 0.57 0.23 0} +\newcolor{CornflowerBlue}{0.65 0.13 0 0} +\newcolor{MidnightBlue}{0.98 0.13 0 0.43} +\newcolor{NavyBlue}{0.94 0.54 0 0} +\newcolor{RoyalBlue}{1 0.50 0 0} +\newcolor{Blue}{1 1 0 0} +\newcolor{Cerulean}{0.94 0.11 0 0} +\newcolor{Cyan}{1 0 0 0} +\newcolor{ProcessBlue}{0.96 0 0 0} +\newcolor{SkyBlue}{0.62 0 0.12 0} +\newcolor{Turquoise}{0.85 0 0.20 0} +\newcolor{TealBlue}{0.86 0 0.34 0.02} +\newcolor{Aquamarine}{0.82 0 0.30 0} +\newcolor{BlueGreen}{0.85 0 0.33 0} +\newcolor{Emerald}{1 0 0.50 0} +\newcolor{JungleGreen}{0.99 0 0.52 0} +\newcolor{SeaGreen}{0.69 0 0.50 0} +\newcolor{Green}{1 0 1 0} +\newcolor{ForestGreen}{0.91 0 0.88 0.12} +\newcolor{PineGreen}{0.92 0 0.59 0.25} +\newcolor{LimeGreen}{0.50 0 1 0} +\newcolor{YellowGreen}{0.44 0 0.74 0} +\newcolor{SpringGreen}{0.26 0 0.76 0} +\newcolor{OliveGreen}{0.64 0 0.95 0.40} +\newcolor{RawSienna}{0 0.72 1 0.45} +\newcolor{Sepia}{0 0.83 1 0.70} +\newcolor{Brown}{0 0.81 1 0.60} +\newcolor{Tan}{0.14 0.42 0.56 0} +\newcolor{Gray}{0 0 0 0.50} +\newcolor{Black}{0 0 0 1} +\newcolor{White}{0 0 0 0} +% +% Our extra colors +% +\newcolor{LightYellow}{0 0 0.7 0} +\newcolor{LightRed}{0 0.75 0.7 0} +\newcolor{LightBlue}{0.7 0.5 0 0} +\newcolor{LightGray}{0 0 0 0.1} +\newcolor{VeryLightBlue}{0.15 0.07 0 0} +% +\SetColor{Black} +% +% #] Colors : +% #] Common LaTeX code : +% #[ LaTeX primitives : +% +% #[ Putting material +% + +% Some utilities that remove extra space that creeps in, particularly +% when extra groups are inserted before the use of \put. +% Use the definition of \@killglue used in latex.ltx for \put, +% but copy it here, since \@killglue is internal and not documented. +\gdef\AXO@killglue{\unskip\@whiledim \lastskip >\z@\do{\unskip}} + +% Special purpose versions of \put and \special +\long\gdef\putLen(#1,#2)#3{% + % Like LaTeX's \put, except that #1 and #2 are lengths instead of numbers + % giving lengths in units of \unitlength. + \AXO@killglue\raise#2\relax + \hbox to 0pt{\kern#1\relax #3\hss}% + \ignorespaces +} +% +\def\AxoPut(#1,#2)#3{% + % Like \put, but shifted by axodraw's offsets. + % This provides a way of coding the offsets in one place. + % But we are only using it in a limited set of cases so far. + \AXO@killglue + \bgroup + \axounitlength = \axoscale pt + \axo@x = \axoxoff \unitlength + \advance\axo@x by \axoxo \axounitlength + \advance\axo@x by #1 \axounitlength + \axo@y = \axoyoff \unitlength + \advance\axo@y by \axoyo \axounitlength + \advance\axo@y by #2 \axounitlength + \putLen(\axo@x,\axo@y){% + % If there are axodraw objects in #3, they should not also + % apply shifts, that would be double + % counting! Hence: + \SetOffset(0,0)% + \SetScaledOffset(0,0)% + #3% + }% + \egroup +\ignorespaces +} + +\def\AXOspecial#1{% + % Insertion of postscript code: + % Replacement for \special{" ...}, with the color initialized + % to the color befor the \special. (Ordinary \special{"...} + % initializes color to black.) + % Definitions made by \special{!...} are in dictionary SDict + % (as stated in dvips documentation), and we save color there. + \special{ps:: SDict begin savecolor end }% + \special{" restorecolor #1 }% +} + +\def\AXOputPS#1{% + % Insert postscript code after allowing for offsets. + \AxoPut(0,0){\AXOspecial{#1}}% +} + +\def\AXOputPDF#1{ + % Insert pdf code after allowing for offsets. + \AxoPut(0,0){\axo@pdfliteral{#1}}% +} + +% +% Now variables and routines for setting material in boxes (used by +% the BText etc commands. +% +\newdimen\tmpX +\newdimen\tmpY +\newsavebox{\tmpBox} +\newsavebox{\tmpBoxA} +% +\newcount\axo@tmp +\newcount\axo@tmpA +\newcount\axo@tmpB + +\newcount\bpinsp +\bpinsp = 65782 +\newcount\ptinsp +\ptinsp = 65536 + +\def\AssignDecDiv#1#2#3{% + % Assign the variable of name #1 to the result of dividing integer + % #2 by integer #3, with result as a textual decimal. Absolute + % accuracy: 0.001. + % Typical use: conversion of lengths to points and big points. + % \AssignDecDiv{cachedscale}{\unitlength}{65536} + % \AssignDecDiv{cachedscale}{\unitlength}{\ptinsp} + % to get length in points. + % Notes on conversion + % 1 sp = 2^{-16} pt = (1/65536) pt + % 1 pt = (1/72.27) in + % 1 bp = (1/72) in + % 1 sp = (1/65781.76) bp + % Use \relax at end of lines setting count registers. + % This ensures that the code works both when the arguments are + % given as numbers, e.g., \AxoDecDiv{100}{3}, as well as when they are + % given as lengths, etc, e.g., \AxoDecDiv{\unitlength}{256} + % + \axo@tmp = #2\relax + \axo@tmpA = \axo@tmp + \divide \axo@tmpA by #3\relax + \axo@tmpB=\axo@tmpA + \multiply \axo@tmpA by #3\relax + \advance \axo@tmp by -\axo@tmpA + \multiply \axo@tmp by 1000 + \divide \axo@tmp by #3\relax + \expandafter\edef\csname #1\endcsname{\the\axo@tmpB.\the\axo@tmp}% +} + +\def\SetTmpBox#1{% + % Sets the box \tmpBox to the contents of #1 set with current PS + % font and size. Sets \tmpX and \tmpY to the dimensions of the box + % plus some space around it, suitable for drawing an enclosing box. + % + % The vertical box setting numbers agree with those in axodraw's + % postscript code, but not (28 July 2014) with the axohelp pdf code. + % The reverse is true for the horizontal box settings. + % We can tweak them further. + % This is a standardized routine for use in all versions of postscript + % textbox routines. + % N.B. Use LaTeX's \sbox at first step, not TeX primitives to set + % box contents; it works properly with color. + \sbox{\tmpBox}{\UseCurrentPSFont #1}% + \tmpX = \axofontsize pt + \advance \tmpX by \wd\tmpBox + \tmpY = \axofontsize pt + \tmpY = 0.33333 \tmpY + \advance \tmpY by \ht\tmpBox + \advance \tmpY by \dp\tmpBox + \AssignDecDiv{tmpXT}{\tmpX}{\ptinsp}% + \AssignDecDiv{tmpYT}{\tmpY}{\ptinsp}% +} + +\def\SetTmpBoxTwo#1#2{% + % Equivalent of \SetTmpBox for two line commands. + % + % N.B. Use LaTeX's \sbox at first step, not TeX primitives to set + % box contents; it works properly with color. + \sbox{\tmpBox}{\UseCurrentPSFont #1}% + \sbox{\tmpBoxA}{\UseCurrentPSFont #2}% + \ifdim \wd\tmpBox > \wd\tmpBoxA + \tmpX = \wd\tmpBox + \else + \tmpX = \wd\tmpBoxA + \fi + \advance \tmpX by \axofontsize pt + \tmpY = \axofontsize pt + \setbox\tmpBox=% + \vbox{% + \lineskip = 0.1 \tmpY + \baselineskip = 1.1 \tmpY + \vskip 0.3 \tmpY + \hbox{\makebox[0pt]{\box\tmpBox}}% + \hbox{\makebox[0pt]{\box\tmpBoxA}}% + \vskip 0.3 \tmpY + }% + \tmpY = \ht\tmpBox + \advance \tmpY by \dp\tmpBox + \AssignDecDiv{tmpXT}{\tmpX}{\ptinsp}% + \AssignDecDiv{tmpYT}{\tmpY}{\ptinsp}% +} +% +% #] Putting +% #[ Point setting and using : +% +\def\SetPoint#1(#2,#3){% + % Define a named point in 2D + \@namedef{AXO@p.X@#1}{#2}% + \@namedef{AXO@p.Y@#1}{#3}% +} +\def\useX#1{% + % Use a named point + \@nameuse{AXO@p.X@#1}% +} +\def\useY#1{% + % Use a named point + \@nameuse{AXO@p.Y@#1}% +} +% +% #] Point setting and using : +% #[ Particle routines : +% #[ Gluon : +% +\def\Gluon{% +% +% Draws a gluon from (x1,y1) to (x2,y2) with amplitude and number of windings +% + \AXO@Parse{\AXO@Gluon}{}% +} +% +% #] Gluon : +% #[ DoubleGluon : +% +\defWithOption{DoubleGluon}{(#2,#3)(#4,#5)#6#7#8}{% +% +% Draws a gluon from (x1,y1) to (x2,y2) with amplitude and number of windings +% + \Gluon[double,sep=#8,#1](#2,#3)(#4,#5){#6}{#7}% +} +% +% #] DoubleGluon : +% #[ DashGluon : +% +\defWithOption{DashGluon}{(#2,#3)(#4,#5)#6#7#8}{% +% +% Draws a gluon from (x1,y1) to (x2,y2) with amplitude and number of windings +% + \Gluon[dash,dashsize=#8,#1](#2,#3)(#4,#5){#6}{#7}% +} +% +% #] DashGluon : +% #[ DashDoubleGluon : +% +\defWithOption{DashDoubleGluon}{(#2,#3)(#4,#5)#6#7#8#9}{% +% +% Draws a gluon from (x1,y1) to (x2,y2) with amplitude and number of windings +% + \Gluon[double,sep=#8,dash,dashsize=#9,#1](#2,#3)(#4,#5){#6}{#7}% +} +% +% #] DashDoubleGluon : +% #[ GluonCirc : +% +% Draws a gluon on a circle. The center of the circle is at (#1,#2) +% The radius and the phase angle are (#3,#4), #5 is the +% amplitude of the gluon, and #6 is the number of windings. +% +\def\GluonCirc{% +% +% Draws a gluon from (x1,y1) to (x2,y2) with amplitude and number of windings +% + \AXO@Parse{\AXO@GluonCirc}{}% +} +% +% #] GluonCirc : +% #[ DoubleGluonCirc : +% +\defWithOption{DoubleGluonCirc}{(#2,#3)(#4,#5)#6#7#8}{% +% +% Draws a gluon from (x1,y1) to (x2,y2) with amplitude and number of windings +% + \GluonCirc[double,sep=#8,#1](#2,#3)(#4,#5){#6}{#7}% +} +% +% #] DoubleGluonCirc : +% #[ DashGluonCirc : +% +\defWithOption{DashGluonCirc}{(#2,#3)(#4,#5)#6#7#8}{% +% +% Draws a gluon from (x1,y1) to (x2,y2) with amplitude and number of windings +% + \GluonCirc[dash,dashsize=#8,#1](#2,#3)(#4,#5){#6}{#7}% +} +% +% #] DashGluonCirc : +% #[ DashDoubleGluonCirc : +% +\defWithOption{DashDoubleGluonCirc}{(#2,#3)(#4,#5)#6#7#8#9}{% +% +% Draws a gluon from (x1,y1) to (x2,y2) with amplitude and number of windings +% + \GluonCirc[double,sep=#8,dash,dashsize=#9,#1](#2,#3)(#4,#5){#6}{#7}% +} +% +% #] DashDoubleGluonCirc : +% #[ GluonArc : +% +\def\GluonArc{% +% \GluonArc(x,y)(r,theta1,theta2){amplitude}{numwind} +% draws a gluon on an arc centered at (x,y) of radius r, starting +% at theta1, and ending at theta2, with given amplitude and +% number of windings +% + \AXO@Parse{\AXO@GluonArc}{}% +} +% +\let\GlueArc=\GluonArc % For backward compatibility +% +% #] GluonArc : +% #[ DoubleGluonArc : +% +\defWithOption{DoubleGluonArc}{(#2)(#3)#4#5#6}{% +% +% \DoubleGluonArc(x,y)(r,theta1,theta2){amplitude}{numwind}{sep} +% draws a gluon on an arc centered at (x,y) of radius r, starting +% at theta1, and ending at theta2, with given amplitude and +% number of windings +% + \GluonArc[double,sep=#6,#1](#2)(#3){#4}{#5}% +} +% +\let\DoubleGlueArc=\DoubleGluonArc % For backward compatibility +% +% #] DoubleGluonArc : +% #[ DashGluonArc : +% +\defWithOption{DashGluonArc}{(#2)(#3)#4#5#6}{% +% +% \DashGluonArc(x,y)(r,theta1,theta2){amplitude}{numwind}{dashsize} +% draws a gluon on an arc centered at (x,y) of radius r, starting +% at theta1, and ending at theta2, with given amplitude and +% number of windings +% + \GluonArc[dash,dashsize=#6,#1](#2)(#3){#4}{#5}% +} +% +\let\DashGlueArc=\DashGluonArc % For backward compatibility +% +% #] DashGluonArc : +% #[ DashDoubleGluonArc : +% +\defWithOption{DashDoubleGluonArc}{(#2)(#3)#4#5#6#7}{% +% +% \DashGluonArc(x,y)(r,theta1,theta2){amplitude}{numwind}{dashsize} +% draws a gluon on an arc centered at (x,y) of radius r, starting +% at theta1, and ending at theta2, with given amplitude and +% number of windings +% + \GluonArc[double,sep=#6,dash,dashsize=#7,#1](#2)(#3){#4}{#5}% +} +% +\let\DashDoubleGlueArc=\DashDoubleGluonArc % For backward compatibility +% +% #] DashDoubleGluonArc : +% #[ GluonArcn : +% +\defWithOption{GluonArcn}{(#2)(#3)#4#5}{% +% \GluonArcn(x,y)(r,theta1,theta2){amplitude}{numwind} +% draws a gluon on an arc centered at (x,y) of radius r, starting +% at theta1, and ending at theta2, with given amplitude and +% number of windings. The n stands for clockwise +% + \GluonArc[clockwise,#1](#2)(#3){#4}{#5}% +} +% +\let\GlueArcn=\GluonArcn % For backward compatibility +% +% #] GluonArcn : +% #[ DoubleGluonArcn : +% +\defWithOption{DoubleGluonArcn}{(#2)(#3)#4#5#6}{% +% +% \DoubleGluonArcn(x,y)(r,theta1,theta2){amplitude}{numwind}{sep} +% draws a gluon on an arc centered at (x,y) of radius r, starting +% at theta1, and ending at theta2, with given amplitude and +% number of windings. Clockwise. +% + \GluonArc[clockwise,double,sep=#6,#1](#2)(#3){#4}{#5}% +} +% +\let\DoubleGlueArcn=\DoubleGluonArcn % For backward compatibility +% +% #] DoubleGluonArcn : +% #[ DashGluonArcn : +% +\defWithOption{DashGluonArcn}{(#2)(#3)#4#5#6}{% +% +% \DashGluonArc(x,y)(r,theta1,theta2){amplitude}{numwind}{dashsize} +% draws a gluon on an arc centered at (x,y) of radius r, starting +% at theta1, and ending at theta2, with given amplitude and +% number of windings. Clockwise. +% + \GluonArc[clockwise,dash,dashsize=#6,#1](#2)(#3){#4}{#5}% +} +% +\let\DashGlueArcn=\DashGluonArcn % For backward compatibility +% +% #] DashGluonArcn : +% #[ DashDoubleGluonArcn : +% +\defWithOption{DashDoubleGluonArcn}{(#2)(#3)#4#5#6#7}{% +% +% \DashGluonArcn(x,y)(r,theta1,theta2){amplitude}{numwind}{dashsize} +% draws a gluon on an arc centered at (x,y) of radius r, starting +% at theta1, and ending at theta2, with given amplitude and +% number of windings. Clockwise. +% + \GluonArc[clockwise,double,sep=#6,dash,dashsize=#7,#1](#2)(#3){#4}{#5}% +} +% +\let\DashDoubleGlueArcn=\DashDoubleGluonArcn % For backward compatibility +% +% #] DashDoubleGluonArcn : +% #[ Photon : +% +\def\Photon{% +% \Photon[opt](x1,y1)(x2,y2){amplitude}{numwind} +% Draws a photon from (x1,y1) to (x2,y2) with given amplitude and +% number of windings +% Supported options: double, sep, linesep +% + \AXO@Parse{\AXO@Photon}{}% +} +% +% #] Photon : +% #[ DoublePhoton : +% +\defWithOption{DoublePhoton}{(#2,#3)(#4,#5)#6#7#8}{% +% +% Draws a photon from (x1,y1) to (x2,y2) with amplitude and number of windings +% + \Photon[double,sep=#8,#1](#2,#3)(#4,#5){#6}{#7}% +} +% +% #] DoublePhoton : +% #[ DashPhoton : +% +\defWithOption{DashPhoton}{(#2,#3)(#4,#5)#6#7#8}{% +% +% Draws a photon from (x1,y1) to (x2,y2) with amplitude and number of windings +% + \Photon[dash,dashsize=#8,#1](#2,#3)(#4,#5){#6}{#7}% +} +% +% #] DashPhoton : +% #[ DashDoublePhoton : +% +\defWithOption{DashDoublePhoton}{(#2,#3)(#4,#5)#6#7#8#9}{% +% +% Draws a photon from (x1,y1) to (x2,y2) with amplitude and number of windings +% + \Photon[double,sep=#8,dash,dashsize=#9,#1](#2,#3)(#4,#5){#6}{#7}% +} +% +% #] DashDoublePhoton : +% #[ PhotonArc : +% +\def\PhotonArc{% +% \PhotonArc(x,y)(r,theta1,theta2){amplitude}{numwind} +% draws a photon on an arc centered at (x,y) of radius r, starting +% at theta1, and ending at theta2, with given amplitude and +% number of windings +% + \AXO@Parse{\AXO@PhotonArc}{}% +} +% +% #] PhotonArc : +% #[ DoublePhotonArc : +% +\defWithOption{DoublePhotonArc}{(#2,#3)(#4,#5,#6)#7#8#9}{% +% +% \PhotonArc(x,y)(r,theta1,theta2){amplitude}{numwind}{sep} +% draws a photon on an arc centered at (x,y) of radius r, starting +% at theta1, and ending at theta2, with given amplitude and +% number of windings +% + \PhotonArc[double,sep=#9,#1](#2,#3)(#4,#5,#6){#7}{#8}% +} +% +% #] DoublePhotonArc : +% #[ DashPhotonArc : +% +\defWithOption{DashPhotonArc}{(#2,#3)(#4,#5,#6)#7#8#9}{% +% +% \DashPhotonArc(x,y)(r,theta1,theta2){amplitude}{numwind}{dashsize} +% draws a photon on an arc centered at (x,y) of radius r, starting +% at theta1, and ending at theta2, with given amplitude and +% number of windings +% + \PhotonArc[dash,dashsize=#9,#1](#2,#3)(#4,#5,#6){#7}{#8}% +} +% +% +% #] DashPhotonArc : +% #[ DashDoublePhotonArc : +% +\defWithOption{DashDoublePhotonArc}{(#2)(#3)#4#5#6#7}{% +% Note that there are actually ten arguments with the optional #1, +% which LaTeX/TeX can't handle. I consolidate the comma separated +% arguments into one, and then pass them to \PhotonArc +% +% \DashPhotonArc(x,y)(r,theta1,theta2){amplitude}{numwind}{dashsize} +% draws a photon on an arc centered at (x,y) of radius r, starting +% at theta1, and ending at theta2, with given amplitude and +% number of windings +% + \PhotonArc[double,sep=#6,dash,dashsize=#7,#1](#2)(#3){#4}{#5}% +} +% +% +% #] DashDoublePhotonArc : +% #[ PhotonArcn : +% +\defWithOption{PhotonArcn}{(#2,#3)(#4,#5,#6)#7#8}{% +% \PhotonArcn(x,y)(r,theta1,theta2){amplitude}{numwind} +% draws a photon on an arc centered at (x,y) of radius r, starting +% at theta1, and ending at theta2, with given amplitude and +% number of windings +% + \PhotonArc[clockwise,#1](#2,#3)(#4,#5,#6){#7}{#8}% +} +% +% #] PhotonArcn : +% #[ DoublePhotonArcn : +% +\defWithOption{DoublePhotonArcn}{(#2)(#3)#4#5#6}{% +% I consolidate the comma separated arguments into one, and then pass +% them to \PhotonArc +% +% \PhotonArcn(x,y)(r,theta1,theta2){amplitude}{numwind}{sep} +% draws a photon on an arc centered at (x,y) of radius r, starting +% at theta1, and ending at theta2, with given amplitude and +% number of windings +% + \PhotonArc[clockwise,double,sep=#6,#1](#2)(#3){#4}{#5}% +} +% +% #] DoublePhotonArcn : +% #[ DashPhotonArcn : +% +\defWithOption{DashPhotonArcn}{(#2)(#3)#4#5#6}{% +% I consolidate the comma separated arguments into one, and then pass +% them to \PhotonArc +% +% \DashPhotonArcn(x,y)(r,theta1,theta2){amplitude}{numwind}{dashsize} +% draws a photon on an arc centered at (x,y) of radius r, starting +% at theta1, and ending at theta2, with given amplitude and +% number of windings.Clockwise. +% + \PhotonArc[clockwise,dash,dashsize=#6,#1](#2)(#3){#4}{#5}% +} +% +% +% #] DashPhotonArcn : +% #[ DashDoublePhotonArcn : +% +\defWithOption{DashDoublePhotonArcn}{(#2)(#3)#4#5#6#7}{% +% I consolidate the comma separated arguments into one, and then pass +% them to \PhotonArc +% +% \DashPhotonArcn(x,y)(r,theta1,theta2){amplitude}{numwind}{dashsize} +% draws a photon on an arc centered at (x,y) of radius r, starting +% at theta1, and ending at theta2, with given amplitude and +% number of windings. Clockwise. +% + \PhotonArc[clockwise,double,sep=#6,dash,dashsize=#7,#1](#2)(#3){#4}{#5}% +} +% +% +% #] DashDoublePhotonArcn : +% #[ ZigZag : +% +\def\ZigZag{% +% \ZigZag[opt](x1,y1)(x2,y2){amplitude}{numwind} +% Draws a zigzag from (x1,y1) to (x2,y2) with given amplitude and +% number of windings +% Supported options: double, sep, linesep +% + \AXO@Parse{\AXO@ZigZag}{}% +} +% +% #] ZigZag : +% #[ DoubleZigZag : +% +\defWithOption{DoubleZigZag}{(#2,#3)(#4,#5)#6#7#8}{% +% +% Draws a zigzag from (x1,y1) to (x2,y2) with amplitude and number of windings +% + \ZigZag[double,sep=#8,#1](#2,#3)(#4,#5){#6}{#7}% +} +% +% #] DoubleZigZag : +% #[ DashZigZag : +% +\defWithOption{DashZigZag}{(#2,#3)(#4,#5)#6#7#8}{% +% +% Draws a zigzag from (x1,y1) to (x2,y2) with amplitude and number of windings +% + \ZigZag[dash,dashsize=#8,#1](#2,#3)(#4,#5){#6}{#7}% +} +% +% #] DashZigZag : +% #[ DashDoubleZigZag : +% +\defWithOption{DashDoubleZigZag}{(#2,#3)(#4,#5)#6#7#8#9}{% +% +% Draws a zigzag from (x1,y1) to (x2,y2) with amplitude and number of windings +% + \ZigZag[double,sep=#8,dash,dashsize=#9,#1](#2,#3)(#4,#5){#6}{#7}% +} +% +% #] DashDoubleZigZag : +% #[ ZigZagArc : +% +\def\ZigZagArc{% +% \ZigZagArc(x,y)(r,theta1,theta2){amplitude}{numwind} +% draws a zigzag on an arc centered at (x,y) of radius r, starting +% at theta1, and ending at theta2, with given amplitude and +% number of windings +% + \AXO@Parse{\AXO@ZigZagArc}{}% +} +% +% #] ZigZagArc : +% #[ DoubleZigZagArc : +% +\defWithOption{DoubleZigZagArc}{(#2,#3)(#4,#5,#6)#7#8#9}{% +% +% \ZigZagArc(x,y)(r,theta1,theta2){amplitude}{numwind}{sep} +% draws a zigzag on an arc centered at (x,y) of radius r, starting +% at theta1, and ending at theta2, with given amplitude and +% number of windings +% + \ZigZagArc[double,sep=#9,#1](#2,#3)(#4,#5,#6){#7}{#8}% +} +% +% #] DoubleZigZagArc : +% #[ DashZigZagArc : +% +\defWithOption{DashZigZagArc}{(#2)(#3)#4#5#6}{% +% +% \DashZigZagArc(x,y)(r,theta1,theta2){amplitude}{numwind}{dashsize} +% draws a zigzag on an arc centered at (x,y) of radius r, starting +% at theta1, and ending at theta2, with given amplitude and +% number of windings +% + \ZigZagArc[dash,dashsize=#6,#1](#2)(#3){#4}{#5}% +} +% +% +% #] DashZigZagArc : +% #[ DashDoubleZigZagArc : +% +\defWithOption{DashDoubleZigZagArc}{(#2)(#3)#4#5#6#7}{% +% +% \DashZigZagArc(x,y)(r,theta1,theta2){amplitude}{numwind}{dashsize} +% draws a zigzag on an arc centered at (x,y) of radius r, starting +% at theta1, and ending at theta2, with given amplitude and +% number of windings +% + \ZigZagArc[double,sep=#6,dash,dashsize=#7,#1](#2)(#3){#4}{#5}% +} +% +% +% #] DashDoubleZigZagArc : +% #[ ZigZagArcn : +% +\defWithOption{ZigZagArcn}{(#2)(#3)#4#5}{% +% \ZigZagArcn(x,y)(r,theta1,theta2){amplitude}{numwind} +% draws a zigzag on an arc centered at (x,y) of radius r, starting +% at theta1, and ending at theta2, with given amplitude and +% number of windings +% + \ZigZagArc[clockwise,#1](#2)(#3){#4}{#5}% +} +% +% #] ZigZagArcn : +% #[ DoubleZigZagArcn : +% +\defWithOption{DoubleZigZagArcn}{(#2)(#3)#4#5#6}{% +% +% \ZigZagArcn(x,y)(r,theta1,theta2){amplitude}{numwind}{sep} +% draws a zigzag on an arc centered at (x,y) of radius r, starting +% at theta1, and ending at theta2, with given amplitude and +% number of windings +% + \ZigZagArc[clockwise,double,sep=#6,#1](#2)(#3){#4}{#5}% +} +% +% #] DoubleZigZagArcn : +% #[ DashZigZagArcn : +% +\defWithOption{DashZigZagArcn}{(#2)(#3)#4#5#6}{% +% +% \DashZigZagArcn(x,y)(r,theta1,theta2){amplitude}{numwind}{dashsize} +% draws a zigzag on an arc centered at (x,y) of radius r, starting +% at theta1, and ending at theta2, with given amplitude and +% number of windings.Clockwise. +% + \ZigZagArc[clockwise,dash,dashsize=#6,#1](#2)(#3){#4}{#5}% +} +% +% +% #] DashZigZagArcn : +% #[ DashDoubleZigZagArcn : +% +\defWithOption{DashDoubleZigZagArcn}{(#2)(#3)#4#5#6#7}{% +% +% \DashZigZagArcn(x,y)(r,theta1,theta2){amplitude}{numwind}{dashsize} +% draws a zigzag on an arc centered at (x,y) of radius r, starting +% at theta1, and ending at theta2, with given amplitude and +% number of windings. Clockwise. +% + \ZigZagArc[clockwise,double,sep=#6,dash,dashsize=#7,#1](#2)(#3){#4}{#5}% +} +% +% #] DashDoubleZigZagArcn : +% #] Particle routines : +% #[ Line routines : +% #[ Line : +% +\def\Line{% +% \Line[opt](x1,y1)(x2,y2) +% draws a line from (x1,y1) to (x2,y2). NO arrow by default. +% Supported options: all arrow settings, all double line settings, +% all dash line settings. +% + \AXO@Parse{\AXO@Line}{}% +} +% +% #] Line : +% #[ DoubleLine : +% +\defWithOption{DoubleLine}{(#2,#3)(#4,#5)#6}{% +% +% \DoubleLine[opt](x1,y1)(x2,y2){sep} +% Draws a double line, with NO arrow by default, from (x1,y1) to (x2,y2), +% with separation sep +% + \Line[arrow=false,double,sep=#6,#1](#2,#3)(#4,#5)% +} +% +% #] DoubleLine : +% #[ DashLine : +% +\defWithOption{DashLine}{(#2,#3)(#4,#5)#6}{% +% \DashLine[opt](x1,y1)(x2,y2){sep} +% Draws a line from (x1,y1) to (x2,y2) with a dash pattern of which the +% alternating black and white pieces are approximately sep points long +% + \Line[dash,dashsize=#6,#1](#2,#3)(#4,#5)% +} +% +% #] DashLine : +% #[ DashDoubleLine : +% +\defWithOption{DashDoubleLine}{(#2,#3)(#4,#5)#6#7}{% +% \DashDoubleLine[opt](x1,y1)(x2,y2){sep}{dashsize} +% Draws a double line from (x1,y1) to (x2,y2) with separation sep, +% and with a dash pattern of which the +% alternating black and white pieces are approximately sep points long +% Arrow off. + \Line[arrow=off,dash,dashsize=#7,double,sep=#6,#1](#2,#3)(#4,#5)% +} +% +% #] DashDoubleLine : +% #[ ArrowLine : +% +\defWithOption{ArrowLine}{(#2,#3)(#4,#5)}{% +% \ArrowLine[opt](x1,y1)(x2,y2) +% draws a line from (x1,y1) to (x2,y2). Arrow by default. +% + \Line[arrow,#1](#2,#3)(#4,#5)% +} +% +% #] ArrowLine : +% #[ ArrowDoubleLine : +% +\defWithOption{ArrowDoubleLine}{(#2,#3)(#4,#5)#6}{% +% +% \ArrowDoubleLine[opt](x1,y1)(x2,y2){sep} +% Draws a double line, with arrow by default, from (x1,y1) to (x2,y2), +% with separation sep +% + \Line[arrow,double,sep=#6,#1](#2,#3)(#4,#5)% +} +% +% #] ArrowDoubleLine : +% #[ DashArrowLine : +% +\defWithOption{DashArrowLine}{(#2,#3)(#4,#5)#6}{% +% \DashArrowLine[opt](x1,y1)(x2,y2){sep} +% Draws a line from (x1,y1) to (x2,y2) with a dash pattern of which the +% alternating black and white pieces are approximately sep points +% long. Arrow by default. +% + \Line[arrow,dash,dashsize=#6,#1](#2,#3)(#4,#5)% +} +% +\let\ArrowDashLine=\DashArrowLine% +% +% #] DashArrowLine : +% #[ DashArrowDoubleLine : +% +\defWithOption{DashArrowDoubleLine}{(#2,#3)(#4,#5)#6#7}{% +% \DashArrowDoubleLine[opt](x1,y1)(x2,y2){sep}{dashsize} +% Draws a double line from (x1,y1) to (x2,y2) with separation sep, +% and with a dash pattern of which the +% alternating black and white pieces are approximately sep points long +% Arrow on. +% + \Line[arrow,dash,dashsize=#7,double,sep=#6,#1](#2,#3)(#4,#5)% +} +% +\let\ArrowDashDoubleLine=\DashArrowDoubleLine% +% +% #] DashArrowDoubleLine : +% #[ LongArrow : +% +\defWithOption{LongArrow}{(#2,#3)(#4,#5)}{% + \Line[arrow,arrowpos=1,#1](#2,#3)(#4,#5)% +} +% +% #] LongArrow : +% #[ DashLongArrowLine : +% +\defWithOption{DashLongArrowLine}{(#2,#3)(#4,#5)#6}{% +% \DashLongArrowLine[opt](x1,y1)(x2,y2){sep} +% Draws a line from (x1,y1) to (x2,y2) with a dash pattern of which the +% alternating black and white pieces are approximately sep points +% long. Arrow by default. +% +% + \Line[arrow,arrowpos=1,dash,dashsize=#6,#1](#2,#3)(#4,#5)% +} +\let\DashLongArrow=\DashLongArrowLine +\let\LongArrowDash=\DashLongArrowLine +\let\LongArrowDashLine=\DashLongArrowLine +% +% #] DashLongArrowLine : +% #] Line routines : +% #[ Arc routines : +% #[ Arc : +% +\def\Arc{% +% \Arc[opt](x,y)(r,theta1,theta2) +% draws an arc centered at (x,y) of radius r, starting at theta1, +% and ending at theta2. By default: no arrow, undashed, single, +% anticlockwise. +% Supported options: all arrow settings, all double line settings, +% all dash line settings, clock +% + \AXO@Parse{\AXO@Arc}{}% +} +% +% #] Arc : +% #[ CArc : +% +\let\CArc=\Arc +% +% #] CArc : +% #[ DoubleArc : +% +\defWithOption{DoubleArc}{(#2,#3)(#4,#5,#6)#7}{% +% +% Draws a double lined arc segment. The center of the curve +% is at (1,2). +% The radius, start angle and target angle are (#3,#4,#5). +% The arc segment runs anticlockwise +% #6 is the separation of the lines. +% + \Arc[double,sep=#7,#1](#2,#3)(#4,#5,#6)% +} +\let\DoubleCArc=\DoubleArc +% +% #] DoubleArc : +% #[ DashArc : +% +\defWithOption{DashArc}{(#2,#3)(#4,#5,#6)#7}{% +% +% Draws a dashed arc segment. The center of the curve +% is at (1,2). +% The radius, start angle and target angle are (#3,#4,#5). +% The arc segment runs anticlockwise +% #6 is the dashsize. this is rounded to make things come +% out right. +% + \Arc[dash,dsize=#7,#1](#2,#3)(#4,#5,#6)% +} +\let\DashCArc=\DashArc +% +% #] DashArc : +% #[ DashDoubleArc : +% +\defWithOption{DashDoubleArc}{(#2,#3)(#4,#5,#6)#7#8}{ +% +% Draws a dashed arc segment. The center of the curve +% is at (1,2). +% The radius, start angle and target angle are (#3,#4,#5). +% The arc segment runs anticlockwise +% #6 is the line separation. +% #7 is the dashsize. this is rounded to make things come +% out right. +% + \Arc[double,sep=#7,dash,dsize=#8,#1](#2,#3)(#4,#5,#6)% +} +\let\DashDoubleCArc=\DashDoubleArc +% +% #] DashDoubleArc : +% #[ ArrowArc : +% +\def\ArrowArc{% + \AXO@PrependOption{\Arc}{arrow}% +} +\let\ArrowCArc=\ArrowArc +% +% #] ArrowArc : +% #[ ArrowDoubleArc : +% +\defWithOption{ArrowDoubleArc}{(#2,#3)(#4,#5,#6)#7}{% + \Arc[arrow,double,sep=#7,#1](#2,#3)(#4,#5,#6)% +} +\let\ArrowDoubleCArc=\ArrowDoubleArc +% +% #] ArrowDoubleArc : +% #[ ArrowDashArc : +% +\defWithOption{ArrowDashArc}{(#2,#3)(#4,#5,#6)#7}{% + \Arc[arrow,dash,dsize=#7,#1](#2,#3)(#4,#5,#6)% +} +\let\ArrowDashCArc=\ArrowDashArc +\let\DashArrowCArc=\ArrowDashArc +\let\DashArrowArc=\ArrowDashArc +% +% #] ArrowDashArc : +% #[ ArrowDashDoubleArc : +% +\defWithOption{ArrowDashDoubleArc}{(#2,#3)(#4,#5,#6)#7#8}{% + \Arc[arrow,double,sep=#7,dash,dsize=#8,#1](#2,#3)(#4,#5,#6)% +} +\let\ArrowDashDoubleCArc=\ArrowDashDoubleArc +\let\DashArrowDoubleCArc=\ArrowDashDoubleArc +\let\DashArrowDoubleArc=\ArrowDashDoubleArc +% +% +% #] ArrowDashDoubleArc : +% #[ LongArrowArc : +% +\def\LongArrowArc{% + \AXO@PrependOption{\Arc}{arrow,arrowpos=1}% +} +% +% #] LongArrowArc : +% #[ LongDashArrowArc : +% +\defWithOption{LongArrowDashArc}{(#2,#3)(#4,#5,#6)#7}{% + \Arc[arrow,arrowpos=1,dash,dsize=#7,#1](#2,#3)(#4,#5,#6)% +} +\let\LongArrowDashCArc=\LongArrowDashArc +\let\LongDashArrowCArc=\LongArrowDashArc +\let\LongDashArrowArc=\LongArrowDashArc +% +% +% #] LongDashArrowArc : +% #[ ArrowArcn : +% +\def\ArrowArcn{% + \AXO@PrependOption{\Arc}{arrow,clock}% +} +% +% #] ArrowArcn : +% #[ LongArrowArcn : +% +\def\LongArrowArcn{% + % \ArrowArcn, but with arrow at end by default + \AXO@PrependOption{\Arc}{arrow, clock, arrowpos=1}% +} +% +% #] LongArrowArcn : +% #[ DashArrowArcn : +% +\defWithOption{DashArrowArcn}{(#2,#3)(#4,#5,#6)#7}{% +% (x,y)(radius,start,end){dashsize} +% Draws a dashed arc segment with an arrow in it. The center of the curve +% is at (x,y), with given radius, start angle, and end angle +% The arc segment runs anticlockwise + \Arc[clock,arrow,dash,dashsize=#7,#1](#2,#3)(#4,#5,#6)% +} +% +\let\ArrowDashArcn=\DashArrowArcn% +% +% +% #] DashArrowArcn : +% #] Arc routines : +% #[ Bezier : +% +\def\Bezier{% +% \Bezier[opt](x1,y1)(x2,y2)(x3,y3)(x4,y4) +% Draws a Bezier cubic with the control points (x1,y1), (x2,y2), (x3,y3), (x4,y4) +% Supported options: dash, dashsize and dashsize + \AXO@Parse{\AXO@Bezier}{}% +} +% +\defWithOption{DoubleBezier}{(#2,#3)(#4,#5)(#6,#7)(#8)#9}{% +% +% Draws a Bezier cubic with control points (x1,y1), (x2,y2), +% (x3,y3), (x4,y4) in a double line +% + \Bezier[double,sep=#9,#1](#2,#3)(#4,#5)(#6,#7)(#8)% +} +% +\defWithOption{DashBezier}{(#2,#3)(#4,#5)(#6,#7)(#8)#9}{% +% +% Draws a Bezier cubic with control points (x1,y1), (x2,y2), +% (x3,y3), (x4,y4) with a dash pattern of which the +% alternating black and white pieces are approximately #9 points long +% + \Bezier[dash,dashsize=#9,#1](#2,#3)(#4,#5)(#6,#7)(#8)% +} +% +\defWithOption{DashDoubleBezier}{(#2,#3)(#4,#5)(#6)(#7)#8#9}{% +% +% Draws a Bezier cubic with control points (x1,y1), (x2,y2), +% (x3,y3), (x4,y4) with a dash pattern of which the +% alternating black and white pieces are approximately #9 points long +% The line is a double line +% + \Bezier[double,sep=#8,dash,dashsize=#9,#1](#2,#3)(#4,#5)(#6)(#7)% +} +% +% #] Bezier : +% #] LaTeX primitives : +% #[ Mixed routines : +% +% Here we have routines that make different calls depending on the value +% of the variable \axo@pdfoutput +% +% #[ EBox : +% +\def\EBox(#1,#2)(#3,#4){% +% +% Draws a transparent box with the left bottom at (x1,y1) andthe +% right top at (x2,y2). +% +\ifcase\axo@pdfoutput + \put(\axoxoff,\axoyoff){\AXOspecial{% + #1 \axoxo\space add #2 \axoyo\space add + #3 \axoxo\space add #4 \axoyo\space add \axowidth\space \axoscale\space ebox }} +\else + \getaxohelp{EBox}{#1 #2 #3 #4 \axowidth} + \put(\axoxoff,\axoyoff){\axo@pdfliteral{\contentspdf}} +\fi +} +% +% #] EBox : +% #[ FBox : +% +\def\FBox(#1,#2)(#3,#4){% +% +% Draws a filled box with the left bottom at (x1,y1) and the right top +% at (x2,y2). +% +\ifcase\axo@pdfoutput + \put(\axoxoff,\axoyoff){\AXOspecial{% + #1 \axoxo\space add #2 \axoyo\space add + #3 \axoxo\space add #4 \axoyo\space add \axowidth\space \axoscale\space fbox }} +\else + \getaxohelp{FBox}{#1 #2 #3 #4 \axowidth} + \put(\axoxoff,\axoyoff){\axo@pdfliteral{\contentspdf}} +\fi +} +% +% #] FBox : +% #[ BBox : +% +\def\BBox(#1,#2)(#3,#4){% +% +% Draws a box with the left bottom at (x1,y1) and the right top +% at (x2,y2). The contents are blanked out. +% + {% + \SetColor{White}% + \FBox(#1,#2)(#3,#4)% + }% + \EBox(#1,#2)(#3,#4)% +} +% +% #] BBox : +% #[ GBox : +% +\def\GBox(#1,#2)(#3,#4)#5{% +% +% Draws a box with the left bottom at (x1,y1) and the right top +% at (x2,y2). The contents are in Grayscale#5 (0=black,1=white). +% + {% + \color[gray]{#5}% + \FBox(#1,#2)(#3,#4)% + \color[gray]{0}% + \EBox(#1,#2)(#3,#4)% + }% +\ignorespaces +} +% +% #] GBox : +% #[ CBox : +% +\def\CBox(#1,#2)(#3,#4)#5#6{% +% +% Draws a box with the left bottom at (x1,y1) and the right top +% at (x2,y2). The outside is color#5 and the inside color #6. +% + {% + \SetColor{#6}% + \FBox(#1,#2)(#3,#4)% + \SetColor{#5}% + \EBox(#1,#2)(#3,#4)% + }% +\ignorespaces +} +% +% #] CBox : +% #[ EBoxc : +% +\def\EBoxc(#1,#2)(#3,#4){% +% +% Draws a centered box with the center at (x1,y1). +% The other parameters are the width and the height. +% Uses current color +% +\ifcase\axo@pdfoutput + \put(\axoxoff,\axoyoff){\AXOspecial{% + #1 \axoxo\space add #3 2 div sub #2 \axoyo\space add + #4 2 div sub #1 \axoxo\space add #3 2 div add #2 + \axoyo\space add #4 2 div add \axowidth\space \axoscale\space ebox }} +\else + \getaxohelp{Boxc}{#1 #2 #3 #4 \axowidth} + \put(\axoxoff,\axoyoff){\axo@pdfliteral{\contentspdf}} +\fi +} +% +\let\Boxc=\EBoxc +% +% #] EBoxc : +% #[ FBoxc : +% +\def\FBoxc(#1,#2)(#3,#4){% +% +% Draws a filled centered box with the center at (x1,y1). +% The other parameters are the width and the height. +% Current color +% +\ifcase\axo@pdfoutput + \put(\axoxoff,\axoyoff){\AXOspecial{% + #1 \axoxo\space add #3 2 div sub #2 \axoyo\space add + #4 2 div sub #1 \axoxo\space add #3 2 div add #2 \axoyo\space add #4 2 div add + \axowidth\space \axoscale\space fbox }} +\else + \getaxohelp{FBoxc}{#1 #2 #3 #4 \axowidth} + \put(\axoxoff,\axoyoff){\axo@pdfliteral{\contentspdf}} +\fi +} +% +% #] FBoxc : +% #[ BBoxc : +% +\def\BBoxc(#1,#2)(#3,#4){% +% +% Draws a centered box with the center at (x1,y1). +% The other parameters are the width and the height. +% The contents are blanked out. +% +\bgroup + \SetColor{White}% + \FBoxc(#1,#2)(#3,#4)% +\egroup +\EBoxc(#1,#2)(#3,#4)% +} +% +% #] BBoxc : +% #[ GBoxc : +% +\def\GBoxc(#1,#2)(#3,#4)#5{% +% +% Draws a centered box with the center at (x1,y1). +% The other parameters are the width and the height. +% The contents are in Grayscale#5 (0=black,1=white). +% + {% + \color[gray]{#5}% + \FBoxc(#1,#2)(#3,#4)% + \color[gray]{0}% + \EBoxc(#1,#2)(#3,#4)% + }% +\ignorespaces +} +% +% #] GBoxc : +% #[ CBoxc : +% +\def\CBoxc(#1,#2)(#3,#4)#5#6{% +% +% Draws a centered box with the center at (x1,y1). +% The other parameters are the width and the height. +% The outside is color#5 and the inside color #6. +% + {% + \SetColor{#6}% + \FBoxc(#1,#2)(#3,#4)% + \SetColor{#5}% + \EBoxc(#1,#2)(#3,#4)% + }% +\ignorespaces +} +% +% #] CBoxc : +% #[ RotatedBox : +% +\def\RotatedBox(#1,#2)(#3,#4)#5#6{% +% +% Draws a centered box with the center at (#1,#2) +% with width #3, height #4, anticlockwise rotated by #5, and in +% color #6. +% + \AxoPut(#1,#2){% + {\SetColor{#6}% + \rotatebox{#5}{\EBoxc(0,0)(#3,#4)}% + }}% +} +% +% #] RotatedBox : +% #[ FilledRotatedBox : +% +\def\FilledRotatedBox(#1,#2)(#3,#4)#5#6{% +% +% Draws a filled centered box with the center at (#1,#2) +% with width #3, height #4, anticlockwise rotated by #5, and in +% color #6. +% + \AxoPut(#1,#2){% + {\SetColor{#6}% + \rotatebox{#5}{\FBoxc(0,0)(#3,#4)}% + }}% +} +% +% #] FilledRotatedBox : +% #[ ETri : +% +% Draws a triangle. No filling. +% The corners are (x1,y1), (x2,y2), (x3,y3) +% +\def\ETri(#1,#2)(#3,#4)(#5,#6){% +% +\ifcase\axo@pdfoutput + \put(\axoxoff,\axoyoff){\AXOspecial{% + #1 \axoxo\space add #2 \axoyo\space add + #3 \axoxo\space add #4 \axoyo\space add + #5 \axoxo\space add #6 \axoyo\space add + \axowidth\space \axoscale\space triangle }} +\else + \getaxohelp{ETri}{#1 #2 #3 #4 #5 #6 \axowidth} + \put(\axoxoff,\axoyoff){\axo@pdfliteral{\contentspdf}} +\fi +} +% +% #] ETri : +% #[ FTri : +% +% Draws a filled triangle. +% The corners are (x1,y1), (x2,y2), (x3,y3) +% +\def\FTri(#1,#2)(#3,#4)(#5,#6){% +% +\ifcase\axo@pdfoutput + \put(\axoxoff,\axoyoff){\AXOspecial{% + #1 \axoxo\space add #2 \axoyo\space add + #3 \axoxo\space add #4 \axoyo\space add + #5 \axoxo\space add #6 \axoyo\space add + \axowidth\space \axoscale\space ftriangle }} +\else + \getaxohelp{FTri}{#1 #2 #3 #4 #5 #6 \axowidth} + \put(\axoxoff,\axoyoff){\axo@pdfliteral{\contentspdf}} +\fi +} +% +% #] FTri : +% #[ BTri : +% +% Draws a triangle. The contents are blanked out. +% The corners are (x1,y1), (x2,y2), (x3,y3) +% +\def\BTri(#1,#2)(#3,#4)(#5,#6){% + {% + \SetColor{White}% + \FTri(#1,#2)(#3,#4)(#5,#6)% + }% + \ETri(#1,#2)(#3,#4)(#5,#6)% +} +% +% #] BTri : +% #[ GTri : +% +% Draws a triangle. The contents are given in Grayscale #7 (0=black,1=white) +% The corners are (x1,y1), (x2,y2), (x3,y3) +% +\def\GTri(#1,#2)(#3,#4)(#5,#6)#7{% +% + {% + \color[gray]{#7}% + \FTri(#1,#2)(#3,#4)(#5,#6)% + \color[gray]{0}% + \ETri(#1,#2)(#3,#4)(#5,#6)% + }% +\ignorespaces +} +% +% #] GTri : +% #[ CTri : +% +% Draws a colored(#7) triangle. The contents are blanked out in color #8 +% The corners are (x1,y1), (x2,y2), (x3,y3) +% +\def\CTri(#1,#2)(#3,#4)(#5,#6)#7#8{% + {% + \SetColor{#7}% + \FTri(#1,#2)(#3,#4)(#5,#6)% + \SetColor{#8}% + \ETri(#1,#2)(#3,#4)(#5,#6)% + }% +\ignorespaces +} +% +% #] CTri : +% #[ Vertex : +% +\def\Vertex(#1,#2)#3{% +% +% Draws a fat dot at (1,2). The radius of the dot is given by 3. +% +\ifcase\axo@pdfoutput + \put(\axoxoff,\axoyoff){\AXOspecial{% + #1 \axoxo\space add #2 \axoyo\space add #3 + \axoscale\space vertex }} +\else + \getaxohelp{Vertex}{#1 #2 #3 \axowidth} + \put(\axoxoff,\axoyoff){\axo@pdfliteral{\contentspdf}} +\fi +} +% +% #] Vertex : +% #[ ECirc : +% +\def\ECirc(#1,#2)#3{% +% +% Draws a circle at (1,2) and radius 3, with current color. +% Nothing is written inside. +% +\ifcase\axo@pdfoutput + \put(\axoxoff,\axoyoff){\AXOspecial{% + #1 \axoxo\space add #2 \axoyo\space add #3 + \axowidth\space \axoscale\space ecirc }}% +\else + \getaxohelp{ECirc}{#1 #2 #3 \axowidth}% + \put(\axoxoff,\axoyoff){\axo@pdfliteral{\contentspdf}}% +\fi +} +% +% #] ECirc : +% #[ FCirc : +% +\let\FCirc=\Vertex +% +% #] FCirc : +% #[ BCirc : +% +\def\BCirc(#1,#2)#3{% +% +% Draws a circle at (1,2) and radius 3 that is blanked out. + {% + \SetColor{White}% + \FCirc(#1,#2){#3} + }% + \ECirc(#1,#2){#3}% +} +% +% #] BCirc : +% #[ GCirc : +% +\def\GCirc(#1,#2)#3#4{% +% +% Draws a circle at (1,2) and radius 3 that is blanked out. +% Then it fills the circle with a gray scale 4 (0 = black, 1 is white) +% + {% + \color[gray]{#4}% + \FCirc(#1,#2){#3}% + \color[gray]{0}% + \ECirc(#1,#2){#3}% + }% +\ignorespaces +} +% +% #] GCirc : +% #[ CCirc : +% +% Draws a circle at (1,2) and radius 3 that is blanked out. +% #4 is the color of the circle, #5 the color of the contents +% +\def\CCirc(#1,#2)#3#4#5{% +% +% Draws a circle at (1,2) and radius 3 that is blanked out. +% #4 is the color of the circle, #5 the color of the contents +% +{% + \SetColor{#5}% + \FCirc(#1,#2){#3}% + \SetColor{#4}% + \ECirc(#1,#2){#3}% +}% +\ignorespaces +} +% +% #] CCirc : +% #[ GOval : +% +\def\GOval(#1,#2)(#3,#4)(#5)#6{% +% +% Draws a gray oval that overwrites whatever was there. +% \GOval(x_center,y_center)(height,width)(rotation)(grayscale) +% The grayscale: (0 = black, 1 is white) +% + {% + \color[gray]{#6}% + \FOval(#1,#2)(#3,#4)(#5)% + \color[gray]{0}% + \Oval(#1,#2)(#3,#4)(#5)% + }% + \ignorespaces +} +% +% #] GOval : +% #[ COval : +% +\def\COval(#1,#2)(#3,#4)(#5)#6#7{% +% +% Draws a colored oval that overwrites whatever was there. +% \COval(x_center,y_center)(height,width)(rotation){color1}{color2} +% + {% + \SetColor{#7}% + \FOval(#1,#2)(#3,#4)(#5)% + \SetColor{#6}% + \Oval(#1,#2)(#3,#4)(#5)% + }% + \ignorespaces +} +% +% #] COval : +% #[ FOval : +% +\def\FOval(#1,#2)(#3,#4)(#5){% +% +% Draws a colored oval that overwrites whatever was there. +% \FOval(x_center,y_center)(height,width)(rotation) +% Uses current color +% + \ifcase\axo@pdfoutput + \put(\axoxoff,\axoyoff)% + {\AXOspecial{#1 \axoxo\space add #2 \axoyo\space add #3 #4 #5 + \axowidth\space \axoscale\space foval + }}% + \else + \getaxohelp{FOval}{#1 #2 #3 #4 #5 \axowidth}% + \put(\axoxoff,\axoyoff){\axo@pdfliteral{\contentspdf}}% + \fi +} +% +% #] FOval : +% #[ Oval : +% +\def\Oval(#1,#2)(#3,#4)(#5){% +% +% Draws an oval that does not overwrite whatever was there. +% \Oval(x_center,y_center)(height,width)(rotation) +% +\ifcase\axo@pdfoutput + \put(\axoxoff,\axoyoff)% + {\AXOspecial{#1 \axoxo\space add #2 \axoyo\space add #3 #4 #5 + \axowidth\space \axoscale\space oval + }}% +\else + \getaxohelp{Oval}{#1 #2 #3 #4 #5 \axowidth}% + \put(\axoxoff,\axoyoff){\axo@pdfliteral{\contentspdf}}% +\fi +} +% +% #] Oval : +% #[ Polygon : +% +% Draws a curve through the points in argument 1. +% The points are given as coordinates (x1,y1)(x2,y2)(x3,y3)..... +% The curve is continous and continuous in its first and second +% derivatives. The method is linear interpolation of +% quadratic curves. +% Color name is argument 2. +% +\def\Polygon#1#2{% + {% + \SetColor{#2}% + \ifcase\axo@pdfoutput + \put(\axoxoff,\axoyoff){\AXOspecial{% + [ \axoparray#1] \axowidth\space \axoscale\space polygon }}% + \else + \getaxohelp{Polygon}{"#1" \axowidth}% + \put(\axoxoff,\axoyoff){\axo@pdfliteral{\contentspdf}}% + \fi + }% + \ignorespaces +} +% +% #] Polygon : +% #[ FilledPolygon : +% +% Draws a curve through the points in argument 1. +% The points are given as coordinates (x1,y1)(x2,y2)(x3,y3)..... +% The curve is continous and continuous in its first and second +% derivatives. The method is linear interpolation of +% quadratic curves. +% Color name is argument 2. +% +\def\FilledPolygon#1#2{% + {% + \SetColor{#2}% + \ifcase\axo@pdfoutput + \put(\axoxoff,\axoyoff){\AXOspecial{% + [ \axoparray#1] \axowidth\space \axoscale\space filledpolygon }} + \else + \getaxohelp{FilledPolygon}{"#1" \axowidth}% + \put(\axoxoff,\axoyoff){\axo@pdfliteral{\contentspdf}}% + \fi + }% + \ignorespaces +} +% +% #] FilledPolygon : +% #[ Curve : +% +% Draws a curve through the points in argument 1. +% The points are given as coordinates (x1,y1)(x2,y2)(x3,y3)..... +% The curve is continous and continuous in its first and second +% derivatives. The method is linear interpolation of quadratic curves. +% +\def\Curve#1{% +\ifcase\axo@pdfoutput + \put(\axoxoff,\axoyoff){\AXOspecial{[ \axoparray#1] + \axowidth\space \axoscale\space makecurve }} +\else + \getaxohelp{Curve}{"#1" \axowidth} + \put(\axoxoff,\axoyoff){\axo@pdfliteral{\contentspdf}} +\fi +} +% +% #] Curve : +% #[ DashCurve : +% +% Draws a curve through the points in argument 1. +% The points are given as coordinates (x1,y1)(x2,y2)(x3,y3)..... +% The curve is continous and continuous in its first and second +% derivatives. The method is linear interpolation of quadratic curves. +% Argument 2 gives a dash size. +% +\def\DashCurve#1#2{% +\ifcase\axo@pdfoutput + \put(\axoxoff,\axoyoff){\AXOspecial{[ \axoparray#1] #2 + \axowidth\space \axoscale\space makedashcurve }} +\else + \getaxohelp{DashCurve}{"#1" #2 \axowidth} + \put(\axoxoff,\axoyoff){\axo@pdfliteral{\contentspdf}} +\fi +} +% +% #] DashCurve : +% #[ LinAxis : +% +\def\LinAxis(#1,#2)(#3,#4)(#5,#6,#7,#8,#9){% +% +% Draws a line with linear hash marks along it. +% LinAxis(x1,y1)(x2,y2)(num_decs,per_dec,hashsize,offset,width) +% The line is from (x1,y1) to (x2,y2) and the marks are on the left side +% when hashsize is positive, and right when it is negative. +% num_decs is the number of accented marks, per_dec the number of +% divisions between them and offset is the number +% at which one starts at (x1,y1) (like if offset=2 we start at the second +% small mark) Width is the linewidth. +% +\ifcase\axo@pdfoutput + \put(\axoxoff,\axoyoff){\AXOspecial{% + #1 \axoxo\space add #2 \axoyo\space add + #3 \axoxo\space add #4 \axoyo\space add + #5 #6 #7 #8 #9 \axoscale\space linaxis }} +\else + \getaxohelp{LinAxis}{#1 #2 #3 #4 #5 #6 #7 #8 #9} + \put(\axoxoff,\axoyoff){\axo@pdfliteral{\contentspdf}} +\fi +} +% +% #] LinAxis : +% #[ LogAxis : +% +\def\LogAxis(#1,#2)(#3,#4)(#5,#6,#7,#8){% +% +% Draws a line with logarithmic hash marks along it. +% LogAxis(x1,y1)(x2,y2)(num_logs,hashsize,offset,width) +% The line is from (x1,y1) to (x2,y2) and the marks are on the left side +% when hashsize is positive, and right when it is negative. +% num_logs is the number of orders of magnitude and offset is the number +% at which one starts at (x1,y1) (like if offset=2 we start at 2) +% When offset is 0 we start at 1. Width is the linewidth. +% +\ifcase\axo@pdfoutput + \put(\axoxoff,\axoyoff){\AXOspecial{% + #1 \axoxo\space add #2 \axoyo\space add + #3 \axoxo\space add #4 \axoyo\space add + #5 #6 #7 #8 \axoscale\space logaxis }} +\else + \getaxohelp{LogAxis}{#1 #2 #3 #4 #5 #6 #7 #8} + \put(\axoxoff,\axoyoff){\axo@pdfliteral{\contentspdf}} +\fi +} +% +% #] LogAxis : +% #[ AxoGrid : +% +\def\AxoGrid(#1,#2)(#3,#4)(#5,#6)#7#8{% +% +% Makes a grid with the left bottom at #1,#2 +% The increments in x and y are #3,#4 +% The number of steps in each direction are #5,#6 (there are n+1 lines) +% #7 is the color and #8 the linewidth +% +{\SetColor{#7}% + \ifcase\axo@pdfoutput + \put(\axoxoff,\axoyoff){% + \AXOspecial{% + #3 #4 #5 #6 + #1 \axoxo\space add #2 \axoyo\space add + #8 \axoscale\space axogrid + }}% + \else + \getaxohelp{Grid}{#1 #2 #3 #4 #5 #6 #8}% + \put(\axoxoff,\axoyoff){\axo@pdfliteral{\contentspdf}}% + \fi +}% +\ignorespaces +} +% +% #] AxoGrid : +% #[ AXO@Arc : +% +% Generic Arc segment with many options. +% +% +\def\AXO@Arc(#1,#2)(#3,#4,#5){% +% +% Draws arc centered at (#1,#2), radius #3, starting and ending +% angles #4, #5. +% Double, dashing, arrow, clockwise according to current settings +% +{\AXO@useopts +\ifcase\axo@pdfoutput + \put(\axoxoff,\axoyoff){% + \AXOspecial{% + \AXO@ArrowArg \space + \ifAXO@flip true \else false \fi + \ifAXO@double \AXO@CurrentSep \space \else 0 \fi + \ifAXO@dash \AXO@CurrentDashSize \space \else 0 \fi + \ifAXO@clock true \else false \fi + #3 #4 #5 + #1 \axoxo\space add #2 \axoyo\space add + \AXO@CurrentWidth\space \axoscale\space arc2 + }}% +\else + \getaxohelp{AxoArc}{#1 #2 #3 #4 #5 + \ifAXO@double \AXO@CurrentSep \space \else 0 \fi + \ifAXO@dash \AXO@CurrentDashSize \space \else 0 \fi + \AXO@ArrowArg \space + \ifAXO@flip 1 \else 0 \fi + \ifAXO@clock 1 \else 0 \fi + \AXO@CurrentWidth} + \put(\axoxoff,\axoyoff){\axo@pdfliteral{\contentspdf}} +\fi +}\ignorespaces +} +% +% #] AXO@Arc : +% #[ AXO@Bezier : +% +\def\AXO@Bezier(#1,#2)(#3,#4)(#5,#6)(#7,#8){% +% +% Draws a Bezier cubic with the control points (x1,y1), (x2,y2), +% (x3,y3), (x4,y4) +% Assumes options have been set +% +{\AXO@useopts +\ifcase\axo@pdfoutput + \put(\axoxoff,\axoyoff){\AXOspecial{% + #1 \axoxo\space add #2 \axoyo\space add + #3 \axoxo\space add #4 \axoyo\space add + #5 \axoxo\space add #6 \axoyo\space add + #7 \axoxo\space add #8 \axoyo\space add + \AXO@ArrowArg \space + \ifAXO@flip true \else false \fi + \ifAXO@double \AXO@CurrentSep \space \else 0 \fi + \ifAXO@dash \AXO@CurrentDashSize \space \else 0 \fi + \AXO@CurrentWidth\space \axoscale\space dashdoublebezier + }}% +\else + \getaxohelp{AxoBezier}{#1 #2 #3 #4 #5 #6 #7 #8 + \ifAXO@double \AXO@CurrentSep \space \else 0 \fi + \ifAXO@dash \AXO@CurrentDashSize \space \else 0 \fi + \AXO@ArrowArg \space + \ifAXO@flip 1 \else 0 \fi + \AXO@CurrentWidth} + \put(\axoxoff,\axoyoff){\axo@pdfliteral{\contentspdf}} +\fi +}\ignorespaces +} +% +% #] AXO@Bezier : +% #[ AXO@GluonHelper : +% +\def\AXO@GluonHelper(#1,#2)(#3,#4)#5#6#7#8{% +% +% Draws a single gluon from (x1,y1) to (x2,y2) with amplitude #5 and number +% of windings #6. Width #7 + #8 +% Assumes options have been set. +% Used as helper from \AXO@Gluon + % +\ifAXO@arrow\AXO@NOTIMPLEMENTED{arrow not implemented for gluon}\fi +\ifcase\axo@pdfoutput + \put(\axoxoff,\axoyoff){% + \AXOspecial{% + #1 \axoxo\space add #2 \axoyo\space add + #3 \axoxo\space add #4 \axoyo\space add + #5 #6 + \ifAXO@dash \AXO@CurrentDashSize \space \else 0 \fi + #7 #8 add \axoscale \space dashgluon + }% + }% +\else + \getaxohelp{AxoGluon}{#1 #2 #3 #4 #5 #6 + #7 + \ifAXO@dash \AXO@CurrentDashSize \space \else 0 \fi + #8}% + \put(\axoxoff,\axoyoff){\axo@pdfliteral{\contentspdf}} +\fi +} +% +\def\AXO@GluonHelperNEW(#1,#2)(#3,#4)#5#6#7#8{% +% IDEA: Showing cleaner code +% +% Draws a single gluon from (x1,y1) to (x2,y2) with amplitude #5 and number +% of windings #6. Width #7 + #8 +% Assumes options have been set. +% Used as helper from \AXO@Gluon +% + \ifAXO@arrow\AXO@NOTIMPLEMENTED{arrow not implemented for gluon}\fi + \ifcase\axo@pdfoutput + \AXOputPS{% + #1 #2 #3 #4 #5 #6 + \ifAXO@dash \AXO@CurrentDashSize \space \else 0 \fi + #7 #8 add \axoscale \space dashgluon + }% + \else + \getaxohelp{AxoGluon}{#1 #2 #3 #4 #5 #6 + #7 + \ifAXO@dash \AXO@CurrentDashSize \space \else 0 \fi + #8}% + \AXOputPDF{\contentspdfNoOffset}% + \fi +} +% +% #] AXO@GluonHelper : +% #[ AXO@Gluon : +% +\def\AXO@Gluon(#1,#2)(#3,#4)#5#6{% +% +% Draws a gluon from (x1,y1) to (x2,y2) with amplitude #5 and number +% of windings #6. +% Assumes options have been set +% +{\AXO@useopts + \ifAXO@arrow\AXO@NOTIMPLEMENTED{arrow not implemented for gluon}\fi + \AXO@arrowfalse % To avoid repeated errors + \ifAXO@double + \AXO@GluonHelper(#1,#2)(#3,#4){#5}{#6}{\AXO@CurrentWidth}{\AXO@CurrentSep}% + \SetColor{White}% + \AXO@dashfalse + \AXO@GluonHelper(#1,#2)(#3,#4){#5}{#6}{-\AXO@CurrentWidth}{\AXO@CurrentSep}% + \else + \AXO@GluonHelper(#1,#2)(#3,#4){#5}{#6}{0}{\AXO@CurrentWidth}% + \fi + }% +\ignorespaces +} +% #] AXO@Gluon : +% #[ AXO@GluonArcHelper : +% +\def\AXO@GluonArcHelper(#1,#2)(#3,#4,#5)#6#7#8#9{% +% +% Draws a gluon on an arc segment. The center of the curve is at (1,2) +% The radius, start angle and target angle are (#3,#4,#5), #6 is the +% amplitude of the gluon, and #7 is the number of windings. +% Assumes options have been set +% Width #8 + #9 +% Assumes options have been set. +% Used as helper from \AXO@GluonArc +\ifAXO@arrow\AXO@NOTIMPLEMENTED{arrow not implemented for gluon arc}\fi +\ifcase\axo@pdfoutput + \put(\axoxoff,\axoyoff){\AXOspecial{#6 #7 + \ifAXO@dash \AXO@CurrentDashSize \space \else 0 \fi + \ifAXO@clock true \else false \fi + #3 #4 #5 + #1 \axoxo\space add #2 \axoyo\space add + #8 #9 add \axoscale\space dashgluearc + }}% +\else + \getaxohelp{AxoGluonArc}{#1 #2 #3 #4 #5 #6 #7 + #8 + \ifAXO@dash \AXO@CurrentDashSize \space \else 0 \fi + \ifAXO@clock 1 \else 0 \fi + #9} + \put(\axoxoff,\axoyoff){\axo@pdfliteral{\contentspdf}} +\fi +} +% #] AXO@GluonArcHelper : +% #[ AXO@GluonArc : +% +\def\AXO@GluonArc(#1,#2)(#3,#4,#5)#6#7{% +% +% Draws a gluon on an arc segment. The center of the curve is at (1,2) +% The radius, start angle and target angle are (#3,#4,#5), #6 is the +% amplitude of the gluon, and #7 is the number of windings. +% Assumes options have been set +% + {\AXO@useopts + \ifAXO@arrow\AXO@NOTIMPLEMENTED{arrow not implemented for gluon}\fi + \AXO@arrowfalse % To avoid repeated errors + \ifAXO@double + \AXO@GluonArcHelper(#1,#2)(#3,#4,#5){#6}{#7}{\AXO@CurrentWidth}{\AXO@CurrentSep}% + \SetColor{White}% + \AXO@dashfalse + \AXO@GluonArcHelper(#1,#2)(#3,#4,#5){#6}{#7}{-\AXO@CurrentWidth}{\AXO@CurrentSep}% + \else + \AXO@GluonArcHelper(#1,#2)(#3,#4,#5){#6}{#7}{0}{\AXO@CurrentWidth}% + \fi + }% +\ignorespaces +} +% #] AXO@GluonArc : +% #[ AXO@GluonCircHelper : +% +\def\AXO@GluonCircHelper(#1,#2)(#3,#4)#5#6#7#8{% +% +% Draws a gluon on a circle. The center of the circle is at (1,2) +% The radius and the phase angle are (#3,#4), 5 is the +% amplitude of the gluon, and 6 is the number of windings. +% Width #7 + #8 +% Assumes options have been set. +% Used as helper from \AXO@GluonCirc +\ifAXO@arrow\AXO@NOTIMPLEMENTED{arrow not implemented for gluon arc}\fi +\ifcase\axo@pdfoutput + \put(\axoxoff,\axoyoff){\AXOspecial{% + #5 #6 + \ifAXO@dash \AXO@CurrentDashSize \space \else 0 \fi + #3 #4 + #1 \axoxo\space add #2 \axoyo\space add + #7 #8 add \axoscale\space dashgluoncirc + }}% +\else + \getaxohelp{AxoGluonCirc}{#1 #2 #3 #4 #5 #6 + #7 + \ifAXO@dash \AXO@CurrentDashSize \space \else 0 \fi + #8} + \put(\axoxoff,\axoyoff){\axo@pdfliteral{\contentspdf}} +\fi +} +% #] AXO@GluonCicHelper : +% #[ AXO@GluonCirc : +% +\def\AXO@GluonCirc(#1,#2)(#3,#4)#5#6{% +% +% Draws a gluon on a circle. The center of the circle is at (1,2) +% The radius and the phase angle are (#3,#4), 5 is the +% amplitude of the gluon, and 6 is the number of windings. +% + {\AXO@useopts + \ifAXO@arrow\AXO@NOTIMPLEMENTED{arrow not implemented for gluon}\fi + \AXO@arrowfalse % To avoid repeated errors + \ifAXO@double + \AXO@GluonCircHelper(#1,#2)(#3,#4){#5}{#6}{\AXO@CurrentWidth}{\AXO@CurrentSep}% + \SetColor{White}% + \AXO@dashfalse + \AXO@GluonCircHelper(#1,#2)(#3,#4){#5}{#6}{-\AXO@CurrentWidth}{\AXO@CurrentSep}% + \else + \AXO@GluonCircHelper(#1,#2)(#3,#4){#5}{#6}{0}{\AXO@CurrentWidth}% + \fi + }% +\ignorespaces +} +% +% #] AXO@GluonCirc : +% #[ AXO@Line : +% +\def\AXO@Line(#1,#2)(#3,#4){% +% +% Draws a line from (x1,y1) to (x2,y2) +% Double, dashing, arrow according to current settings +% +{\AXO@useopts +\ifcase\axo@pdfoutput + \put(\axoxoff,\axoyoff){% + \AXOspecial{% + \AXO@ArrowArg \space + \ifAXO@flip true \else false \fi + \ifAXO@double \AXO@CurrentSep \space \else 0 \fi + \ifAXO@dash \AXO@CurrentDashSize \space \else 0 \fi + #1 \axoxo\space add #2 \axoyo\space add + #3 \axoxo\space add #4 \axoyo\space add + \AXO@CurrentWidth \space \axoscale \space + dasharrowdoubleline + }}% +\else + \getaxohelp{AxoLine}{#1 #2 #3 #4 + \ifAXO@double \AXO@CurrentSep \space \else 0 \fi + \ifAXO@dash \AXO@CurrentDashSize \space \else 0 \fi + \AXO@ArrowArg \space + \ifAXO@flip 1 \else 0 \fi + \AXO@CurrentWidth} + \put(\axoxoff,\axoyoff){\axo@pdfliteral{\contentspdf}}% +\fi +}\ignorespaces +} +% +% #] AXO@Line : +% #[ AXO@Photon : +% +\def\AXO@Photon(#1,#2)(#3,#4)#5#6{% +% +% Draws a photon from (x1,y1) to (x2,y2) with amplitude #5 and number +% of windings #6. +% Assumes options have been set +% +{\AXO@useopts +\ifAXO@arrow\AXO@NOTIMPLEMENTED{arrow not implemented for photon}\fi +\ifcase\axo@pdfoutput + \put(\axoxoff,\axoyoff){\AXOspecial{% + #1 \axoxo\space add #2 \axoyo\space add + #3 \axoxo\space add #4 \axoyo\space add #5 #6 + \ifAXO@double \AXO@CurrentSep \space \else 0 \fi + \ifAXO@dash \AXO@CurrentDashSize \space \else 0 \fi + \AXO@CurrentWidth\space \axoscale\space dashdoublephoton }}% +\else + \getaxohelp{AxoPhoton}{#1 #2 #3 #4 #5 #6 + \ifAXO@double \AXO@CurrentSep \space \else 0 \fi + \ifAXO@dash \AXO@CurrentDashSize \space \else 0 \fi + \AXO@CurrentWidth} + \put(\axoxoff,\axoyoff){\axo@pdfliteral{\contentspdf}} +\fi +}\ignorespaces +} +% #] AXO@Photon : +% #[ AXO@PhotonArc : +% +\def\AXO@PhotonArc(#1,#2)(#3,#4,#5)#6#7{% +% +% Draws a photon on an arc segment. The center of the curve is at (1,2) +% The radius, start angle and target angle are (#3,#4,#5), #6 is the +% amplitude of the gluon, and #7 is the number of wiggles. +% Assumes options have been set +% +{\AXO@useopts +\ifAXO@arrow\AXO@NOTIMPLEMENTED{arrow not implemented for photon arc}\fi +\ifcase\axo@pdfoutput + \put(\axoxoff,\axoyoff){\AXOspecial{% + #6 #7 + \ifAXO@double \AXO@CurrentSep \space \else 0 \fi + \ifAXO@dash \AXO@CurrentDashSize \space \else 0 \fi + \ifAXO@clock true \else false \fi + #3 #4 #5 + #1 \axoxo\space add #2 \axoyo\space add + \AXO@CurrentWidth\space \axoscale\space dashdoublephotonarc + }}% +\else + \getaxohelp{AxoPhotonArc}{#1 #2 #3 #4 #5 #6 #7 + \ifAXO@double \AXO@CurrentSep \space \else 0 \fi + \ifAXO@dash \AXO@CurrentDashSize \space \else 0 \fi + \ifAXO@clock 1 \else 0 \fi + \AXO@CurrentWidth} + \put(\axoxoff,\axoyoff){\axo@pdfliteral{\contentspdf}} +\fi +}\ignorespaces +} +% +% #] AXO@PhotonArc : +% #[ AXO@ZigZag : +% +\def\AXO@ZigZag(#1,#2)(#3,#4)#5#6{% +% +% Draws a zigzag from (x1,y1) to (x2,y2) with amplitude #5 and number +% of windings #6. +% Assumes options have been set +% +{\AXO@useopts +\ifAXO@arrow\AXO@NOTIMPLEMENTED{arrow not implemented for zigzag}\fi +\ifcase\axo@pdfoutput + \put(\axoxoff,\axoyoff){\AXOspecial{% + #1 \axoxo\space add #2 \axoyo\space add + #3 \axoxo\space add #4 \axoyo\space add #5 #6 + \ifAXO@double \AXO@CurrentSep \space \else 0 \fi + \ifAXO@dash \AXO@CurrentDashSize \space \else 0 \fi + \AXO@CurrentWidth\space \axoscale\space dashdoublezigzag }}% +\else + \getaxohelp{AxoZigZag}{#1 #2 #3 #4 #5 #6 + \ifAXO@double \AXO@CurrentSep \space \else 0 \fi + \ifAXO@dash \AXO@CurrentDashSize \space \else 0 \fi + \AXO@CurrentWidth} + \put(\axoxoff,\axoyoff){\axo@pdfliteral{\contentspdf}}% +\fi +}\ignorespaces +} +% #] AXO@ZigZag : +% #[ AXO@ZigZagArc : +% +\def\AXO@ZigZagArc(#1,#2)(#3,#4,#5)#6#7{% +% +% Draws a zigzag on an arc segment. The center of the curve is at (1,2) +% The radius, start angle and target angle are (#3,#4,#5), #6 is the +% amplitude of the gluon, and #7 is the number of wiggles. +% Assumes options have been set +% +{\AXO@useopts +\ifAXO@arrow\AXO@NOTIMPLEMENTED{arrow not implemented for zigzag arc}\fi +\ifcase\axo@pdfoutput + \put(\axoxoff,\axoyoff){\AXOspecial{% + #6 #7 + \ifAXO@double \AXO@CurrentSep \space \else 0 \fi + \ifAXO@dash \AXO@CurrentDashSize \space \else 0 \fi + \ifAXO@clock true \else false \fi + #3 #4 #5 + #1 \axoxo\space add #2 \axoyo\space add + \AXO@CurrentWidth\space \axoscale\space dashdoublezigzagarc + }}% +\else + \getaxohelp{AxoZigZagArc}{#1 #2 #3 #4 #5 #6 #7 + \ifAXO@double \AXO@CurrentSep \space \else 0 \fi + \ifAXO@dash \AXO@CurrentDashSize \space \else 0 \fi + \ifAXO@clock 1 \else 0 \fi + \AXO@CurrentWidth} + \put(\axoxoff,\axoyoff){\axo@pdfliteral{\contentspdf}} +\fi +}\ignorespaces +} +% +% #] AXO@ZigZagArc : +% #[ Text and boxes : +% #[ SetPFont : +% +% To access fonts, from both latex and pdflatex, we need +% to define a mapping from the human-readable name to +% the name known to (pdf)latex. Then we can define a +% user command for setting the font. The human-readable +% name is the one used by postscript. +% Variables used: +% \pfontN = human name of current PS font (e.g., Helvetica). +% \pfontC = TeX code for the font (e.g., phvr). +% Both are \relax to use regular document font +% \axofontsize = size of font (text command with unit) + + +\def\defineaxofont#1#2{% + % #1 is user visible name of font, #2 is LaTex name. + % Define a command of name #1 to return #2 + \expandafter\def\csname #1\endcsname{#2} +} + +\def\SetPFont#1#2{% + \ifthenelse{ \equal{#1}{} }% + {\let\pfontN=\relax \let\pfontC=\relax}% + {\@ifundefined{#1}% + {\PackageWarning{axodraw2}{trying to set undefined font `#1'}}% + {\def\pfontN{#1}% Human name (postscript) + \def\pfontC{\@nameuse{#1}}% Code name + }% + }% + \ifthenelse{ \equal{#2}{} }% + {% Use the value of LaTeX's fontsize when the font is used: + \def\axofontsize{\f@size}% + }% + {\def\axofontsize{#2}}% +\ignorespaces +} + +\def\UseCurrentPSFont{% + % Set regular size of regular font, so math has rational size + \fontsize{\axofontsize}{\axofontsize}% + \selectfont + \ifx\pfontC\relax + \else + \font\axofont = \pfontC \space at \axofontsize pt + \axofont + \fi +} + +\defineaxofont{AvantGarde-Book}{pagk} +\defineaxofont{AvantGarde-BookOblique}{pagko} +\defineaxofont{AvantGarde-Demi}{pagd} +\defineaxofont{AvantGarde-DemiOblique}{pagdo} +\defineaxofont{Bookman-Demi}{pbkd} +\defineaxofont{Bookman-DemiItalic}{pbkdi} +\defineaxofont{Bookman-Light}{pbkl} +\defineaxofont{Bookman-LightItalic}{pbkli} +\defineaxofont{Courier-Bold}{pcrb} +\defineaxofont{Courier-BoldOblique}{pcrbo} +\defineaxofont{Courier}{pcrr} +\defineaxofont{Courier-Oblique}{pcrro} +\defineaxofont{Helvetica-Bold}{phvb} +\defineaxofont{Helvetica-BoldOblique}{phvbo} +\defineaxofont{Helvetica-NarrowBold}{phvbrn} +\defineaxofont{Helvetica-NarrowBoldOblique}{phvbon} +\defineaxofont{Helvetica}{phvr} +\defineaxofont{Helvetica-Oblique}{phvro} +\defineaxofont{Helvetica-Narrow}{phvrrn} +\defineaxofont{Helvetica-NarrowOblique}{phvron} +\defineaxofont{NewCenturySchlbk-Bold}{pncb} +\defineaxofont{NewCenturySchlbk-BoldItalic}{pncbi} +\defineaxofont{NewCenturySchlbk-Italic}{pncri} +\defineaxofont{NewCenturySchlbk-Roman}{pncr} +\defineaxofont{Palatino-Bold}{pplb} +\defineaxofont{Palatino-BoldItalic}{pplbi} +\defineaxofont{Palatino-Italic}{pplri} +\defineaxofont{Palatino-Roman}{pplr} +\defineaxofont{Symbol}{psyr} +\defineaxofont{Times-Bold}{ptmb} +\defineaxofont{Times-BoldItalic}{ptmbi} +\defineaxofont{Times-Italic}{ptmri} +\defineaxofont{Times-Roman}{ptmr} +\defineaxofont{ZapfChancery-MediumItalic}{pzcmi} +\defineaxofont{ZapfDingbats}{pzdr} + +% Now we can set the default: + +\SetPFont{Times-Roman}{10} + +% +% #] SetPFont : +% #[ Text : +% +% Aim: \Text(#1,#2)(#3)[#4]#5, to set text #5 at position (#1,#2) +% with angle #3 and positioning #4. +% But the presence of (#3) and [#3] is to be optional (with +% defaults being equivalent to (0) and [] +% +\def\Text(#1,#2){% + \@ifnextchar(% ) + {\Text@A(#1,#2)}% + {\Text@A(#1,#2)(0)}% +} +% +\def\Text@A(#1,#2)(#3){% + \@ifnextchar[% ] + {\Text@Z(#1,#2)(#3)}% + {\Text@Z(#1,#2)(#3)[]}% +} +% +\def\axoscaleTT{\ifPSTextScalesLikeGraphics 1\else \axotextscale \fi} +\def\axoscalePT{\ifPSTextScalesLikeGraphics \axoscale\else \axotextscale \fi} +% +\def\Text@Z(#1,#2)(#3)[#4]#5{% + % + % Draws text at (#1,#2). Argument #3 is combination of l, r, t, b to + % indicate positioning instead of default (which is horizontally and + % vertically centered --- these are same as \makebox + % the text is left adjusted, right adjusted or centered. Or b or t. + % 4 is of course the text. + % + \AxoPut(#1,#2){% + \scalebox{\axoscaleTT}% + {\rotatebox{#3}{\makebox(0,0)[#4]{#5}}}% + }% + \ignorespaces +} +% +% #] Text : +% #[ PText : *+ +% +\def\PText(#1,#2)(#3)[#4]#5{% +% +% Draws a postscript text in a postscript font. +% Focal point is (1,2), rotation angle is 3, 4 is the mode (as in text) +% and 5 is the text. +% + \begingroup + \UseCurrentPSFont + \AxoPut(#1,#2){% + \scalebox{\axoscalePT}% + {\rotatebox{#3}{\makebox(0,0)[#4]{#5}}}% + }% + \endgroup + \ignorespaces +} +% +% #] PText : +% #[ RText : +% +\def\RText(#1,#2)[#3](#4)#5{% +% +% Draws rotated text at (1,2). Argument 3 is l,r or c indicating whether +% the text is left adjusted, right adjusted or centered. +% 4 is the rotation angle and 5 is of course the text. +% + \Text(#1,#2)(#4)[#3]{#5}% + \ignorespaces +} +% +% #] RText : +% #[ rText : * +% +\def\rText(#1,#2)[#3][#4]#5{% +% +% Draws rotated text at (1,2). Argument 3 is l,r or c indicating whether +% the text is left adjusted, right adjusted or centered. +% 4 is the rotation angle (specified as l, r, u, or blank, +% and 5 is of course the text. +% + \begingroup + \def\this@angle{0}% + \ifx#4l% + \def\this@angle{90}% + \else + \ifx#4r% + \def\this@angle{-90}% + \else + \ifx#4u% + \def\this@angle{180}% + \fi + \fi + \fi + \Text(#1,#2)(\this@angle)[#3]{#5}% + \endgroup + \ignorespaces +} +% +% #] rText : +% #[ BText : +% +\def\BText(#1,#2)#3{% +% +% Draws a box with the center at (x1,y1) and postscript text #3 in it. +% + \AxoPut(#1,#2){% + \edef\axoscale{\axoscalePT}% + \SetTmpBox{#3}% + \BBoxc(0,0)(\tmpXT,\tmpYT)% + \PText(0,0)(0)[]{\usebox{\tmpBox}}% + }% + \ignorespaces +} +% +% #] BText : +% #[ GText : +% +\def\GText(#1,#2)#3#4{% +% +% Draws a box with the center at (x1,y1) and postscript(#4) text in it. +% The grayness of the box is given by #3 +% + \AxoPut(#1,#2){% + \edef\axoscale{\axoscalePT}% + \SetTmpBox{#4}% + \GBoxc(0,0)(\tmpXT,\tmpYT){#3}% + \PText(0,0)(0)[]{\usebox{\tmpBox}}% + }% + \ignorespaces +} +% +% #] GText : +% #[ CText : +% +\def\CText(#1,#2)#3#4#5{% +% +% Draws a box with the center at (x1,y1) and postscript(#5) text in it. +% The color of box and text is in #3 +% The color of the background is in #4 +% + \AxoPut(#1,#2){% + \edef\axoscale{\axoscalePT}% + \SetTmpBox{\SetColor{#3}{#5}}% + \CBoxc(0,0)(\tmpXT,\tmpYT){#3}{#4}% + \PText(0,0)(0)[]{\usebox{\tmpBox}}% + }% +} +% +% #] CText : +% #[ BTwoText : +% +\def\BTwoText(#1,#2)#3#4{% +% +% Draws a box with the center at (x1,y1) and two lines of postscript +% text in it. +% + \AxoPut(#1,#2){% + \edef\axoscale{\axoscalePT}% + \SetTmpBoxTwo{#3}{#4}% + \BBoxc(0,0)(\tmpXT,\tmpYT)% + \PText(0,0)(0)[]{\usebox{\tmpBox}}% + }% + \ignorespaces +} +% +% #] BTwoText : +% #[ GTwoText : +% +\def\GTwoText(#1,#2)#3#4#5{% +% +% Draws a box with the center at (x1,y1) and two lines of postscript +% text (#4 and #5) in it. +% The grayness of the box is given by #3 +% + \AxoPut(#1,#2){% + \edef\axoscale{\axoscalePT}% + \SetTmpBoxTwo{#4}{#5}% + \GBoxc(0,0)(\tmpXT,\tmpYT){#3}% + \PText(0,0)(0)[]{\usebox{\tmpBox}}% + }% + \ignorespaces +} +% +% #] GTwoText : +% #[ CTwoText : +% +\def\CTwoText(#1,#2)#3#4#5#6{% +% +% Draws a box with the center at (x1,y1) and two lines of postscript +% text (#5 and #6) in it. +% The color of the box and the text is given by #3 +% The background color is given by #4 +% + \AxoPut(#1,#2){% + \edef\axoscale{\axoscalePT}% + \SetTmpBoxTwo{\SetColor{#3}#5}{\SetColor{#3}#6}% + \CBoxc(0,0)(\tmpXT,\tmpYT){#3}{#4}% + \PText(0,0)(0)[]{\usebox{\tmpBox}}% + }% + \ignorespaces +} +% +% #] CTwoText : +% #] Text and boxes : +% #] Mixed routines : +% #[ Postscript specific : +% +% The code here is used only when we need Postscript output. This concerns +% mainly the Postscript library. +% +\ifcase\axo@pdfoutput +% +% #[ PostScript preamble : +% +\AtBeginDvi{ +% +% This forces the PostScript preamble commands to be put into the +% dvi file. Without this, revtex4 can remove them by funny +% stuff with manipulating the first page. +% +% #[ inventory : +% +% The variables in here are: +% num,num1,ampi,ampi1,x1,y1,x2,y2,x3,y3,x4,y4,dx,dy,dr +% width, arrowpos, arrowspec, arrowwidth, arrowlength, arrowinset +% arcend, arcmid, arcstart, radius, linesep, angdsize, dsize, +% clockwise, dotsize, inc, pi, sign +% darc,const,amp1, amp2, amp3, amp4, amp5, amp6, amp7, amp8, amp1i +% gcolor,xx2 +% +% NOTE: blank lines are not allowed inside the postscript code!!!!! +% (LaTeX sneaks \par commands in and the postscript goes boink) +% +\special{color} % Provoke dvips into including color.pro + % Revtex4 in 2-column mode fails to force that +% +\special{! + /savecolor { %/cmyk [ currentcmykcolor ] def + /oldcolor [ [ currentcolor ] currentcolorspace ] def + } def + /restorecolor { oldcolor aload pop setcolorspace aload pop setcolor } def +% /savecolor { [ currentcmykcolor ] /cmyk ed } def +% /restorecolor { cmyk aload pop setcmykcolor } def +% % Do a save color now, to ensure default variables are defined: + savecolor +} +% +\special{! + /pi 3.141592 def + /ed{exch def}def +% Implement conversion of length unit from pt to bp by scaling + /gs{gsave 1.00375 div dup scale}def + /gsw{ gs + /width ed + width setlinewidth + }def + /p1{/y1 ed /x1 ed}def + /p2{/y2 ed /x2 ed}def + /p3{/y3 ed /x3 ed}def + /p4{/y4 ed /x4 ed}def + /pp1{/yy1 ed /xx1 ed}def + /pp2{/yy2 ed /xx2 ed}def + /pp3{/yy3 ed /xx3 ed}def + /setabs{ + % Usage /var setabs + % Sets variable to its absolute value + dup load abs def + }def + % + /normalizearc { + % Usage: clockwise r angle1 angle2 x y normalizearc + % Adjusts coordinate system for anticlockwize arc from angle + % zero, centered at origin. + % Left on stack: r d_angle, with 0<d_angle <=360. + % Zero angle arc converted to loop + translate + exch dup rotate % Origin of arc now at angle 0 + sub % Change angle2 to dangle + 3 2 roll + { % Clockwise arc: obtain from anticlockwise arc + neg + 1 -1 scale + } if + dup abs 360 ge + { %Outside 360 degrees, make exactly a loop + pop 360 + } + { % Convert to positive angle mod 360. + dup + dup 0 lt { 360 sub } if + 360 div truncate 360 mul sub + dup 0.1 lt { pop 360 } if + }ifelse + } def + % + /normalizeline { + % Usage: x1 y1 x2 y2 normalizeline + % Adjusts coordinate system for line from origin in x direction + % Left on stack: dr = length of line + 3 index 3 index translate + 2 index sub exch 3 index sub + 2 copy atan rotate + dup mul exch dup mul add sqrt + 3 1 roll pop pop + } def + % + /abox{ + newpath + x1 y1 moveto + x1 y2 lineto + x2 y2 lineto + x2 y1 lineto + closepath + }def + /atriangle{ + newpath + x1 y1 moveto + x2 y2 lineto + x3 y3 lineto + closepath + }def + /abezier{ + newpath + x1 y1 moveto + x2 y2 x3 y3 x4 y4 curveto + }def + /distance{ + % Usage: x1 y1 x2 y2 distance -> x1 y1 x2 y2 r + % Pure stack based: computes distance between points. Keeps points + dup + 3 index sub dup mul + 2 index 5 index sub dup mul add sqrt + } def + /setbackgroundcolor{ + 0 0 0 0 setcmykcolor + } def +} +% +% #] inventory : +% #[ Arrows : +% +% Define better arrows +% +\special{! +% Arrow making routines +% + /getarrow { + /witharrow ed + /arrowpos ed + /arrowaspect ed + /arrowscale ed + /arrowinset ed + /arrowlength ed + /arrowwidth ed + /arrowstroke ed + } def + /drawarrow { + gsave + [] 0 setdash + rotate + arrowwidth 0 eq { + arrowlength 0 eq { + linewidth linesep 0.7 mul add 1 add 1.2 mul dup + 2.5 lt { + pop + 2.5 + } if + arrowscale mul + /arrowwidth ed + /arrowlength arrowwidth 2 mul arrowaspect mul def + } { + /arrowlength arrowlength arrowscale mul def + /arrowwidth arrowlength 2 div arrowaspect div def + } ifelse + } { + arrowlength 0 eq { + /arrowwidth arrowwidth arrowscale mul def + /arrowlength arrowwidth 2 mul arrowaspect mul def + } { + /arrowwidth arrowwidth arrowscale mul def + /arrowlength arrowlength arrowscale mul def + } ifelse + } ifelse + arrowstroke 0 ne { + arrowstroke setlinewidth + gsave + setbackgroundcolor + newpath + 0 arrowlength -0.5 mul moveto + arrowwidth arrowlength rlineto + arrowwidth -1 mul arrowlength arrowinset mul -1 mul rlineto + arrowwidth -1 mul arrowlength arrowinset mul rlineto + closepath fill + grestore + newpath + 0 arrowlength -0.5 mul moveto + arrowwidth arrowlength rlineto + arrowwidth -1 mul arrowlength arrowinset mul -1 mul rlineto + arrowwidth -1 mul arrowlength arrowinset mul rlineto + closepath stroke + } { + newpath + 0 arrowlength -0.5 mul moveto + arrowwidth arrowlength rlineto + arrowwidth -1 mul arrowlength arrowinset mul -1 mul rlineto + arrowwidth -1 mul arrowlength arrowinset mul rlineto + closepath fill + } ifelse + grestore + } def +% +} +% +% #] Arrows : +% +% Basic line drawing +% #[ fixdash : +% +\special{! /fixdash{ +% Usage: r dashsize fixdash +% Sets renormalized dashsize, doing +% [rdsize rdsize] 0 setdash +% so that n+1/2 patterns fit in length r +% If dsize is too big or if dsize is zero, use continuous line +% Uses stack, no named variables. + 2 copy gt + 1 index 0 ne + and + { + 2 copy + 2 mul div 0.5 sub round + dup 0 le { pop 0 } if + 2 mul 1 add exch pop div + dup 2 array astore 0 setdash + } + { pop pop [] 0 setdash } + ifelse +} def } +% +% #] fixdash : +% #[ dashline : +% +\special{! /dashline{ +% Draws a straight dashed line: x1,y1,x2,y2 +% Assumes dsize already set +% The pattern is ideally [dsize dsize] 0 setdash +% but we want to have (2*n+1)/2 patterns, so dsize must be rounded +% If dsize is too large or zero, use a continuous line +% Pure stack operation. + gsave + distance dsize fixdash % Function distance leaves points on stack + newpath + moveto + lineto + stroke + grestore +} def } +% #] dashline : +% #[ dasharc : +% +\special{! /dasharc{ +% Draws an arc segment anticlockwise: +% x_center, y_center, radius, start_angle, end_angle +% Assumes angdsize (radians) set elsewhere + gsave + 3 copy sub abs + % Top of stack is copy of radius, start_angle, end_angle + pi mul 180 div mul + % Top of stack is arc length + 3 index angdsize mul fixdash + newpath arc stroke + grestore +} def } +% +% #] dasharc : +% #[ dashgluon : +% +\special{! /dashgluon{ +% +% Draw gluon, possibly dashed +% We have a 'head' and a 'tail' and in between the 'body' +% The head + tail is 2 windings. The body is num-1 windings. +% + gsw + /dsize ed + /num ed /ampi ed + normalizeline /dr ed + /num num 0.5 sub round def +% + dsize 0 eq { + [] 0 setdash + } { + /amp8 ampi abs 0.9 mul def + /size amp8 neg 0 amp8 neg ampi 2 mul dup dr num 2 mul 2 add div exch + 1 lengthofbezier def +% + /ndash size dsize 2 mul div truncate def + ndash 0 eq { /ndash 1 def } if + size 2 dsize ndash mul mul sub abs + size 2 dsize ndash 1 add mul mul sub abs gt { /ndash ndash 1 add def } if + /dsize size 2 ndash mul div def + [ dsize dsize ] dsize 2 div setdash + } ifelse +% + /inc dr num 2 mul 2 add div def % increment per half winding + /amp8 ampi 0.9 mul def + amp8 0 lt {/amp8 amp8 neg def} if +% + /x1 inc 2 mul def +% + newpath + x1 ampi neg moveto + x1 amp8 add dup ampi neg exch ampi inc 1.4 mul ampi curveto + inc 0.5 mul ampi inc 0.1 mul ampi 0.5 mul 0 0 curveto + stroke + newpath + x1 ampi neg moveto + 2 1 num { + pop + x1 amp8 sub dup ampi neg exch ampi dup x1 inc add exch curveto + /x1 x1 inc dup add add def + x1 amp8 add dup ampi exch ampi neg dup x1 exch curveto + } for +% + x1 amp8 sub dup ampi neg exch ampi dup x1 inc 0.6 mul add exch curveto + x1 inc 1.5 mul add ampi dr inc 0.1 mul sub ampi 0.5 mul dr 0 curveto + stroke +% + grestore +} def } +% +% #] dashgluon : +% #[ dashdoublephoton : +% +\special{! /dashdoublephoton{ +% +% Draws a photon from x1,y1 to x2,y2 with amplitude A and n wiggles +% Possibly double +% + gsw + /dsize ed + /linesep ed + /num ed /ampi ed + normalizeline /dr ed + /num num 2 mul 0.5 sub round def +% + dsize 0 eq { + [] 0 setdash + } { +% Compute the dash size + /xdd dr num div def + /size 4 3 div xdd mul pi div dup neg xdd add + 4 3 div ampi mul dup 3 1 roll xdd 0 1 lengthofbezier 2 div def + /ndash size dsize 2 mul div truncate def + ndash 0 eq { /ndash 1 def } if + size 2 dsize ndash mul mul sub abs + size 2 dsize ndash 1 add mul mul sub abs gt { /ndash ndash 1 add def } if + /dsize size 2 ndash mul div def + [ dsize dsize ] dsize 2 div setdash + } ifelse +% + linesep 0 eq + { 0 0 dr 0 ampi num photon1 } + { +% 0 linesep 2 div dup dr exch ampi num photon1 +% 0 linesep -2 div dup dr exch ampi num photon1 +% + linesep width add setlinewidth 0 0 dr 0 ampi num photon1 + [] 0 setdash + 0 0 0 0 setcmykcolor + linesep width sub setlinewidth 0 0 dr 0 ampi num photon1 +% + } + ifelse + grestore +} def } +% +% #] dashdoublephoton : +% #[ photon1 : +% +\special{! /photon1{ +% +% Draws a single photon from x1,y1 to x2,y2 with amplitude A and n wiggles +% + gsave + /num1 ed /ampi1 ed + normalizeline /dr ed +% + /x2 dr num1 div def + /sign 1 def + 1 1 num1 { + pop + newpath + 0 0 moveto + 4 3 div x2 mul pi div dup neg x2 add + 4 3 div ampi1 sign mul mul dup 3 1 roll + x2 0 curveto + stroke + /sign sign neg def + x2 0 translate + } for +% + grestore +} def } +% +% #] photon1 : +% #[ dashdoublezigzag : +% +\special{! /dashdoublezigzag{ +% +% Draws a zigzag from x1,y1 to x2,y2 with amplitude A and n wiggles +% Possibly double +% + gsw + /dsize ed + /linesep ed + /num ed /ampi ed + normalizeline /dr ed + /num num 2 mul 0.5 sub round def +% + dsize 0 eq { + [] 0 setdash + } { +% Compute the dash size + /size dr num 2 mul div dup mul ampi dup mul add sqrt def + /ndash size dsize 2 mul div truncate def + ndash 0 eq { /ndash 1 def } if + size 2 dsize ndash mul mul sub abs + size 2 dsize ndash 1 add mul mul sub abs gt { /ndash ndash 1 add def } if + /dsize size 2 ndash mul div def + [ dsize dsize ] dsize 2 div setdash + } ifelse +% + linesep 0 eq + { 0 0 dr 0 ampi num zigzag1 } + { +% 0 linesep 2 div dup dr exch ampi num zigzag1 +% 0 linesep -2 div dup dr exch ampi num zigzag1 +% + linesep width add setlinewidth 0 0 dr 0 ampi num zigzag1 + [] 0 setdash + 0 0 0 0 setcmykcolor + linesep width sub setlinewidth 0 0 dr 0 ampi num zigzag1 +% + } + ifelse + grestore +} def } +% +% #] dashdoublezigzag : +% #[ zigzag1 : +% +\special{! /zigzag1{ +% +% Draws a single zigzag from x1,y1 to x2,y2 with amplitude A and n wiggles +% + gsave + /num1 ed /ampi1 ed + normalizeline /dr ed +% + /x2 dr num1 div def + /sign 1 def + 1 1 num1 { + pop + newpath + 0 0 moveto + x2 2 div ampi1 sign mul lineto + x2 0 lineto + stroke + /sign sign neg def + x2 0 translate + } for +% + grestore +} def } +% +% #] zigzag1 : +% #[ dashgluearc : +% +\special{! /dashgluearc{ +% +% Draws a gluon on an arcsegment +% gluon_radius, num, linesep (0 for no-double), dsize (0 for no dashes) +% clock, radius, start_angle, end_angle, x_center, y_center +% in which num is the number of windings of the gluon. +% +% Method for the gluon arc itself: +% 1: compute length of arc. +% 2: generate gluon in x and y as if the arc is a straight line +% 3: x' = (radius+y)*cos(x*const) +% y' = (radius+y)*sin(x*const) +% + gsw + normalizearc + /darc ed /radius ed /dsize ed /num ed /ampi ed + /num num 0.5 sub round def +% + dsize 0 eq { + [] 0 setdash + } { + /dr radius darc mul pi mul 180 div def % length of segment. + /const darc dr div def % conversion constant + /inc dr num 2 mul 2 add div def % increment per half winding + /amp8 ampi 0.9 mul def + /amp1 radius ampi add def + /amp2 radius ampi sub def + /amp4 amp1 inc amp8 add const mul cos div def + /amp5 amp2 amp8 const mul cos div def + amp8 0 lt {/amp8 amp8 neg def} if + /x1 inc 2 mul def + /x0 x1 const mul cos amp2 mul def + /y0 x1 const mul sin amp2 mul def + x1 amp8 sub const mul dup cos amp5 mul x0 sub exch sin amp5 mul y0 sub + x1 amp8 sub const mul dup cos amp4 mul x0 sub exch sin amp4 mul y0 sub + x1 inc add const mul dup cos amp1 mul x0 sub exch sin amp1 mul y0 sub + 1 lengthofbezier + /size ed +% + /ndash size dsize 2 mul div truncate def + ndash 0 eq { /ndash 1 def } if + size 2 dsize ndash mul mul sub abs + size 2 dsize ndash 1 add mul mul sub abs gt { /ndash ndash 1 add def } if + /dsize size 2 ndash mul div def + [ dsize dsize ] dsize 2 div setdash + } ifelse +% + /dr radius darc mul pi mul 180 div def % length of segment. + /const darc dr div def % conversion constant + /inc dr num 2 mul 2 add div def % increment per half winding + /amp8 ampi 0.9 mul def + /amp1 radius ampi add def + /amp2 radius ampi sub def + /amp3 radius ampi 2 div add def + /amp4 amp1 inc amp8 add const mul cos div def + /amp5 amp2 amp8 const mul cos div def + /amp6 amp1 inc 0.6 mul amp8 add const mul cos div def + /amp7 amp1 inc 0.9 mul const mul cos div def + amp8 0 lt {/amp8 amp8 neg def} if +% + newpath + /x1 inc 2 mul def + x1 const mul dup cos amp2 mul exch sin amp2 mul + moveto + x1 amp8 add const mul dup cos amp5 mul exch sin amp5 mul + x1 amp8 add const mul dup cos amp6 mul exch sin amp6 mul + inc 1.4 mul const mul dup cos amp1 mul exch sin amp1 mul + curveto + inc 0.5 mul const mul dup cos amp7 mul exch sin amp7 mul + inc 0.1 mul const mul dup cos amp3 mul exch sin amp3 mul + radius 0 + curveto + stroke + newpath + x1 const mul dup cos amp2 mul exch sin amp2 mul moveto + 2 1 num { pop + x1 amp8 sub const mul dup cos amp5 mul exch sin amp5 mul + x1 amp8 sub const mul dup cos amp4 mul exch sin amp4 mul + x1 inc add const mul dup cos amp1 mul exch sin amp1 mul + curveto + /x1 x1 inc dup add add def + x1 amp8 add const mul dup cos amp4 mul exch sin amp4 mul + x1 amp8 add const mul dup cos amp5 mul exch sin amp5 mul + x1 const mul dup cos amp2 mul exch sin amp2 mul + curveto + } for + x1 amp8 sub const mul dup cos amp5 mul exch sin amp5 mul + x1 amp8 sub const mul dup cos amp6 mul exch sin amp6 mul + x1 inc 0.6 mul add const mul dup cos amp1 mul exch sin amp1 mul + curveto + x1 inc 1.5 mul add const mul dup cos amp7 mul exch sin amp7 mul + dr inc 0.1 mul sub const mul dup cos amp3 mul exch sin amp3 mul + dr const mul dup cos radius mul exch sin radius mul + curveto + stroke +% + grestore +} def +} +% +% #] dashgluearc : +% #[ dashdoublephotonarc : +% +\special{! /dashdoublephotonarc{ +% +% Draws a photon on an arcsegment +% photon_radius, num, linesep (0 for no-double), dsize (0 for no dashes), +% clock, radius, start_angle, end_angle, x_center, y_center +% in which num is the number of wiggles of the photon. +% + gsw + normalizearc + /darc ed /radius ed /dsize ed /linesep ed /num ed /ampli ed +% + /num num 2 mul round def % number of half wiggles + /darc1 darc num div def + /cp darc1 cos def + /sp darc1 sin def + darc1 2 div dup + /cp2 exch cos def + /sp2 exch sin def +% + dsize 0 eq { + [] 0 setdash + } { +% +% Compute the length of the outer curve and the inner curve. +% There must be an integer number of patterns in half the sum. +% The we use half of the first to determine where in the pattern +% we should start. +% + /ampli1 ampli def + /beta radius darc1 mul 180 ampli1 mul div def + /tt sp cp beta mul sub cp sp beta mul add div def + /amp1 radius ampli1 add 8 mul beta cp2 mul sp2 sub mul beta 4 cp add mul + tt cp mul 3 mul sp 4 mul sub add radius mul sub + beta tt sub 3 mul div def % this is x2 + radius ampli1 add 8 mul cp2 mul 1 cp add radius mul sub 3 div amp1 sub + dup radius sub exch radius sub beta mul % x1,y1 + amp1 radius sub amp1 radius cp mul sub tt mul radius sp mul add % x2,y2 + radius cp mul radius sub radius sp mul % x3 y3 + 1 lengthofbezier + /len1 ed + /ampli1 ampli1 neg def + /beta radius darc1 mul 180 ampli1 mul div def + /tt sp cp beta mul sub cp sp beta mul add div def + /amp1 radius ampli1 add 8 mul beta cp2 mul sp2 sub mul beta 4 cp add mul + tt cp mul 3 mul sp 4 mul sub add radius mul sub + beta tt sub 3 mul div def % this is x2 + radius ampli1 add 8 mul cp2 mul 1 cp add radius mul sub 3 div amp1 sub + dup radius sub exch radius sub beta mul % x1,y1 + amp1 radius sub amp1 radius cp mul sub tt mul radius sp mul add % x2,y2 + radius cp mul radius sub radius sp mul % x3 y3 + 1 lengthofbezier + /len2 ed + /size len1 len2 add 2 div def + /size2 len1 2 div def +% + /ndash size dsize 2 mul div truncate def + ndash 0 eq { /ndash 1 def } if + size 2 dsize ndash mul mul sub abs + size 2 dsize ndash 1 add mul mul sub abs gt { /ndash ndash 1 add def } if + /dsize size 2 ndash mul div def + /numd size2 dsize 2 mul div truncate def + /dstart dsize 2 div size2 sub 2 numd dsize mul mul add def + dstart 0 lt { /dstart dstart dsize 2 mul add def } if + [ dsize dsize ] dstart setdash + } ifelse +% + linesep 0 eq { + radius photonarc1 + } { + linesep width add setlinewidth radius photonarc1 + [] 0 setdash + 0 0 0 0 setcmykcolor + linesep width sub setlinewidth radius photonarc1 + } ifelse +% + grestore +} def } +% +% #] dashdoublephotonarc : +% #[ photonarc1 : +% +\special{! /photonarc1{ +% Usage: radius photonarc1 +% Draws a single photon on an arcsegment. +% Called from dashdoublephotonarc with coordinates centered on center, +% start on x-axis. +% Assume the following are set: num, ampli, arcend phi, arcstart phi/2, cp, +% cp2, sp, sp2. +% Draws a photonarc center at x1,y1, radius arcstart,arcend, amplitude +% number of wiggles, width, scale +% + gsave + /radius1 ed + % Local copy of amplitude, since I change it + /ampli1 ampli def +% + newpath + radius1 0 moveto + 1 1 num { 1 sub /ii ed + /cpi darc1 ii mul cos def + /spi darc1 ii mul sin def + /beta radius1 darc1 mul 180 ampli1 mul div def + /tt sp cp beta mul sub cp sp beta mul add div def + /x2 radius1 ampli1 add 8 mul beta cp2 mul sp2 sub mul beta 4 cp add mul + tt cp mul 3 mul sp 4 mul sub add radius1 mul sub + beta tt sub 3 mul div def + /x1 radius1 ampli1 add 8 mul cp2 mul 1 cp add radius1 mul sub 3 div x2 sub def + /y1 x1 radius1 sub beta mul def + /y2 x2 radius1 cp mul sub tt mul radius1 sp mul add def + /x3 radius1 cp mul def + /y3 radius1 sp mul def + x1 cpi mul y1 spi mul sub y1 cpi mul x1 spi mul add + x2 cpi mul y2 spi mul sub y2 cpi mul x2 spi mul add + x3 cpi mul y3 spi mul sub y3 cpi mul x3 spi mul add + curveto + /ampli1 ampli1 neg def + } for + stroke +% + grestore +} def } +% +% #] photonarc1 : +% #[ dashdoublezigzagarc : +% +\special{! /dashdoublezigzagarc{ +% +% Draws a zigzag on an arcsegment +% zigzag_radius, num, linesep (0 for no-double), dsize (0 for no dashes), +% clock, radius, start_angle, end_angle, x_center, y_center +% in which num is the number of wiggles of the zigzag. +% + gsw + normalizearc + /darc ed /radius ed /dsize ed /linesep ed /num ed /ampli ed +% + /num num 2 mul round def % number of half wiggles + /darc1 darc num div def + /cp darc1 cos def + /sp darc1 sin def + darc1 2 div dup + /cp2 exch cos def + /sp2 exch sin def +% + dsize 0 eq { + [] 0 setdash + } { + /size ampli dup mul radius dup mul add radius dup mul ampli dup mul sub + cp mul sub 2 div sqrt def + /size2 ampli dup mul ampli radius add radius mul 2 mul 1 cp2 sub mul + add sqrt def +% + /ndash size dsize 2 mul div truncate def + ndash 0 eq { /ndash 1 def } if + size 2 dsize ndash mul mul sub abs + size 2 dsize ndash 1 add mul mul sub abs gt { /ndash ndash 1 add def } if + /dsize size 2 ndash mul div def + /numd size2 dsize 2 mul div truncate def + /dstart dsize 2 div size2 sub 2 numd dsize mul mul add def + dstart 0 lt { /dstart dstart dsize 2 mul add def } if + [ dsize dsize ] dstart setdash + } ifelse +% + linesep 0 eq { + radius zigzagarc1 + } { + linesep width add setlinewidth radius zigzagarc1 + [] 0 setdash + 0 0 0 0 setcmykcolor + linesep width sub setlinewidth radius zigzagarc1 + } ifelse +% + grestore +} def } +% +% #] dashdoublezigzagarc : +% #[ zigzagarc1 : +% +\special{! /zigzagarc1{ +% Usage: radius zigzagarc1 +% Draws a single zigzag on an arcsegment. +% Called from dashdoublezigzagarc with coordinates centered on center, +% start on x-axis. +% Assume the following are set: num, ampli, arcend phi, arcstart phi/2, cp, +% cp2, sp, sp2. +% Draws a zigzagarc center at x1,y1, radius arcstart,arcend, amplitude +% number of wiggles, width, scale +% + gsave + /radius1 ed +% Local copy of amplitude, since I change it + /ampli1 ampli def +% +% Num is the number of half wiggles. We like to start and end with +% quarter wiggles though. +% + /darc2 darc1 2 div def + newpath + radius1 0 moveto + darc2 dup sin exch cos + radius1 ampli1 add mul exch radius1 ampli1 add mul lineto + /ampli1 ampli1 neg def + /num1 num 1 sub def + 1 1 num1 { + darc1 mul darc2 add dup sin exch cos + radius1 ampli1 add mul exch radius1 ampli1 add mul lineto + /ampli1 ampli1 neg def + } for + num darc1 mul dup sin exch cos + radius1 mul exch radius1 mul lineto + stroke +% + grestore +} def } +% +% #] zigzagarc1 : +% #[ dashgluoncirc : +% +\special{! /dashgluoncirc{ +% +% Draws a gluon on a complete circle +% cmyk color setting +% gluon_ampl, num, linesep (0 for no-double), dsize (0 for no dashes) +% radius, phase_angle, x_center, y_center +% in which num is the number of windings of the gluon. +% + gsw + translate + /phase ed /radius ed /dsize ed /num ed /ampi ed + /num num 0.5 sub round def + /darc 180 num div def +% +% We rotate in such a way that 0 angle becomes more accessible. +% + darc phase add rotate +% + dsize 0 eq { + [] 0 setdash + } { + /dr radius 2 mul pi mul def % 2*pi*r + /inc dr 2 num mul div def % 2*pi*r/(2*num) + /const 360 dr div def % 360/(2*pi*r) + /amp8 ampi 0.9 mul def + /amp1 radius ampi add def + /amp2 radius ampi sub def + /amp4 amp1 inc amp8 add const mul cos div def + /amp5 amp2 amp8 const mul cos div def + amp8 0 lt {/amp8 amp8 neg def} if + /xx inc 2 mul def + /x0 amp1 inc const mul cos mul def + /y0 amp1 inc const mul sin mul def + amp4 xx amp8 add const mul cos mul x0 sub + amp4 xx amp8 add const mul sin mul y0 sub + amp5 xx amp8 add const mul cos mul x0 sub + amp5 xx amp8 add const mul sin mul y0 sub + amp2 xx const mul cos mul x0 sub + amp2 xx const mul sin mul y0 sub + 1 lengthofbezier + /size ed +% + /ndash size dsize 2 mul div truncate def + ndash 0 eq { /ndash 1 def } if + size 2 dsize ndash mul mul sub abs + size 2 dsize ndash 1 add mul mul sub abs gt { /ndash ndash 1 add def } if + /dsize size 2 ndash mul div def + [ dsize dsize ] dsize 2 div setdash + } ifelse +% + /dr radius 2 mul pi mul def % 2*pi*r + /inc dr 2 num mul div def % 2*pi*r/(2*num) + /const 360 dr div def % 360/(2*pi*r) + /amp8 ampi 0.9 mul def + /amp1 radius ampi add def + /amp2 radius ampi sub def + /amp4 amp1 inc amp8 add const mul cos div def + /amp5 amp2 amp8 const mul cos div def + amp8 0 lt {/amp8 amp8 neg def} if +% + newpath +% + /xx inc 2 mul def + amp1 inc const mul cos mul amp1 inc const mul sin mul moveto +% + 1 1 num { pop + amp4 xx amp8 add const mul cos mul + amp4 xx amp8 add const mul sin mul + amp5 xx amp8 add const mul cos mul + amp5 xx amp8 add const mul sin mul + amp2 xx const mul cos mul + amp2 xx const mul sin mul + curveto + amp5 xx amp8 sub const mul cos mul + amp5 xx amp8 sub const mul sin mul + amp4 xx amp8 sub const mul cos mul + amp4 xx amp8 sub const mul sin mul + amp1 xx inc add const mul cos mul + amp1 xx inc add const mul sin mul + curveto + /xx xx inc 2 mul add def + } for +% + stroke +% + grestore +} def } +% +% #] dashgluoncirc : +% #[ arc2 : +% +\special{! /arc2{ +% Draws an arc segment: +% arrowspec, arrowpos, flip, linesep, dsize, +% clock, radius, start_angle, end_angle, x_center, y_center, width, scale +% If linesep == 0, then single line, else double with separation linesep. +% + gsw + normalizearc + /darc ed /radius ed + /dsize ed /linesep ed + /angdsize dsize radius div def + /flip ed + getarrow + /arcmid darc arrowpos mul def + /linewidth width def + dsize 0 eq + { linesep 0 eq + { 0 0 radius 0 darc dasharc } + { gsave + linesep linewidth add setlinewidth + 0 0 radius 0 darc dasharc + setbackgroundcolor + [] 0 setdash + linesep linewidth sub setlinewidth + 0 0 radius 0 darc dasharc + grestore + } ifelse + } + { linesep 0 eq + { 0 0 radius 0 arcmid dasharc + 0 0 radius arcmid darc dasharc + } { + gsave + linesep linewidth add setlinewidth + 0 0 radius 0 arcmid dasharc + 0 0 radius arcmid darc dasharc + setbackgroundcolor + [] 0 setdash + linesep linewidth sub setlinewidth + 0 0 radius 0 darc dasharc + grestore + } ifelse + } ifelse + arcmid rotate + radius 0 translate + flip { 0 } { 180 } ifelse + witharrow { drawarrow } if + grestore +} def } +% +% #] arc2 : +% #[ dasharrowdoubleline : +% +\special{! /dasharrowdoubleline{ +% +% arrowspec, arrowpos, flip, linesep, dsize, +% x1, y1, x2, y2, width, scale +% If linesep == 0, then single line, else double with separation linesep. +% Draws a dashed double straight line with arrow. +% If dsize==0, then continuous line. +% If linesep==0, then single line. + gsw + normalizeline + /dr ed + /dsize ed + /linesep ed + /flip ed + getarrow +% + % If linesep is negative, that means the arrow is flipped. + % But the lineend coordinates are already flipped, so there is + % no need to make any adjustment; i.e., replace linesep by + % absolute value. + /linesep setabs + /linewidth width def + linesep 0 eq { + 0 0 dr 0 dashline + } { + gsave + linesep linewidth add setlinewidth 0 0 dr 0 dashline + setbackgroundcolor + [] 0 setdash + linesep linewidth sub setlinewidth 0 0 dr 0 newpath moveto lineto stroke + grestore + } ifelse + dr arrowpos mul 0 translate + flip { -90 }{ 90 } ifelse + witharrow { drawarrow } if + grestore +} def } +% +% #] dasharrowdoubleline : +% #[ vertex : +% +\special{! /vertex{ +% +% Puts a fat dot at x,y size is the radius of the dot +% + gs + /dotsize ed + translate + newpath + 0 0 dotsize 0 360 arc + fill stroke + grestore +} def } +% +% #] vertex : +% #[ ecirc : +% +\special{! /ecirc{ +% +% Draws an anti-clockwise circle : +% x_center, y_center, radius +% Transparent interior +% + gsw /radius ed + translate % x and y are still on stack + newpath 0 0 radius 0 360 arc stroke + grestore +} def } +% +% #] ecirc : +% #[ ebox : +% +\special{! /ebox{ +% +% Draws a transparent box x1,y1,x2,y2 +% + gsw p2 p1 + abox stroke + grestore +} def } +% +% #] ebox : +% #[ fbox : +% +\special{! /fbox{ +% +% Draws a filled box x1,y1,x2,y2 +% + gsw p2 p1 + abox fill + grestore +} def } +% +% #] fbox : +% #[ triangle : +% +\special{! /triangle{ +% +% Draws a triangle x1,y1,x2,y2,x3,y3 +% + gsw p3 p2 p1 + atriangle stroke + grestore +} def } +% +% #] triangle : +% #[ ftriangle : +% +\special{! /ftriangle{ +% +% Draws a triangle x1,y1,x2,y2,x3,y3 +% + gsw p3 p2 p1 + atriangle fill + grestore +} def } +% +% #] ftriangle : +% #[ ellipse: +% +\special{! /ellipse { + % Draw an ellipse + % RedGrittyBrick 20/10/2003 + % From http://www.redgrittybrick.org/postscript/ellipse.html. 2011/03/22 + % draw an ellipse using four bezier curves + % + /r2 exch def % 2nd parameter + /r1 exch def % 1st parameter + /kappa 0.5522847498 def + % + newpath + 0 r2 moveto % start point of curve + % + % top clockwise + kappa r1 mul r2 % 1st Bezier control point + r1 kappa r2 mul % 2nd Bezier control point + r1 0 curveto % end point of curve + % + % right clockwise + r1 kappa r2 mul neg + kappa r1 mul r2 neg + 0 r2 neg curveto + % + % bottom clockwise + kappa r1 mul neg r2 neg + r1 neg kappa r2 mul neg + r1 neg 0 curveto + % + % left clockwise + r1 neg kappa r2 mul + kappa r1 mul neg r2 + 0 r2 curveto + % + } def % ellipse +} +% +% #] ellipse: +% #[ goval : +% +\special{! /goval{ +% +% Draws a gray oval that overwrites whatever was there. +% x_center y_center height width rotation color linewidth scale +% + gsw /gcolor ed /angle ed /width ed /height ed +% + translate % x and y are still on stack + angle rotate + 1 setgray width height ellipse fill + gcolor setgray width height ellipse fill + 0 setgray width height ellipse stroke + grestore +} def } +% +% #] goval : +% #[ fcoval : +% +\special{! /foval{ +% +% Draws an oval that overwrites whatever was there. +% x_center y_center height width rotation linewidth scale +% + gsw /angle ed /width ed /height ed +% + translate % x and y are still on stack + angle rotate + width height ellipse fill + grestore +} def } +% +% #] foval : +% #[ oval : +% +\special{! /oval{ +% +% Draws an oval that does not overwrite whatever was there. +% x_center y_center height width rotation linewidth scale +% + gsw /angle ed /width ed /height ed +% + translate % x and y are still on stack + angle rotate + width height ellipse stroke + grestore +} def } +% +% #] oval : +% #[ polygon : +% +% Incoming stack: +% [array of x,y pairs] width scale +% +\special{! /polygon{ + gsw /points ed + /ss points length 2 idiv 2 mul def + ss 4 gt { + newpath + points 0 get points 1 get moveto + 0 2 ss 4 sub { /ii ed + /x1 points ii 2 add get def + /y1 points ii 3 add get def + x1 y1 lineto + } for + closepath + stroke + } if + grestore +} def } +% +% #] polygon : +% #[ filledpolygon : +% +% Incoming stack: +% [array of x,y pairs] width scale +% +\special{! /filledpolygon{ + gsw /points ed + /ss points length 2 idiv 2 mul def + ss 4 gt { + newpath + points 0 get points 1 get moveto + 0 2 ss 4 sub { /ii ed + /x1 points ii 2 add get def + /y1 points ii 3 add get def + x1 y1 lineto + } for + closepath + fill + } if + grestore +} def } +% +% #] filledpolygon : +% #[ makecurve : +% +\special{! /docurve{ + x1 2 mul x2 add 3 div + y1 y0 sub x1 x0 sub div x2 x0 sub mul + y2 y0 sub x2 x0 sub div x1 x0 sub mul add + y1 add y0 2 mul add 3 div + x1 x2 2 mul add 3 div + y2 y3 sub x2 x3 sub div x1 x3 sub mul + y1 y3 sub x1 x3 sub div x2 x3 sub mul add + y2 add y3 2 mul add 3 div + x2 y2 curveto +} def } +% +\special{! /makecurve{ +% +% Incoming stack: +% [array of x,y pairs] width scale +% + gsw /points ed + /ss points length 2 idiv 2 mul def + newpath + ss 4 gt { + /x1 points 0 get def + /y1 points 1 get def + /x2 points 2 get def + /y2 points 3 get def + /x3 points 4 get def + /y3 points 5 get def + /x0 x1 2 mul x2 sub def + /y0 y3 y2 sub x3 x2 sub div y2 y1 sub x2 x1 sub div sub 2 mul + x2 x1 sub dup mul x3 x1 sub div mul + y1 2 mul add y2 sub def + x1 y1 moveto + docurve + 0 2 ss 8 sub { /ii ed + /x0 points ii get def + /y0 points ii 1 add get def + /x1 points ii 2 add get def + /y1 points ii 3 add get def + /x2 points ii 4 add get def + /y2 points ii 5 add get def + /x3 points ii 6 add get def + /y3 points ii 7 add get def + docurve + } for + /x0 points ss 6 sub get def + /y0 points ss 5 sub get def + /x1 points ss 4 sub get def + /y1 points ss 3 sub get def + /x2 points ss 2 sub get def + /y2 points ss 1 sub get def + /x3 x2 2 mul x1 sub def + /y3 y2 y1 sub x2 x1 sub div y1 y0 sub x1 x0 sub div sub 2 mul + x2 x1 sub dup mul x2 x0 sub div mul + y2 2 mul add y1 sub def + docurve + } { + ss 4 eq { + points 0 get points 1 get moveto + points 2 get points 3 get lineto + } if + } ifelse + stroke + grestore +} def } +% +% #] makecurve : +% #[ makedashcurve : +% +\special{! /makedashcurve{ +% +% Incoming stack: +% [array of x,y pairs] dashsize width scale +% + gsw /dsize ed /points ed + /ss points length 2 idiv 2 mul def + newpath + ss 4 gt { + /x1 points 0 get def + /y1 points 1 get def + /x2 points 2 get def + /y2 points 3 get def + /x3 points 4 get def + /y3 points 5 get def + /x0 x1 2 mul x2 sub def + /y0 y3 y2 sub x3 x2 sub div y2 y1 sub x2 x1 sub div sub 2 mul + x2 x1 sub dup mul x3 x1 sub div mul + y1 2 mul add y2 sub def + x1 y1 moveto + docurve + 0 2 ss 8 sub { /ii ed + /x0 points ii get def + /y0 points ii 1 add get def + /x1 points ii 2 add get def + /y1 points ii 3 add get def + /x2 points ii 4 add get def + /y2 points ii 5 add get def + /x3 points ii 6 add get def + /y3 points ii 7 add get def + docurve + } for + /x0 points ss 6 sub get def + /y0 points ss 5 sub get def + /x1 points ss 4 sub get def + /y1 points ss 3 sub get def + /x2 points ss 2 sub get def + /y2 points ss 1 sub get def + /x3 x2 2 mul x1 sub def + /y3 y2 y1 sub x2 x1 sub div y1 y0 sub x1 x0 sub div sub 2 mul + x2 x1 sub dup mul x2 x0 sub div mul + y2 2 mul add y1 sub def + docurve + } { + ss 4 eq { + points 0 get points 1 get moveto + points 2 get points 3 get lineto + } if + } ifelse + centerdash + stroke + grestore +} def } +% +\special{! /pathlength{ + flattenpath + /dist 0 def + { /yfirst ed /xfirst ed /ymoveto yfirst def /xmoveto xfirst def } + { /ynext ed /xnext ed /dist dist ynext yfirst sub dup mul + xnext xfirst sub dup mul add sqrt add def + /yfirst ynext def /xfirst xnext def } + {} + {/ynext ymoveto def /xnext xmoveto def + /dist ynext yfirst sub dup mul + xnext xfirst sub dup mul add sqrt add def + /yfirst ynext def /xfirst xnext def } + pathforall + dist +} def } +% +\special{! /centerdash{ + /pathlen pathlength def + /jj pathlen dsize div 2.0 div cvi def + /ddsize pathlen jj 2.0 mul div def + [ddsize] ddsize 2 div setdash +} def } +% +% #] makedashcurve : +% #[ logaxis : +% +\special{! /logaxis{ +% +% Draws an axis from x1,y1 to x2,y2 with nl log divisions +% size of the hashes hs, offset F +% and width W. The stack looks like +% x1,y1,x2,y2,nl,hs,F,W,scale +% After the rotation the hash marks are on top if nl is positive and +% on the bottom if nl is negative +% + gsw /offset ed /hashsize ed /nlogs ed + normalizeline /rr ed + offset 0 ne { /offset offset ln 10 ln div def } if + /offset offset dup cvi sub def + newpath + 0 0 moveto + rr 0 lineto + /lsize rr nlogs div def + 0 1 nlogs { /x2 ed + x2 offset ge { + /y2 x2 offset sub lsize mul def + y2 rr le { + y2 0 moveto + y2 hashsize 1.2 mul lineto + } if + } if + } for + stroke + width 0.6 mul setlinewidth + newpath + 0 1 nlogs { /x2 ed + 2 1 9 { + ln 10 ln div x2 add + /xx2 ed + xx2 offset ge { + /y2 xx2 offset sub lsize mul def + y2 rr le { + y2 0 moveto + y2 hashsize 0.8 mul lineto + } if + } if + } for + } for + stroke + grestore +} def } +% +% #] logaxis : +% #[ linaxis : +% +\special{! /linaxis{ +% +% x1,y1,x2,y2,num_decs,per_dec,hashsize,offset,width,scale +% + gsw /offset ed /hashsize ed /perdec ed /numdec ed + normalizeline + /rr ed + /perdec perdec round def + /offset offset + % Do real equivalent of offset perdec mod + dup cvi perdec idiv + sub + dup 0 lt {perdec add} if + dup perdec ge {perdec sub} if + def + newpath + 0 0 moveto + rr 0 lineto + /x1 rr numdec perdec mul div def + /y1 rr numdec div def + offset 0 eq {0} {1} ifelse 1 numdec + { y1 mul offset x1 mul sub + dup 0 moveto + hashsize 1.2 mul lineto + } for + stroke + width 0.6 mul setlinewidth + newpath + /offset offset dup cvi sub def + offset 0 eq {0} {1} ifelse 1 numdec perdec mul { + offset sub x1 mul + dup 0 ge { + dup rr le { + dup 0 moveto + hashsize 0.8 mul lineto + } if + } if + } for + stroke + grestore +} def } +% +% #] linaxis : +% #[ dashbezier : +% +\special{! /dashbezier{ +% +% Draws a dashed Bezier with control points x1,y1,x2,y2,x3,y3,x4,y4 +% + gsw /dsize ed p4 p3 p2 p1 + dsize 0 ne { + /size x2 x1 sub y2 y1 sub x3 x1 sub y3 y1 sub x4 x1 sub y4 y1 sub + 1 lengthofbezier def + /numdashes size dsize 2 mul div def + numdashes 0 eq { /numdashes 1 def } if + size dsize 2 mul numdashes mul sub abs + size dsize 2 mul numdashes 1 add mul sub abs + gt { /numdashes 1 add def } if + /dsize size numdashes 2 mul div def + [dsize dsize] dsize 2 div setdash + } if + abezier stroke + grestore +} def } +% +% #] dashbezier : +% #[ dashdoublebezier : +% +\special{! /dashdoublebezier{ +% +% Draws a dashed Bezier with control points x1,y1,x2,y2,x3,y3,x4,y4 +% + gsw /dsize ed /linesep ed + /flip ed + getarrow + p4 p3 p2 p1 + /linewidth width def + /bsize x2 x1 sub y2 y1 sub x3 x1 sub y3 y1 sub x4 x1 sub y4 y1 sub + 1 lengthofbezier def + dsize 0 ne { + /numdashes bsize dsize 2 mul div def + numdashes 0 eq { /numdashes 1 def } if + bsize dsize 2 mul numdashes mul sub abs + bsize dsize 2 mul numdashes 1 add mul sub abs + gt { /numdashes 1 add def } if + /dsize bsize numdashes 2 mul div def + [dsize dsize] dsize 2 div setdash + } if + linesep 0 ne { + linesep linewidth add setlinewidth abezier stroke + gsave + 0 0 0 0 setcmykcolor + linesep linewidth sub setlinewidth abezier stroke + grestore + } { + abezier stroke + } ifelse +% + witharrow { + /tb arrowpos def + /tbmax 1 def /tbmin 0 def + { + /sizeb x2 x1 sub y2 y1 sub x3 x1 sub y3 y1 sub x4 x1 sub y4 y1 sub + tb lengthofbezier def + sizeb bsize div arrowpos sub abs 0.0001 le { exit } if + sizeb bsize div arrowpos gt + { /tbmax tb def /tb tb tbmin add 2 div def } + { /tbmin tb def /tb tb tbmax add 2 div def } ifelse + } loop + /ub 1 tb sub def + x1 ub ub ub mul mul mul tb x2 3 mul ub mul ub mul tb x3 3 mul ub mul + x4 tb mul add mul add mul add + y1 ub ub ub mul mul mul tb y2 3 mul ub mul ub mul tb y3 3 mul ub mul + y4 tb mul add mul add mul add translate + y4 tb dup mul mul y3 tb mul 2 3 tb mul sub mul add y2 ub mul 1 3 tb mul + sub mul add y1 ub dup mul mul sub 3 mul + x4 tb dup mul mul x3 tb mul 2 3 tb mul sub mul add x2 ub mul 1 3 tb mul + sub mul add x1 ub dup mul mul sub 3 mul + atan rotate + flip { -90 }{ 90 } ifelse + drawarrow + } if +% + grestore +} def } +% +% #] dashdoublebezier : +% #[ lengthofbezier : +% +% Calculates the length of a Bezier curve assuming that we start +% in the point 0,0. We use a Gaussian quadrature with 16 points. +% If, at any time, more precision is needed we have the 32 points +% numbers in axohelp.c. (and there is more commentary in that file) +% +\special{! + /g16x1 { 0.095012509837637440185 } def + /g16x2 { 0.281603550779258913230 } def + /g16x3 { 0.458016777657227386342 } def + /g16x4 { 0.617876244402643748447 } def + /g16x5 { 0.755404408355003033895 } def + /g16x6 { 0.865631202387831743880 } def + /g16x7 { 0.944575023073232576078 } def + /g16x8 { 0.989400934991649932596 } def + /g16w1 { 0.189450610455068496285 } def + /g16w2 { 0.182603415044923588867 } def + /g16w3 { 0.169156519395002538189 } def + /g16w4 { 0.149595988816576732081 } def + /g16w5 { 0.124628971255533872052 } def + /g16w6 { 0.095158511682492784810 } def + /g16w7 { 0.062253523938647892863 } def + /g16w8 { 0.027152459411754094852 } def + /onepoint { + /gpt ed + /tpt 1 gpt add 2 div tmax mul def + xc tpt mul xb add tpt mul xa add dup mul + yc tpt mul yb add tpt mul ya add dup mul + add sqrt + /tpt 1 gpt sub 2 div tmax mul def + xc tpt mul xb add tpt mul xa add dup mul + yc tpt mul yb add tpt mul ya add dup mul + add sqrt add 2 div + } def + /lengthofbezier { + /tmax ed + pp3 pp2 pp1 + /xa xx1 3 mul def /xb xx2 xx1 2 mul sub 6 mul def + /xc xx3 xx2 xx1 sub 3 mul sub 3 mul def + /ya yy1 3 mul def /yb yy2 yy1 2 mul sub 6 mul def + /yc yy3 yy2 yy1 sub 3 mul sub 3 mul def +% + g16x1 onepoint g16w1 mul + g16x2 onepoint g16w2 mul add + g16x3 onepoint g16w3 mul add + g16x4 onepoint g16w4 mul add + g16x5 onepoint g16w5 mul add + g16x6 onepoint g16w6 mul add + g16x7 onepoint g16w7 mul add + g16x8 onepoint g16w8 mul add + tmax mul + } def +} +% #] lengthofbezier : +% #[ axogrid : +% +\special{! /axogrid{ + gsw translate + /ny ed /nx ed /dy ed /dx ed + /maxx nx dx mul def + /maxy ny dy mul def + 0 1 nx { + newpath dx mul dup 0 moveto maxy lineto stroke + } for + 0 1 ny { + newpath maxx exch dy mul dup 0 exch moveto lineto stroke + } for +} def } +% +% #] axogrid : +} +% #] PostScript preamble : +% #[ axoparray : Puts an array of 2-dim points +% +% Puts a sequence of points in the notation (x1,y1)(x2,y2).... +% on the Postscript stack. This is for Curve and DashCurve. +% +\let\eind=] +% +\def\axoparray(#1,#2)#3{#1 \axoxo\space add #2 \axoyo\space add \ifx #3\eind\else +\expandafter\axoparray\fi#3} +% +% #] axoparray : +% +\fi +% #] Postscript specific : +% #[ PDF specific : +% +% Here are the routines that are used purely for the PDF output. +% The main concern here is the communication with the axohelp program. +% +\ifcase\axo@pdfoutput\else +% +% #[ getaxohelp : +% +% This is the command that makes the PDF work. Use as in +% getaxohelp{NameOfFunction}{parameters to be passed} +% The format is very precise. If axohelp is not happy there will +% be no output. The most common error is that the parameters are +% not separated by black spaces. Some \space might have to be inserted. +% The reason we do not separate the parameters by comma's is that +% both Postscript and PDF want their objects separated by blanks. +% Also a separation by blanks makes the parameters into separate +% arguments in the call to axohelp. Our colors need blanks.... +% +% +\def\getoneline#1#2{% + % Set the command of name #1 to the next line of the file + % for which the input stream number is #2. + \def\tmpfh{#2}% + \ifeof\tmpfh + \else + \read\tmpfh to \tmpline + \fi + \ifeof\tmpfh + \@namedef{#1}{}% + \else + \expandafter \let \csname #1\endcsname = \tmpline + \fi +} +% +\def\getaxohelp#1#2{% + \def\axohelp{}% + \stepcounter{axo@objectIndex}% + \def\axo@currentInput{#1 #2;}% + \immediate\write\axo@spec{[\arabic{axo@objectIndex}]\space \axo@currentInput}% + \ifaxo@axohelpRerun% + \else% + \def\axo@currentInput{{#1 #2;}}% + \getoneline{axo@partOne}\axo@axohelpFile% + \catcode`\ =13% + \getoneline{axo@partTwo}\axo@axohelpFile% + \catcode`\ =10% + \getoneline{axo@partThree}\axo@axohelpFile% + \ifeof\axo@axohelpFile + \rlap{New object; rerun axohelp}% + \global\axo@axohelpReruntrue + \else + \ifthenelse{\equal{\axo@partTwo}{\axo@currentInput}}% + {% Current definition is same as the one processed + % by axohelp, so it is safe to use + \expandafter\def\expandafter\axohelp\axo@partThree% + }% + {% + \rlap{Changed object; rerun axohelp}% + \global\axo@axohelpReruntrue + }% + \fi + \fi% +} +% +% #] getaxohelp : +% #[ Use the axohelp output : +% +% Implement conversion of length unit from pt to bp by scaling +\def\contentspdf{q \axoscale\space 0 0 \axoscale\space 0 0 cm + 0.99626401 0 0 0.99626401 0 0 cm + 1 0 0 1 \axoxo\space \axoyo\space cm + \axohelp\space + Q} +\def\contentspdfNoOffset{q \axoscale\space 0 0 \axoscale\space 0 0 cm + 0.99626401 0 0 0.99626401 0 0 cm + \axohelp\space + Q} +% +% #] Use the axohelp output : +% +\fi +% #] PDF specific : + +% Process options now, after all potentially necessary commands have +% been defined. Use starred form, so that the options are processed +% in the order the user writes them. Also set defaults here. +\PSTextScalesLikeGraphicstrue +\canvasScaleObjectScale +\ProcessOptions* diff --git a/Master/tlpkg/bin/tlpkg-ctan-check b/Master/tlpkg/bin/tlpkg-ctan-check index 025182365ff..4cc40e17c97 100755 --- a/Master/tlpkg/bin/tlpkg-ctan-check +++ b/Master/tlpkg/bin/tlpkg-ctan-check @@ -52,7 +52,7 @@ my @TLP_working = qw( aucklandthesis augie auncial-new aurical aurl autobreak autopdf authoraftertitle authorindex auto-pst-pdf autoaligne autoarea automata autonum autosp avantgar avremu - awesomebox + awesomebox axodraw2 b1encoding babel babel-albanian babel-azerbaijani babel-basque babel-belarusian babel-bosnian babel-breton diff --git a/Master/tlpkg/libexec/ctan2tds b/Master/tlpkg/libexec/ctan2tds index ebecd525be2..623d0bde4eb 100755 --- a/Master/tlpkg/libexec/ctan2tds +++ b/Master/tlpkg/libexec/ctan2tds @@ -135,7 +135,6 @@ chomp ($Build = `cd $Master/../Build/source && pwd`); 'auto1', "die 'skipping, nonfree font support'", 'autolatex', "die 'skipping, not self-locating'", 'autotab', "die 'skipping, noinfo license, latex 2.09'", - 'axodraw2', "die 'skipping, requires compilation'", 'babel-frenchb', "die 'skipping, use babel-french'", 'babel-serbianc', "&MAKEflatten", 'babel-slovene', "die 'skipping, use babel-slovenian'", @@ -2929,6 +2928,7 @@ $standardclean = '\.head|\.tmp|\.dvi|\.log|\.out|\.aux|\.toc|\.lof|\.lot' 'accfonts' => $standardclean . '|dvips.enc', # dup enc 'acmconf' => $standardclean . '|flushend.sty', # dup with sttools 'apalike' => "apalike2.bst", # does not belong + 'axodraw2' => "axohelp.exe", # later 'bardiag' => "example/.*(aux|log)", # junk on CTAN 'bibleref' => $standardclean . '|sample.tex|sample-.*', # derived uploaded 'bbm-macros' => $standardclean . '|^bbm$', # symlink diff --git a/Master/tlpkg/tlpsrc/axodraw2.tlpsrc b/Master/tlpkg/tlpsrc/axodraw2.tlpsrc new file mode 100644 index 00000000000..e69de29bb2d --- /dev/null +++ b/Master/tlpkg/tlpsrc/axodraw2.tlpsrc diff --git a/Master/tlpkg/tlpsrc/collection-mathscience.tlpsrc b/Master/tlpkg/tlpsrc/collection-mathscience.tlpsrc index 96574c234f1..8d4c7b30889 100644 --- a/Master/tlpkg/tlpsrc/collection-mathscience.tlpsrc +++ b/Master/tlpkg/tlpsrc/collection-mathscience.tlpsrc @@ -14,6 +14,7 @@ depend algorithms depend amstex depend apxproof depend autobreak +depend axodraw2 depend backnaur depend begriff depend binomexp |