\documentclass{scrartcl}
\usepackage[text={6.5in,9in},centering]{geometry}
\usepackage{graphicx}
\usepackage{ifthen}
\usepackage{makeidx}
\usepackage{datetime}
\makeindex
\usepackage[pdftex,
pdfpagelayout=SinglePage,
bookmarks,
bookmarksopen,
bookmarksopenlevel=3,
pdftoolbar,
colorlinks=true,
pdfstartview=FitV,
linkcolor=blue,
citecolor=blue,
urlcolor=blue]{hyperref}
\parskip 2mm plus 2mm
\parindent 0mm
\newcommand{\todo}[1]{\paragraph{To do:} #1}
\newcommand{\dfrac}[2]{\ensuremath{\displaystyle{\frac{#1}{#2}}}}
\newcommand{\unit}[2]{\ensuremath{#1\;\mbox{#2}}}
\newcommand{\lra}{\longrightarrow}
\newcommand{\be}{\begin{eqnarray*}}
\newcommand{\ee}{\end{eqnarray*}}
\newcommand{\ben}{\begin{eqnarray}}
\newcommand{\een}{\end{eqnarray}}
% Special fonts
\newcommand{\kw}[1]{\ensuremath{\texttt{#1}}}
\newcommand{\id}[1]{\ensuremath{\textsl{#1}}}
\newcommand{\agl}[1]{\ensuremath{\langle\id{\textrm{\textsl #1}}\rangle}}
% Cross-reference
\newcommand{\xe}[1]{(\ref{#1})}
\newcommand{\xf}[1]{Figure~\ref{#1}}
\newcommand{\xfp}[1]{Figure~\ref{#1} on page~\pageref{#1}}
\newcommand{\xs}[1]{(\S\ref{#1}\,:\,\pageref{#1})}
% Figures generated by MetaPost
% #1 = positioning [htbp]; #2 = Metapost file number; #3 = caption; #4 = cross-reference key.
\newcommand{\mpfig}[4]{
\begin{figure}[#1]
\hrule\vskip2mm
$$\includegraphics{figs-#2.mps}$$
\caption{#3}
\label{#4}
\vskip2mm\hrule
\end{figure}
}
\newcommand{\fg}[1]{\includegraphics{figs-#1.mps}}
% Set MP programs
\newenvironment{prog}{\def\-{\hskip 2em}\penalty-1000\vskip\parskip
\parskip0pt\leftskip2pc\obeylines\ttfamily}{\par}
\newcommand{\bpr}{\begin{prog}}
\newcommand{\epr}{\end{prog}}
% Put code on the left and (optionally) output on the right.
% Allowable sequences are \bex ... \eex and \bex ... \mex ... \eex.
% Arguments give box widths.
\newcommand{\bex}[1]{\par\medskip\begin{minipage}{#1}\begin{prog}}
\newcommand{\mex}[1]{\end{prog}\end{minipage}\hfill\begin{minipage}{#1}\begin{prog}}
\newcommand{\eex}{\end{prog}\end{minipage}\par\smallskip}
% Put code on the left and a MP figure on the right.
% \bep argument is the width of the code box.
% \eep arguments are the amount to raise the box (usually negative) and the file number.
\newcommand{\bep}[1]{\par\medskip\begin{minipage}{#1}\begin{prog}}
\newcommand{\eep}[2]{\end{prog}\end{minipage}\hfill\raisebox{#1}
{\includegraphics{figs-#2.mps}}
% Remove the next line to eliminate marginal numbers.
\marginpar{\##2}
\bigskip}
\renewcommand{\mp}{\textsc{MetaPost}}
\newcommand{\umm}{\textsc{umm}}
\newcommand{\iumm}{\textsc{umm}\index{umm@\umm}}
% Protect >> and --
\newcommand{\sh}{\kw{>{}>}}
\newcommand{\ds}{\,\kw{-{}-}\,}
\newcommand{\dss}{\,\kw{-{}-{}-}\,}
\newcommand{\dd}{\kw{\,.\,.\,}}
\newcommand{\ddd}{\kw{\,.\,.\,.\,}}
\newcommand{\idx}[1]{#1\index{#1}} % Print a word and index it
\newcommand{\idc}[1]{\index{#1@\kw{#1}}} % Index a command
\newcommand{\ikw}[1]{\kw{#1}\idc{#1}} % Print a command and index it
\newcommand{\defeq}{\ensuremath{\stackrel{\Delta}{=}}}
\newcommand{\dg}{^\circ}
% Boxed quotations.
% #1 is the quotation
\newlength{\bqtext}
\newlength{\bqbox}
\newcommand{\boxedquote}[1]{
\fboxsep 8pt
\settowidth{\bqtext}{\textbf{\textsl{#1}}}
\ifthenelse
{\lengthtest{\bqtext < 0.9\textwidth}}
{\setlength{\bqbox}{\bqtext}}
{\setlength{\bqbox}{0.5\bqtext}}
\addtolength{\bqbox}{1em}
\begin{center}\fbox{
\begin{minipage}{\bqbox}
\textbf{\textsl{#1}}
\end{minipage}}
\end{center}}
\renewcommand{\topfraction}{0.9}
\renewcommand{\bottomfraction}{0.9}
\renewcommand{\textfraction}{0.1}
\renewcommand{\floatpagefraction}{0.9}
\pagestyle{headings}
\begin{document}
\pagenumbering{roman}
\thispagestyle{empty}
\title{\mp: A Reference Manual}
\author{Peter Grogono}
\date{22 June 2014}
\maketitle
\tableofcontents
\listoffigures
\clearpage
\pagenumbering{arabic}
\thispagestyle{empty}
\section{Introduction}\label{sec:introduction}
\mp\ is a picture-drawing language that generates diagrams and pictures in em\-bedded post\-script. \mp, an extension of Donald Knuth's MetaFont, was designed and implemented by John Hobby at AT\&T Bell Laboratories.
The official guide for \mp, Hobby's \emph{A User's Manual for \mp}, referred to in this manual as \iumm, is written in a narrative style that is easy to read but hard to learn from. Several other people have written \mp\ manuals in narrative form. This manual is intended both to help beginners and to serve as a reference.
Examples of \mp\ code in this manual are intentionally short. This should make it easier to see the point of the example. With long and complex examples, it is sometimes hard to relate the code to the output. There are some longer examples at the end \xs{sec:examples}.
This manual is not complete. Important omissions are indicated by a reference to \iumm. In particular, \umm\ includes a complete grammar for \mp, whereas this manual relies mostly on examples.
\paragraph{Conventions}
\begin{itemize}
\item Since there are a large number of cross-references in this manual, we use a concise notation. For example, \xs{sec:transform} is a reference to Section~\ref{sec:transform} which is to be found on page~\pageref{sec:transform}.
\item Most lists in \mp\ use comma as a separator. Unless stated otherwise, the term ``list of $X$'' means a list of the form $X_1,X_2,X_3,\ldots$.
\item In grammar rules, \agl{pred} indicates a predicate (\kw{boolean}-valued expression) and \agl{seq} indicates a sequence of commands.
\item The command ``$\kw{show} \; \agl{expr};$'' displays `\verb">>"' followed by the value of the expression \xs{sec:show}. In examples containing \kw{show}, we put the code on the left of the page and the output to the right of it, like this:
\bex{80mm}
show (3,4) + (5,6);
\mex{60mm}
\sh\ (8,10)
\eex
\item Similarly, we illustrate drawing techniques by putting code on the left and the picture produced on the right. The ``\#15'' in the right margin indicates that this figure was generated by commands between \ikw{beginfig(15)} and \ikw{endfig} in the \mp\ source file, \ikw{mpref.mp}. The order of figures in the \mp\ source file does not correspond to the order in which they are used in the manual.
\bep{100mm}
draw unitsquare rotated 45 scaled 25;
\eep{-5mm}{15}
\item We use the symbol \defeq\ to mean ``is defined to be equal to''.
\end{itemize}
\paragraph{Acknowledgments} I am indebted to Brian Shearing for ingenious hints on \mp\ usage --- and, indeed, for informing me of its existence in the first place.
\section{Basic Concepts}\label{sec:basic}
\subsection{Version}
Features were added to \mp\ as it evolved. This manual describes Version 1.000 but also includes some useful features of later versions. The string constant \ikw{mpversion} \xs{sec:string} will tell you what \idx{version} you are using, but only if it is a fairly recent version.
\bex{80mm}
show mpversion;
\mex{60mm}
\sh\ "1.005"
\eex
\subsection{Input format}\label{sec:input}
\mp\ is a program that reads an input \idx{file}\index{input file} with a name of the form \agl{name}\kw{.mp} and writes several output files\index{output!to file}. By default, the names of the output files are \agl{name}\kw{.1}, \agl{name}\kw{.2}, \agl{name}\kw{.3}, etc. For example, if the input file was \kw{fig.mp} then the output files would be are \kw{fig.1}, \kw{fig.2}, \kw{fig.3}, and so on. The precise form of the output file name is controlled by the command \ikw{filenametemplate} \xs{sec:filenametemplate}. For example, if the command
\begin{verbatim}
filenametemplate "figs-%c.mps";
\end{verbatim}
occurs at the beginning of the \mp\ source file, the figure file names will be \verb'figs-1.mps', \verb'figs-2.mps', and so on. The suffix \verb'.mps' has the advantage that it is recognized by the \LaTeX\ package \verb'graphicx'.
The output files are read by \TeX, \LaTeX, or any program that accepts embedded postscript files.
In the input file, each figure is introduced by \kw{beginfig($n$)},\index{beginfig@\kw{beginfig}} where $n$ is the number of the figure, and terminated with \ikw{endfig}. Commands may occur outside figures as well as inside them. An input file has the general form (note the final \kw{end}):
\bex{100mm}
\agl{seq}
~
beginfig(1);
\-\agl{seq}
endfig;
~
\agl{seq}
~
beginfig(2);
\-\agl{seq}
endfig;
~
....
~
beginfig($n$);
\-\agl{seq}
endfig;
~
end
\eex
\subsection{The \LaTeX\ File}\label{sec:latexfile}
There are several ways of including \mp\ diagrams in a \LaTeX\ files. Two of them are described below.
\paragraph{Using the \kw{hyperref} Package}
Assume that the file generated by \mp\ for figure $n$ is called \agl{name}.\agl{number}, where
\begin{itemize}
\item \agl{name}\kw{.mp} is the name of the file processed by \mp
\item \agl{number} is the number of the figure
\end{itemize}
This is the format that \mp\ uses by default.
Include the \ikw{hyperref} package by writing
\bpr\verb'\usepackage[...]{hyperref}'\epr
in the preamble of your \LaTeX\ document. This package has many useful options, indicated here by `\kw{...}'. To insert \mp\ figure $n$ in your document, write
\bpr\verb'\convertMPtoPDF{'\agl{name}.\agl{number}\verb'}{'\agl{Xscale}\verb'}{'\agl{Yscale}\verb'}'\epr
in which \agl{Xscale} is the horizontal magnification factor and \agl{Yscale} is the vertical magnification factor. For example, to include Figure 3 generated from \kw{figs.mp} at half its original size, write:
\bpr\verb'\convertMPtoPDF{figs.3}{0.5}{0.5}}'\epr
\paragraph{Using the \kw{graphicx} Package}
Include the \ikw{graphicx} package by writing
\bpr\verb'\usepackage{graphicx}'\epr
in the preamble of your \LaTeX\ document.
The \kw{graphicx} package may not recognize files created by \mp\ with default settings, because these files have a numeric extension. To avoid this problem, include this directive at the beginning of the \mp\ source file \xs{sec:filenametemplate}:
\begin{verbatim}
filenametemplate "figs-%c.mps";
\end{verbatim}
To insert \mp\ figure $n$ in your document, write
\bpr\verb'\includegraphics{figs-'$n$\verb'}'\epr
Use optional arguments to \verb'\includegraphics' to scale the diagram if necessary. Use standard \LaTeX\ commands to position it. One possibility is to use an equation environment to centre the diagram. For example:
\bpr\verb'$$ \includegraphics[width=5in]{mypics.7} $$'\epr
\paragraph{The file \kw{mproof.tex}}
The \TeX\ file \ikw{mproof} creates a ``proof sheet'' in the form of a \kw{.dvi} file from \mp\ output. After the following run, \kw{mproof.dvi} contains the text ``\kw{figs.65}'' and the corresponding figure.
\begin{verbatim}
D:\Pubs>tex mproof figs.65
This is TeX, Version 3.141592 (MiKTeX 2.6)
(figs.65
figs.65: BoundingBox: llx = -1 lly = -3 urx = 61 ury = 72
figs.65: scaled width = 62.23178pt scaled height = 75.28038pt
)
[1]
Output written on mproof.dvi (1 page, 396 bytes).
\end{verbatim}
\subsection{Comments}\index{comments}
\mp\ comments are delimited by the character `\kw{\%}' and the end of the line on which \kw{\%} appears, as in \LaTeX.
\subsection{Units}\label{sec:units}
The default \idx{units} of \mp\ are \emph{Postscript points}. Postscript points\index{point!Postscript} are also called ``\idx{big points}'' because they are slightly bigger than printer's points\index{point!printer's}. The abbreviations for Postscript points and printer's points are \kw{bp}\index{bp@\kw{bp} (big point)} and \kw{pt}\index{pt@\kw{pt} (printer's point)}, respectively, as in \TeX:
\be
\unit{1}{bp} & = & \unit{1/72}{inches} \\
\unit{1}{pt} & = & \unit{1/72.27}{inches}
\ee
\mp\ also understands the other units provided by \TeX: \ikw{cm} (centimetres), \ikw{mm} (millimetres), \ikw{in} (inches), and \ikw{pc} (picas: $1\kw{pc} = \frac{1}{6}\kw{in})$). The units behave like constants defined with the appropriate values. For example, the value of \kw{10*mm} is the length 10~millimetres expressed in Postscript points. The multiplication operator, \kw{*}, can be omitted if the left operand is a number and the right operand is a variable. At the last line, \mp\ does not report an error for \kw{n mm}, but parses it as a compound name \xs{sec:variables}, \kw{n.mm}, with no defined value.
\bex{80mm}
n = 10;
show 10*mm;
show 10mm;
show n*mm;
show n mm;
\mex{60mm}
\sh\ 28.3464
\sh\ 28.3464
\sh\ 28.3464
\sh\ n.mm
\eex
It is sometimes convenient to define a unit and use it to scale every number. Here is an example of picture \idx{scaling}. The first line can be written as either ``\kw{u = 1cm;}'' or ``\kw{u = cm;}''.
\bep{140mm}
u = 1cm;
draw (0u,0u) -- (1.5u,0u) -- (1.5u,1.5u) -- (0u,1.5u) -- cycle;
z1 = (0u,-0.2u);
z2 = (1.5u,-0.2u);
drawdblarrow z1 -- z2;
label.bot("1.5cm", 0.5[z1, z2]);
\eep{-15mm}{20}
\subsection{Scaling a Picture}\label{sec:scaling}\index{scaling}
There are several ways of making sure that a \mp\ diagram has the required size:
\begin{enumerate}
\item The first method, which might be called the \emph{direct method}, is to use \mp's natural units (Postscript points). Lines of text on this page are about 450bp long, so a diagram that is 400bp wide and 300bp high fits nicely onto a page.
\item The second method is to use a better-known unit of length, such as inches or centimetres. The example above shows how to construct a diagram using centimetres as units.
\item The third method is to construct a diagram of any size and then scale it using the optional arguments of \verb'\convertMPtoPDF' or \verb'\includegraphics' \xs{sec:latexfile}. Here are some examples:
\begin{verbatim}
\convertMPtoPDF{figs.3}{0.5}{0.5}}
\includegraphics[width=4in]{pic-1.mps}
\includegraphics[height=7cm]{pic-2.mps}
\includegraphics[scale=2]{pic-2.mps}
\end{verbatim}
\end{enumerate}
\subsection{Coordinates}\label{sec:coordinates}
\mp\ uses the conventional coordinate system of mathematics: $X$ values increase across the page to the right and $Y$ values increase up the page.
\bep{120mm}
drawarrow (0,0) -- (0,30);
drawarrow (0,0) -- (30,0);
dotlabel.llft(btex $(0,0)$ etex, (0,0));
label.rt(btex $X$ etex, (30,0));
label.top(btex $Y$ etex, (0,30));
\eep{-10mm}{22}
Usually, it does not matter where the origin is, because the Postscript file that \mp\ generates defines a bounding box for all of the visible components of the picture. The origin might be centered, at the lower left, somewhere else inside the bounding box, or even outside it. However, if the origin is inside the picture, some of the coordinates may be negative. Postscript processors occasionally object to \idx{negative coordinates}. This problem is rare but, if it occurs, it can be corrected by concluding each figure with the command
\bex{150mm}
currentpicture := currentpicture shifted (-llcorner currentpicture);
\eex
In this command, \ikw{currentpicture} \xs{sec:picture} is an internal variable of type \kw{picture}, \kw{shifted} is a transform \xs{sec:transform} and \kw{llcorner} gives the coordinates of the lower left corner of a picture.
\subsection{Variables}\label{sec:variables}\index{variable!name}\index{name!of variable}
Almost any string to which \mp\ does not assign a meaning can be used as a variable \idx{name}. For example, \verb'@&#$@' is a legal name. In practice, it is usually better to use more conventional names.
In general, a name consists of a \emph{tag}\index{tag} optionally followed by a \emph{suffix}\index{suffix}. Any sequence of upper and lower case letters is a valid tag. Tags may also contain other characters, of which the most common is `.'. For example, \mp\ uses tags such as \kw{b.n} and \kw{b.s} to denote points on boxes.
The suffix may be a simple numeric, as in \kw{p3}, or an expression in brackets, as in \kw{p[i+3]}. Multidimensional indexes must be separated with dots or brackets: \kw{p.3.4} is equivalent to \kw{p[3][4]}.
The names \ikw{x}, \ikw{y}, and \ikw{z} play a special role. First, they are implicitly local \xs{sec:scope}. Second, they are linked by the implicit equations
\be
z & = & (x,y) \\
\kw{xpart} \; z & = & x \\
\kw{ypart} \; z & = & y
\ee
where $x$, $y$, and $z$ stand for names that start with \kw{x}, \kw{y}, or \kw{z} and are followed by a suffix. Thus \kw{z.a[3]} denotes the pair \kw{(x.a[3], y.a[3])}.
\subsection{Internal Variables}\label{sec:internals}
\mp\ has a large number of \idx{internal variable} names.\index{variable!internal} Internal variables are implicitly declared within \mp\ but can be given new values by assignment \xs{sec:assignment}.
The command \ikw{newinternal} introduces new variables that behave like internal variables. This is not very useful in simple diagrams but can be useful in macro packages \xs{sec:macro}. To introduce new internal variables \kw{Jack} and \kw{Jill}, write:
\bpr
newinternal Jack, Jill;
\epr
\subsection{Declarations}\label{sec:declarations}\index{declaration}
A type name followed by a list of variable names serves to \emph{declare} the variables named in the list.\index{variable!declaration} The type names are:\index{name!of type}
\kw{boolean}, \kw{color}, \kw{numeric}, \kw{pair}, \kw{path}, \kw{pen}, \kw{picture}, \kw{string}, \kw{transform}. Each type is described in detail later \xs{sec:types}.
If a variable is used without declaration, it is assumed to be a \kw{numeric}. Occasionally, \mp\ is able to determine the type of a variable from its use, and an \idx{explicit declaration} is not required. In most cases, however, a declaration is required. In particular, a declaration is required when:
\begin{itemize}
\item The type of the variable cannot be determined from the context in which it is used.
\item A declaration can be used to ``\idx{undefine}'' the variable, that is, to change its value to ``unknown''.\index{value!unknown}
\item An \idx{array} is being declared. Following the declaration
\bex{60mm}
pair p[];
\eex
the variables $\kw{p0}, \kw{p1}, \kw{p2}, \ldots, \kw{p[i]}$, in which \kw{i} is an integer expression, are all available for use.
\item Multidimensional arrays\index{multidimensional array} can be declared with flexible syntax:
\bex{80mm}
path p[][], q[]r[];
\eex
Corresponding values would include \kw{p[1][2]}, \kw{q[i]r6}, etc.
\end{itemize}
Declarations with numeric suffixes, such as
\bex{60mm}
pair p1, p2;
\eex
are \emph{not} allowed; the general form \kw{p[]} described above must be used.
\subsection{Scope}\label{sec:scope}\index{scope}
In general, the scope of a name starts at the point of its declaration or first use and extends to the end of the source file. There are two exceptions to this rule. First, the names \kw{x}, \kw{y}, and \kw{z} play a special role to be described shortly. Second, the constructs \kw{begingroup} and \kw{endgroup} provide an environment in which local names can be declared.
\mp\ uses \emph{groups}\index{group} to provide local variables.\index{local!variable}\index{variable!local} The syntax of a group is
\bex{100mm} begingroup\idc{begingroup} \agl{seq} endgroup\idc{endgroup} \eex
in which \agl{seq} is a sequence of commands. The last item in the sequence may be an expression, in which case the value of this expression becomes the value of the group.\index{value!group}
Within a group, the command \ikw{save} \xs{sec:save} followed by a list of variable names makes those names local to the group.\index{name!local}\index{variable!local} The global values\index{value!global} of these names, if any, are saved. In the code below:
\begin{itemize}
\item \kw{a} is used both globally and locally; its global value, 1, is restored on group exit.
\item \kw{b} is defined as a local variable within the group and becomes undefined on group exit.
\item \kw{c} is defined within the group but is not declared as a local variable. Consequently, it is treated as a global variable and its value is retained on group exit.
\end{itemize}
\bex{60mm}
a = 1;
begingroup
\- save a, b;
\- a = 2;
\- b = 3;
\- c = 4;
endgroup;
show a;
show b;
show c;
\mex{40mm}
\vskip 15ex
\sh\ 1
\sh\ b
\sh\ 4
\eex
The command \ikw{interim} allows you to redefine a internal variable\index{variable!internal} inside a group without changing its global value. For example, the following statements draw an arrow \xs{sec:arrows} with an elongated head without changing the global value of \kw{ahlength}:
\bep{100mm}
begingroup;
\- interim ahlength := 15;
\- drawarrow (0,0) -- (40,40);
endgroup;
\eep{-5mm}{66}
The scope of the special names \kw{x}, \kw{y}, and \kw{z} is restricted to a particular figure. That is, the code on the left has the effect of the code on the right (of course, the \kw{beginfig}/\kw{endfig} environment also creates a figure file, etc.):
\qquad\begin{minipage}{80mm}
\bpr
beginfig($n$)
\-\agl{seq}
endfig
\epr
\end{minipage}
\hfill
\begin{minipage}{100mm}
\bpr
begingroup
\-save x, y, z;
\-\agl{seq}
endgroup
\epr
\end{minipage}
\boxedquote{Recommendation: \kw{save} all of the variables in a figure that are not needed for other figures.}
\subsection{Expressions}\label{sec:expressions}
An expression in \mp\ is a \agl{primary}\index{primary}, \agl{secondary}\index{secondary}, \agl{tertiary}\index{tertiary}, or \agl{expression}\index{expression}. A binary operator\index{operator} with highest precedence is called a \agl{primary binop} and its operands must either be \agl{primary}s or be enclosed between parentheses. Since unary operators\index{unary operator} have higher precedence than binary operators, there are four levels of \idx{precedence}. Binary operators\index{binary operator} are organized as follows, with the top line having highest priority.
$$ \renewcommand{\arraystretch}{1.3}\begin{array}{lc}
\agl{unop} & \kw{abs} \quad \kw{angle} \quad \kw{arclength} \quad \ldots \\ \hline
\agl{primary binop} & \kw{*} \quad \kw{/} \quad \kw{**} \quad \kw{and} \quad \kw{dotprod} \quad \kw{div} \quad \kw{mod} \quad \kw{infont} \\ \hline
\agl{secondary binop} & \kw{+} \quad \kw{-} \quad \kw{++} \quad \kw{+-+} \quad \kw{or} \quad \kw{intersectionpoint} \quad \kw{intersectiontimes} \\ \hline
\agl{tertiary binop} & \kw{\&} \quad \kw{<} \quad \kw{<=} \quad \kw{<>} \quad \kw{=} \quad \kw{>=} \quad \kw{>} \quad \kw{cutafter} \quad \kw{cutbefore}
\end{array} $$
However, division (\kw{/}) has highest precedence if both of its operands are numbers. This means that, for example:
\be
\kw{sqrt 2/3} & \equiv & \sqrt{2/3} \\
\kw{sqrt n/d} & \equiv & \sqrt{n}/d \\
\kw{sqrt(n/d)} & \equiv & \sqrt{n/d}
\ee
The exponent operator \ikw{**} has the same precedence as multiply (\kw{*}). Consequently:
\be \kw{3*a**2} & \equiv & (3a)^2 . \ee
The meaning of most of the operators are conventional. There are special operators for the \idx{hypotenuse}\index{sum of squares}\index{operator!sum of squares} and \idx{difference of squares}\index{operator!difference of squares}:\idc{++}\idc{+-+}
\be
\kw{a ++ b} & \equiv & \sqrt{a^2+b^2} \\
\kw{a +-+ b} & \equiv & \sqrt{a^2-b^2}
\ee
There are also many operators with names, both unary and binary. The operators that may be used with each type, and their meanings, are discussed later with the corresponding types \xs{sec:types}.
Some expressions use the keyword \ikw{of}. The general format of these expressions is
$$ \agl{of operator} \; \agl{expression} \kw{ of } \; \agl{primary} $$
where \agl{of operator} is one of:
\begin{quote}
\ikw{arctime} \quad
\ikw{direction} \quad
\ikw{directiontime} \quad
\ikw{directionpoint} \quad
\ikw{penoffset} \quad
\ikw{point} \quad
\ikw{postcontrol} \quad
\ikw{precontrol} \quad
\ikw{subpath} \quad
\ikw{substring}
\end{quote}
For example \xs{sec:string}:
\be \kw{substring (2,4) of "abcde"} & \equiv & \kw{"cd"} . \ee
\subsection{Assignment}\label{sec:assignment}
The \idx{assignment} operator\index{operator!assignment} is \kw{:=}, and it has the usual effect of giving the variable on its left side the new value obtained by evaluating its left side. Previous values of the variable are discarded.
Assignment (\ikw{:=}) should be distinguished from equality (\kw{=}), which is used in equations, as described in the next section.
\subsection{Equations}\label{sec:equations}\index{equation}
Variables may receive values either explicitly by assignment, as above, or implicitly by linear equations. Equations use the \idx{equality} comparison,\index{operator!equality} \ikw{=}. Equations may be built up from numerics \xs{sec:numeric}, pairs \xs{sec:pair}, or colors \xs{sec:color}.
\boxedquote{\mp\ must be able solve equations before drawing any pictures that use their values.}
\mp\ easily solves the equations below, obtaining $a=3,\; b=4,\; c=5$. Note that \kw{2*a} can be abbreviated to \kw{2a}, etc. The effect of the command \ikw{showdependencies} is to display the inferences that \mp\ has made from the equations at that point, as shown at the right.
\bex{100mm}
2a + 2b + c = 19;
3a-b = 5;
showdependencies;
4b-3c = 1;
\mex{100mm}
\sh\ a=-0.125c+3.625
\sh\ b=-0.375c+5.875
\eex
A value obtained by solving equations may be changed by assignment. However, the assignment changes \emph{only} the variable assigned.
\bex{40mm}
a = 2;
a = b;
a := 3;
\mex{120mm}
\% gives a the value 2
\% gives b the value 2
\% gives a the value 3 but does not change b
\eex
The symbol \ikw{whatever} introduces a new, \idx{anonymous variable}.\index{variable!anonymous} It may be used to avoid introducing variables unnecessarily. For example, we could find the intersection \kw{i} of two lines \kw{(p,q)} and \kw{(r,s)} by using the fact that \kw{a[p,q]} is a point on the line from \kw{p} to \kw{q} \xs{sec:expressions}.
\bex{60mm}
i = a[p,q];
i = b[r,s];
\eex
Since the names of the numerics \kw{a} and \kw{b} are not needed, we could write instead:
\bex{160mm}
i = whatever[p,q] = whatever[r,s];
\eex
It does not matter that the two instances of \kw{whatever} will have different values.
\section{Types}\label{sec:types}
The types provided by \mp\ are: \kw{boolean}, \kw{string}, \kw{color}, \kw{numeric}, \kw{pair}, \kw{path}, \kw{pen}, \kw{picture}, and \kw{transform}. All of them are described in this section except \kw{path}, which has its own section \xs{sec:path}.
\subsection{Booleans}\label{sec:boolean}
The values of \ikw{boolean} are \ikw{true} and \ikw{false}. The binary comparison operators\index{operator!comparison} \kw{=}, \kw{<>}, \kw{<}, \kw{<=}, \kw{=>}, and \kw{>} return \kw{boolean} values. The unary operator \ikw{not} and the binary operators \ikw{and} and \ikw{or} take \kw{boolean} operands and return the expected \kw{boolean} values. Booleans are also needed for \kw{if} statements \xs{sec:if}.
The \idx{equality} operators \kw{=} and \kw{<>} work with all types. The \idx{comparison} operators, \kw{<}, \kw{<=}, \kw{=>}, and \kw{>}, work with most types and have the expected \kw{boolean} values for reasonable types.
Type names can be used as predicates:
\be
\ikw{boolean}\; b & \defeq & \mbox{$b$ is a \kw{boolean}} \\
\ikw{color}\; c & \defeq & \mbox{$c$ is a \kw{color}} \\
\ikw{rgbcolor}\; c & \defeq & \mbox{$c$ is a \kw{rgbcolor}} \\
\ikw{cmykcolor}\; c & \defeq & \mbox{$c$ is a \kw{cmykcolor}} \\
\ikw{numeric}\; n & \defeq & \mbox{$n$ is a \kw{numeric}} \\
\ikw{pair}\; p & \defeq & \mbox{$p$ is a \kw{pair}} \\
\ikw{path}\; p & \defeq & \mbox{$p$ is a \kw{path}} \\
\ikw{pen}\; p & \defeq & \mbox{$p$ is a \kw{pen}} \\
\ikw{picture}\; p & \defeq & \mbox{$p$ is a \kw{picture}} \\
\ikw{string}\; s & \defeq & \mbox{$s$ is a \kw{string}} \\
\ikw{transform}\; t & \defeq & \mbox{$t$ is a \kw{transform}}
\ee
Other \idx{predicates} include:
\be
\ikw{odd}\; n & \defeq & \mbox{the closest integer to $n$ is odd} \\
\ikw{cycle}\; p & \defeq & \mbox{path $p$ is a cycle} \\
\ikw{known}\; x & \defeq & \mbox{$x$ has a value} \index{value!known} \\
\ikw{unknown}\; x & \defeq & \mbox{$x$ does not have a value} \index{value!unknown} \\
\ee
\subsection{Strings}\label{sec:string}\index{string}
Strings are sequences of characters bounded by double quotes (\kw{"}). Strings may not contain double quotes or line breaks. The binary comparison operators \kw{=}, \kw{<>}, \kw{<}, \kw{<=}, \kw{=>}, and \kw{>} accept \ikw{string} operands and use the underlying character codes for ordering.
Functions for strings include:
\be
\ikw{string}\; s & \defeq & \mbox{true if $s$ is a \kw{string}} \\
\ikw{length}\; s & \defeq & \mbox{the number of characters in $s$}
\ee
Constants and functions yielding strings include:\index{functions!strings}\index{constants!strings}
\be
\ikw{ditto} & \defeq & \mbox{the one-character string \kw{"}} \\
\ikw{mpversion} & \defeq & \mbox{a string giving the version of \mp} \\
\ikw{substring} \; (m,n) \; \kw{of} \; s & \defeq & \mbox{characters $m$ to $n$ of string $s$} \\
\ikw{scantokens}(s) & \defeq & \mbox{the result of parsing the token sequence $s$ \xs{sec:readfile}} \\
\ikw{char} \; n & \defeq & \mbox{a string consisting of the character with ASCII code $n$}
\index{conversion!char@\kw{char} (ASCII to \kw{string})} \\
\ikw{decimal} \; n & \defeq & \mbox{a string representing the decimal representation of the number $n$}
\index{value!decimal}\index{conversion!decimal@\kw{decimal} (\kw{numeric} to \kw{string})} \\
\ikw{str} \; s & \defeq & \mbox{the string representation of the suffix $s$}
\index{conversion!str@\kw{str} (\kw{suffix} to \kw{string})} \\
s \; \kw{\&} \; t & \defeq & \mbox{the concatenation\index{concatenation!of strings} of strings $s$ and $t$} \index{&@\kw{\&}} \\
\ee
The indexing convention for strings is the same as \textsf{C}: the first character has index 0 and the second argument of \kw{substring} indexes the first character following the selection:
\be \kw{substring (2,4) of "abcde"} & \equiv & \kw{"cd"} . \ee
The expression
\bpr $s$ \ikw{infont} $f$ \epr
yields a picture \xs{sec:picture} consisting of the string $s$ typeset in the font $f$. (\xfp{fig-latex-fonts} shows common \LaTeX\ fonts.) There is a \ikw{defaultfont} (usually \kw{cmtex10}) with a size \ikw{defaultscale} (usually 1).
\bep{100mm}
\begin{verbatim}
draw "MetaPost" infont "cmsl12" scaled 2 rotated 30;
\end{verbatim}
\eep{-10mm}{74}
Calling \kw{scantokens} invokes \mp's input routine. It can be used as a general conversion function. For example, this call gives \kw{pi} the numerical value 3.14159:
\bpr
pi := scantokens("3.14159");
\epr
\kw{scantokens} is one of the few \mp\ operations that creates a list \xs{sec:list}. See also \xs{sec:readfile} for a more interesting application of \kw{scantokens}.
\LaTeX\ code is placed in \kw{btex \ldots\ etex} \xs{sec:btex}.
\mp\ does not invoke functions in these environments, but strings containing functions can be converted to pictures with the \ikw{TEX} macro package \xs{sec:tex}.
\subsection{Colors}\label{sec:color}
A value\index{value!colour} of type \ikw{color} has three components, corresponding to the red, green, and blue components of a colour. Each component is clamped to the range $[0,1]$. Colours are written \kw{(r,g,b)}. \mp\ can solve linear equations involving colours. Two colours may be added or subtracted; a colours may be multiplied and divided by numerics; colours may be used in linear equations.
\bex{100mm}
show white/4;
show 0.2green + 0.6blue;
\mex{80mm}
\sh\ (0.25,0.25,0.25)
\sh\ (0,0.2,0.6) )
\eex
Constants and functions for colours include:\index{functions!colours}\index{constants!colours}
\be
\ikw{color} \; c & \defeq & \mbox{true if $c$ is a RGB colour} \\
\ikw{black} & \defeq & (0,0,0) \\
\ikw{white} & \defeq & (1,1,1) \\
\ikw{red} & \defeq & (1,0,0) \\
\ikw{green} & \defeq & (0,1,0) \\
\ikw{blue} & \defeq & (0,0,1) \\
\ikw{redpart} (r,g,b) & \defeq & r \\
\ikw{greenpart} (r,g,b) & \defeq & g \\
\ikw{bluepart} (r,g,b) & \defeq & b \\
\ikw{background} & \defeq & \mbox{the background colour (default = \kw{white})} \\
\ee
To change the foreground colour (i.e., the drawing colour), use \kw{drawoptions} \xs{sec:drawoptions}.
Later versions \mp\ support the CMYK colour model as well as RGB. A CMYK colour is represented as a four-tuple \kw{(c,m,y,k)} with \kw{(1,1,1,1)} representing black and \kw{(0,0,0,0)} representing white. The following constants and functions are provided:
\be
\ikw{rgbcolor} & \defeq & \mbox{a synonym for \kw{color}} \\
\ikw{cmykcolor} \; c & \defeq & \mbox{true if $c$ is a CMYK colour} \\
\ikw{cyanpart}(c,y,m,k) & \defeq & c \\
\ikw{magentapart}(c,y,m,k) & \defeq & y \\
\ikw{yellowpart}(c,y,m,k) & \defeq & m \\
\ikw{blackpart}(c,y,m,k) & \defeq & k \\
\ee
Colour expressions usually appear in \ikw{withcolor} clauses in conjunction with commands such as \ikw{draw} \xs{sec:draw}, \ikw{drawoptions} \xs{sec:drawoptions}, \ikw{fill} and \ikw{filldraw} \xs{sec:fill}. \kw{withcolor} works for both RGB and CMYK colours, but the two systems should not be mixed within a single picture.
\subsection{Numerics}\label{sec:numeric}
\mp\ uses fixed-point \idx{arithmetic} with $2^{-16}=1/65536$ as the unit for the \ikw{numeric} type. The largest number that can be represented is about 4096.
The \idx{length}s that \mp can represent range from $\unit{1/65536}{bp} \approx \unit{5.38}{nanometres}$ to $\unit{4096}{bp}\approx\unit{1.4}{metres}$. For comparison, the wavelength of blue light is about \unit{400}{nanometres} and the length of standard paper is about \unit{0.29}{metres}, depending on where you live.
The arithmetic operators \kw{+}, \kw{-}, \kw{*}, and \kw{/} can be used with numerics. The binary comparison operators \kw{=}, \kw{<>}, \kw{<}, \kw{<=}, \kw{=>}, and \kw{>} accept \kw{numeric} operands and provide the conventional ordering.
It is sometimes necessary to use a numerical expression as part of a picture. This can be done with the \ikw{TEX} package \xs{sec:tex}. For example, to \idx{label} \xs{sec:labels} the point \kw{p} with the value of the numeric \kw{i}, write:
\begin{verbatim}
label.bot(TEX(decimal(i)), p);
\end{verbatim}
Numeric constants and expressions include:\index{constants!numerics}
\be
\ikw{epsilon} & \defeq & 1/65536 \quad \mbox{(the smallest value that \mp\ can represent)}
\index{value!smallest} \\
\ikw{infinity} & \approx& 4095.99998 \quad \mbox{(the largest value that \mp\ can represent)}
\index{value!largest} \\
\ikw{day} & \defeq & \mbox{current day (of the month)} \\
\ikw{month} & \defeq & \mbox{current month} \\
\ikw{year} & \defeq & \mbox{current year} \\
\ikw{time} & \defeq & \mbox{job start time (minutes since midnight)}
\ee
Numeric functions include:\index{functions!numerics}
\be
\ikw{decimal}\; n & \defeq & \mbox{the decimal string corresponding to $n$} \\
\ikw{numeric}\; n & \defeq & \mbox{\kw{true} if $n$ is numeric} \\
\ikw{odd}\; n & \defeq & \mbox{true if the closest integer to $n$ is odd} \\
\kw{m div n}\idc{div} & \defeq & \lfloor m/n \rfloor \qquad\mbox{(integer division)}
\index{division} \\
\kw{m mod n}\idc{mod} & \defeq & m - n \lfloor m/n \rfloor \qquad\mbox{(integer remainder)}
\index{remainder} \\[2ex]
\ikw{abs}\, x & \defeq & |x|, \mbox{the absolute value of $x$} \\
\ikw{sqrt} \; x & \defeq & \sqrt{x} \\
\ikw{sind} \; x & \defeq & \sin x \quad (\mbox{$x$ in degrees}) \\
\ikw{cosd} \; x & \defeq & \cos x \quad (\mbox{$x$ in degrees}) \\
\ikw{mexp} \; x & \defeq & e^{x/256} \\
\ikw{mlog} \; x & \defeq & 256 \ln x \\
\ikw{floor} \; x & \defeq & \mbox{the greatest integer less than or equal to $x$}
\index{conversion!floor@\kw{floor} (\kw{numeric} to integer)} \\
\ikw{ceiling} \; x & \defeq & \mbox{the least integer greater than or equal to $x$}
\index{conversion!ceiling@\kw{ceiling} (\kw{numeric} to integer)}\\
\ikw{round} \; x & \defeq & \mbox{the integer closest to $x$}
\index{conversion!round@\kw{round} (\kw{numeric} to integer)}\\
\kw{x} \ikw{++} \kw{y} & \defeq & \sqrt{x^2+y^2} \index{sum of squares} \\
\kw{x} \ikw{+-+} \kw{y} & \defeq & \sqrt{x^2-y^2} \index{difference of squares} \\
\ikw{uniformdeviate} \; x & \defeq & \mbox{a random number uniformly distributed in $[0,x]$}
\index{random number}\index{uniform random number} \\
\ikw{normaldeviate} & \defeq & \mbox{a random number with normal distribution, $\mu=0$, $\sigma=1$}
\index{normal!random number}
\ee
\subsection{Pairs}\label{sec:pair}
A \ikw{pair} is a tuple of two \kw{numeric}s that is most often used to represent a position in the two-dimensional plane of the picture but can also be used to represent a direction. Literal pairs are written as \kw{(m,n)} in which \kw{m} and \kw{n} are \kw{numeric}s.
Pairs can be added and subtracted (like vectors), multiplied or divided by \kw{numeric}s, and used in linear equations. \emph{Mediation}\index{mediation} abbreviates a common operation:
\be \kw{r[p,q]} & \defeq & \kw{p} + \kw{r} * (\kw{q} - \kw{p}) . \ee
If $0 \le \kw{r} \le 1$, the result is a point between the points \kw{p} and \kw{q}, with $\kw{r}=0$ corresponding to \kw{p} and $\kw{r}=1$ corresponding to \kw{q}. All values of \kw{r} are legal:
\bep{100mm}
\begin{verbatim}
z1 = (0,0);
z2 = (0,50);
draw z1 -- z2;
dotlabel.rt(btex $4 \over 3$ etex, 4/3[z1,z2]);
dotlabel.rt(btex $2 \over 3$ etex, 2/3[z1,z2]);
dotlabel.rt(btex $1 \over 3$ etex, 1/3[z1,z2]);
\end{verbatim}
\eep{-10mm}{23}
As mentioned previously, the names \ikw{x}, \ikw{y}, and \ikw{z} play a special role:
\begin{itemize}
\item They are undefined by \ikw{beginfig} \xs{sec:input}.
\item \kw{z\agl{suffix}} is defined to be equal to \kw{(x\agl{suffix},\,y\agl{suffix})}, where \agl{suffix} is a number, index, or name \xs{sec:variables}. Thus \kw{z[3].t} can be abbreviated to \kw{z3t} and is equivalent to the pair \kw{(x3t,y3t)}.
\end{itemize}
The \kw{pair} \kw{(x,y)} can be used to represent the direction\index{direction!represented by pair} $\theta=\tan^{-1}(\kw{y}/\kw{x})$. Angles\index{angle} in \mp\ are measured in degrees. For example, $\kw{dir 90}\equiv\kw{pair(0,1)}$.
\bep{120mm}
smallRad = 30;
bigRad = 40;
for angle = 0 step 30 until 330:
\- s := sind angle;
\- c := cosd angle;
\- drawarrow origin -- (smallRad*c, smallRad*s);
\- label(decimal angle, (bigRad*c, bigRad*s));
endfor;
\eep{-10mm}{13}
The difference between two points can be used directly as the direction of the line joining them. In the example below, the arrows are \idx{tangent} to the curve at its endpoints.
\bep{120mm}
drawarrow z0 -- z1;
draw \verb'z1{z1-z0} .. {z3-z2}z2';
drawarrow z2 -- z3;
\eep{0mm}{92}
Constant pairs include:\index{constants!pairs}
$$ \begin{array}{lcll}
\ikw{origin} & \defeq & (0,0) \\
\ikw{up} & \defeq & \kw{(0,1)} \\
\ikw{down} & \defeq & \kw{(0,-1)} \\
\ikw{left} & \defeq & \kw{(-1,0)} \\
\ikw{right} & \defeq & \kw{(1,0)}
\end{array} $$
Functions for pairs include:\index{functions!pairs}
$$ \begin{array}{lcll}
\ikw{xpart}(x,y) & \defeq & x \\
\ikw{ypart}(x,y) & \defeq & y \\[2ex]
\ikw{abs} \; z & \defeq & \sqrt{\rule{0pt}{10pt} x^2+y^2} & \mbox{(\idx{hypotenuse})}
\index{conversion!abs@\kw{abs} (\kw{pair} to \kw{numeric})}\\
\ikw{unitvector} \; z & \defeq & z / \kw{abs} \; z & \mbox{(\idx{normalize})} \\
\ikw{angle} \; z & \defeq & \tan^{-1}(y/x) & \mbox{(in degrees)}
\index{conversion!angle@\kw{angle} (\kw{pair} to \kw{numeric})} \\
\ikw{round} \; z & \defeq & \kw{(round $x$, round $y$)} \\
z_1 \; \ikw{dotprod} \; z_2 & \defeq & x_1y_1 + x_2y_2 & \mbox{(\idx{inner product})} \\
r\kw{[} z_1,z_2 \kw{]} & \defeq & z_1 + r(z_2-z_1) & \mbox{(\idx{mediation})}\idc{[]} \\
\ikw{dir} \; \theta & \defeq & (\kw{cosd}\,\theta,\, \kw{sind}\,\theta) & \mbox{(\idx{direction})}
\index{conversion!dir@\kw{dir} (\kw{numeric} to \kw{pair})}
\end{array} $$
The function \ikw{dir} can be used to position points:
\bep{60mm}
z0 = origin;
z1 = z0 + 40 dir 30;
z2 = z1 + 20 dir 120;
dotlabels.top(0,1,2);
\eep{-10mm}{91}
\subsection{Pens}\label{sec:pen}
All objects are drawn with a \idx{pen}. The command
\bex{80mm} \ikw{pickup} \agl{pen expression} \eex
selects a pen with characteristics defined by \agl{pen expression} with syntax
$$
\left.
\begin{array}{c} \ikw{pencircle} \\
\ikw{pensquare}
\end{array}
\right\} \; \agl{transform}
$$
where \agl{transform} is an affine transformation \xs{sec:transform}. Naturally, \kw{pencircle} gives a round \idx{nib} and \kw{pensquare} gives a square nib. The operator \kw{pensquare} is actually a macro defined by
\be\kw{pensquare} & \defeq & \kw{makepen((-0.5,-0.5)--(0.5,-0.5)--(0.5,0.5)--(-0.5,0.5)--cycle)} \ee
and, in general, \ikw{makepen} will construct a pen nib from any closed path \xs{sec:path}. The operator \ikw{makepath} is the inverse of \ikw{makepen}: if $p$ is a pen, then $\kw{makepath }p$ is the polygon that it uses as a nib. Thus:
\be \kw{makepath pencircle} & \equiv & \kw{fullcircle} . \ee
It is best to use a round nib (\kw{pencircle}) when drawing dotted and dashed lines \xs{sec:dashes}; square or polygonal pens may yield strange results.
The constant \ikw{nullpen} is a pen with no useful properties. A function that is supposed to return a \kw{pen} but cannot do so should return \kw{nullpen}.
The default pen is quite thin:
\be \ikw{defaultpen} & \defeq & \kw{pencircle scaled 0.5 bp} . \ee
Thick pens are defined by simple scaling:
\bex{80mm}
pencircle scaled 5pt
\eex
Transforms \ikw{xscaled} and \ikw{yscaled} provide elliptical or rectangular nibs:
\bep{120mm}
path p;
drawoptions(withpen pencircle
\- xscaled 2bp yscaled 0.1bp);
p = (0,0) for i = 1 upto 100:
\- .. (0.6i*cosd(36i),0.6i*sind(36i)) endfor;
draw p;
drawoptions();
\eep{-15mm}{68}
The shape\index{line!end} of the end of each line is determined by the internal variable \ikw{linecap}. When lines change direction, the shape of the corner\index{line!corner} is determined by \ikw{linejoin}. \xf{fig:pens} illustrates both.
\begin{minipage}{0.4\textwidth}
\be \kw{linecap} & \kw{:=} &
\left\{
\begin{array}{l}
\ikw{rounded} \qquad \mbox{(default)} \\ \ikw{squared} \\ \ikw{butt}
\end{array}
\right.
\ee
\end{minipage}
\hfill
\begin{minipage}{0.4\textwidth}
\be \kw{linejoin} & \kw{:=} &
\left\{
\begin{array}{l}
\ikw{rounded} \qquad \mbox{(default)} \\ \ikw{beveled} \\ \ikw{mitered}
\end{array}
\right.
\ee
\end{minipage}
\begin{figure}[btp]
\hrule\vskip6pt
\begin{center}
\begin{tabular}{lccc}
\qquad \kw{linecap} $\rightarrow$ & \kw{rounded} & \kw{squared} & \kw{butt} \\
$\begin{array}{c}\kw{linejoin} \\ \downarrow \end{array} $ & \\ \hline
\rule{0pt}{36pt} \kw{rounded} & \fg{56} & \fg{59} & \fg{62} \\
\rule{0pt}{30pt} \kw{beveled} & \fg{57} & \fg{60} & \fg{63} \\
\rule{0pt}{30pt} \kw{mitered} & \fg{58} & \fg{61} & \fg{64} \\
\end{tabular}
\end{center}
\caption[The effect of \kw{linecap} and \kw{linejoin}]{The effect of \kw{linecap} and \kw{linejoin}, drawn \kw{withpen pensquare scaled 8}}
\label{fig:pens}
\vskip4pt\hrule
\end{figure}
A long spike may be produced when \ikw{mitered} lines meet at an acute angle. \mp\ changes the join shape to \ikw{beveled} if
$$ \frac{\mbox{miter length}}{\mbox{line width}} > \ikw{miterlimit} . $$
The default value of the internal variable \kw{miterlimit} is 10.0; it can be changed by assignment.
For a sequence of \kw{draw} \xs{sec:draw} and \kw{fill} \xs{sec:fill} commands with a particular kind of pen, use
\bpr \ikw{drawoptions} ( \agl{text} ) \epr
to set the pen characteristics and
\bpr \kw{drawoptions} ( ) \epr
to restore the defaults. The argument \agl{text} can specify \kw{dashed} \xs{sec:dashes}, \kw{withcolor} \xs{sec:color}, and \ikw{withpen} \xs{sec:pen} values.
\bep{130mm}
drawoptions(
\- withcolor 0.8 green
\- withpen pensquare scaled 4 );
d = 10;
draw unitsquare scaled 2d shifted (-d,-d);
draw fullcircle scaled 4d;
drawoptions();
\eep{0mm}{26}
\subsection{Transforms}\label{sec:transform}\index{transform}\index{affine transform}
A variety of affine transformations can be applied to pictures. These are transform expressions (all angles are measured in in degrees):
$$ \begin{array}{rcccl}
(x,y) & \ikw{rotated} & \theta & \defeq & (x\cos\theta - y\sin\theta, x\sin\theta + y\cos\theta) \\
(x,y) & \ikw{slanted} & a & \defeq & (x+ay, y)\\
(x,y) & \ikw{scaled} & a & \defeq & (ax, ay) \\
(x,y) & \ikw{xscaled} & a & \defeq & (ax, y) \\
(x,y) & \ikw{yscaled} & a & \defeq & (x, ay) \\
(x,y) & \ikw{shifted} & (a,b) & \defeq & (x+a, y+b) \\
(x,y) & \ikw{zscaled} & (a,b) & \defeq & (ax - by, bx + ay) \\
(x,y) & \ikw{reflectedabout} & (p,q) & \defeq & \mbox{The reflection of $(x,y)$ in the line $(p,q)$.} \\
(x,y) & \ikw{rotatedaround} & (p,\theta) & \defeq & \mbox{$(x,y)$ rotated about point $p$ through angle $\theta$.} \\
\end{array} $$
Transforms are applied by writing a transform expression after a picture expression. Transform expressions can be combined by concatenating them.
\bep{100mm}
dotlabel.bot(btex $(0,0)$ etex, origin);
path bx;
bx = unitsquare scaled 10;
draw bx shifted (0,36);
draw bx xscaled 1.6 shifted (0,24);
draw bx slanted 0.5 shifted (0,12);
draw bx rotated 30;
\eep{-10mm}{8}
Here are some operators associated with transforms:
$$ \begin{array}{rcl}
\ikw{transform} \; t; & \defeq & \mbox{declares $t$ to be a transform} \\
\ikw{transform} \; t & \defeq & \mbox{used in an expression, returns \kw{true} if $t$ is a transform} \\
\ikw{identity} & \defeq & \mbox{the identity transform: } p \; \ikw{transformed} \; \ikw{identity} \equiv p \\
\ikw{inverse} \; t & \defeq & \mbox{the inverse of transform } t \\
p \; \ikw{transformed} \; t & \defeq & \mbox{picture $p$ transformed by transform $t$}
\end{array} $$
The following example defines and applies a transform called \kw{reflect}.
\bep{120mm}
transform reflect;
reflect = identity xscaled -1;
draw btex Mirror, mirror, on the wall etex
\- transformed reflect;
\eep{5mm}{27}
A transform has six parameters. The mapping from $(x,y)$ to $(x',y')$ is given, in homogeneous coordinates, by
\be
\left[ \begin{array}{c} x' \\ y' \\ 1 \end{array} \right] & = &
\left[ \begin{array}{ccc}
t_{xx} & t_{xy} & t_{x} \\
t_{yx} & t_{yy} & t_{y} \\
0 & 0 & 1 \end{array} \right]
\left[ \begin{array}{c} x \\ y \\ 1 \end{array} \right]
\ee
The values of the parameters for a transform $t$ are referred to in \mp\ as
$$ \begin{array}{rcl @{\hskip 4em} rcl}
t_{x} & = & \ikw{xpart} \; t & t_{y} & = & \ikw{ypart} \; t \\
t_{xx} & = & \ikw{xxpart} \; t & t_{yx} & = & \ikw{yxpart} \; t \\
t_{xy} & = & \ikw{xypart} \; t & t_{yy} & = & \ikw{yypart} \; t \end{array}
$$
Transforms may be defined by equations. Each equation says that a point $p$ is mapped to a point $p'$ and determines two of the transform parameters; consequently, three equations are needed. In the following example, the transform \kw{t} is defined by its effect on three points.
\bep{100mm}
z1 = (-20,0); z2 = (-40,15);
z3 = (0,20); z4 = (0,30);
z5 = (20,0); z6 = (35,-20);
draw fullcircle scaled 40;
drawarrow z1--z2;
drawarrow z3--z4;
drawarrow z5--z6;
transform t;
z1 transformed t = z2;
z3 transformed t = z4;
z5 transformed t = z6;
draw fullcircle scaled 40 transformed t;
\eep{-10mm}{28}
The parameters themselves can be used to define the transformation. For example, the equations
\bpr
xxpart t = yypart t;
xypart t = -yxpart t;
\epr
specify that transform \kw{t} preserves shapes. Two additional equations, defining the effect of \kw{t} on two points, are required to define \kw{t} completely.
The following example combines several features of \mp: the command \ikw{direction} \xs{sec:param} gives the direction of the \idx{tangent} vector at a point on the curve; the command \ikw{angle} \xs{sec:numeric} converts this direction to an angle $\theta$; rotating by $\theta+90\dg$ gives a direction \idx{normal} to the curve; and the command \ikw{point} \xs{sec:param} gives the position of a point on the curve.
\bep{100mm}
path p;
p := fullcircle xscaled 100 yscaled 40;
draw p;
for i = 0 upto 40:
\- t := i/5;
\- draw ((0,0)--(3,0))
\-\- rotated (angle direction t of p - 90)
\-\- shifted (point t of p);
endfor;
\eep{0mm}{47}
\subsection{Pictures}\label{sec:picture}
Anything that can be drawn by \mp\ can be stored in a \idx{picture} variable. Several primitives, including \kw{draw} \xs{sec:path}, store their results in the internal variable \ikw{currentpicture}. Pictures can be transformed \xs{sec:transform}.
The following expressions yield a picture:
\be
s \; \kw{infont} \; f &:& \mbox{string $s$ set in font $f$ \xs{sec:string}} \\
\kw{btex \ldots\ etex} &:& \mbox{raw \TeX\ strings \xs{sec:btex}} \\
\kw{TEX( \ldots\ )} &:& \mbox{processed \TeX\ strings} \xs{sec:tex} \\
\ikw{nullpicture} &:& \mbox{an empty picture} \\
\ikw{currentpicture} &:& \mbox{the ``current'' picture, destination of \kw{draw}, etc.} \\
\ee
These operators return a value associated with a picture $p$:\index{functions!pictures}
\be
\ikw{center} \; p & \defeq & \mbox{the centre of $p$.} \\
\ikw{length} \; p & \defeq & \mbox{the number of components of $p$.} \\
\ikw{llcorner} \; p & \defeq & \mbox{the lower left corner of $p$.} \\
\ikw{lrcorner} \; p & \defeq & \mbox{the lower right corner of $p$.} \\
\ikw{ulcorner} \; p & \defeq & \mbox{the upper left corner of $p$.} \\
\ikw{urcorner} \; p & \defeq & \mbox{the upper right corner of $p$.}
\ee
After defining the picture \kw{p} with the commands
\begin{verbatim}
picture p;
p = btex $\displaystyle\int_0^\infty e^{-x} \, \sin x \, dx $ etex;
\end{verbatim}
we can draw the picture and its corner points:
\bep{120mm}
draw p;
dotlabel.ulft("UL", ulcorner p);
dotlabel.urt ("UR", urcorner p);
dotlabel.llft("LL", llcorner p);
dotlabel.lrt ("LR", lrcorner p);
\eep{-5mm}{2}
The operators \kw{llcorner}, \kw{lrcorner}, \kw{ulcorner}, and \kw{urcorner} define the \emph{\idx{bounding box}} of a picture. They can be used to measure the size of a box.\index{size!of box} Following on from the above example,
\bpr
pair dim;
dim := (urcorner p) - (llcorner p);
width := xpart dim;
height = ypart dim;
\epr
gives $\kw{width}=71.3919$ and $\mbox{height}=23.1722$.
If the bounding box is not what you want, you can change it. The command
\bpr \ikw{setbounds} $v$ to $p$ \epr
makes the picture variable $v$ behave as if its bounding box is the path $p$.
\bep{150mm}
picture p;
p = btex \verb'$\displaystyle\sum_{n=1}^{\infty} {1 \over n}$' etex;
path q;
q = bbox p shifted (20,20);
setbounds p to q;
draw p;
draw q;
\eep{0mm}{67}
Recent versions of \mp\ include a macro \ikw{image} that can be used in places that would otherwise require \kw{currentpicture}. The expression
\bpr image( \agl{seq} ) \epr
yields the \kw{picture} object constructed by the sequence \agl{seq} of drawing commands.
\bep{150mm}
picture smiley;
smiley := image(
\- draw fullcircle scaled 40;
\- draw halfcircle scaled 20 rotated 180;
\- filldraw fullcircle scaled 3 shifted (-10,10);
\- filldraw fullcircle scaled 3 shifted (10,10);
);
draw smiley;
\eep{0mm}{70}
The following predicates can be applied to any object, but are most meaningful for parts of a picture. A ``stroked picture component'' is a part of a picture that was drawn by moving a pen (as opposed to setting text, etc.). These predicates can be used to analyze the structure of a picture \xs{sec:for}.
\be
\ikw{bounded}\; x &\defeq& \mbox{$x$ is a picture with a bounding box}\\
\ikw{clipped}\; x &\defeq& \mbox{$x$ is a picture that has been clipped}\\
\ikw{dashpart}\; x &\defeq& \mbox{$x$ is the dash pattern of a path in a stroked picture}\\
\ikw{filled}\; x &\defeq& \mbox{$x$ is a filled outline}\\
\ikw{pathpart}\; x &\defeq& \mbox{$x$ is the path of a stroked picture component}\\
\ikw{penpart}\; x &\defeq& \mbox{$x$ is the pen of a stroked picture component}\\
\ikw{stroked}\; x &\defeq& \mbox{$x$ is a stroked line}\\
\ikw{textual}\; x &\defeq& \mbox{$x$ is typeset text}
\ee
\subsection{Lists}\label{sec:list}\index{list}
Lists have a rather ghostly existence in \mp: there is no type \emph{list}, but there are a few constructions that create and consume lists.
The function \ikw{scantokens} converts a string to a list of tokens. The expression $x \kw{ step } d \kw{ until } y$ generates the list $x,\,x+d,\,x+2d,\ldots$, stopping when $x+nd\ge y$.\index{step@\kw{step}}\index{until@\kw{until}} For the common case $d=1$, there are macros \ikw{upto} and \ikw{downto}:
\be
\kw{upto} & \defeq & \kw{step 1 until} \\
\mbox{and} \qquad \kw{downto} & \defeq & \kw{step -1 until}
\ee
The \ikw{for} statement \xs{sec:for} has a form
\bpr for \agl{var} = \agl{list}: \agl{seq} endfor \epr
which assigns the variable \agl{var} to each item in \agl{list}. The list can be an actual list of tokens separated by commas, as in
\bpr for i = 1, 2, 4, 8, 16: ... endfor \epr
or a list generated by \kw{scantokens}, as in
\bpr for i = scantokens("1, 2, 4, 8, 16"): ... endfor \epr
\section{Paths}\label{sec:path}
\emph{Paths} are piecewise straight lines, curves, and any combination of these. Path variables of type \ikw{path} may be declared and there are various kinds of \emph{path expressions}. The following examples use the command \kw{draw} \xs{sec:draw} to draw paths.
\subsection{Straight lines}\label{sec:lines}\index{path!straight}\index{line!straight}
The binary infix operator `\ds'\index{--@\ds} constructs a straight line between its point operands.\index{operator!path}
\bep{80mm}
draw
\- (0,0) -- (20,0) -- (20,20) --
\- (40,20) -- (40,0) -- (60,0);
\eep{0mm}{93}
If the last point is the internal name \ikw{cycle}, the last line segment returns to the starting point. The keyword \kw{cycle} can also be used as a predicate:
\be \kw{cycle} \; p & \defeq & \mbox{true if path $p$ is a cycle} \ee
The expression \verb"p & q"\index{&@\kw{\&}} yields the concatenation\index{concatenation!of paths} of the paths \kw{p} and \kw{q}, provided that the last point of \kw{p} is identical to the first point of \kw{q}.
\subsection{Dots and Dashes}\label{sec:dashes}\index{path!dots and dashes}
The general syntax for a \idx{dashed line}\index{dotted line} is:
\idc{dashed}\bex{80mm} draw \agl{path} dashed \agl{pattern} \eex
The basic patterns are:
\be
\ikw{evenly} & : & \mbox{evenly-spaced dashes, \unit{3}{bp} long,} \\
\mbox{and} \qquad \ikw{withdots} & : & \mbox{dots \unit{5}{bp} apart.}
\ee
Patterns may be transformed \xs{sec:transform}:
\be
\ikw{shifted} \; \agl{pair} & : & \mbox{each dash is displaced by \agl{pair},} \\
\mbox{and} \qquad \ikw{scaled} \; \agl{numeric} & : & \mbox{each dash is scaled by \agl{numeric}.}
\ee
\bep{120mm}
\idc{withdots}draw (0,30)--(120,30) dashed withdots;
\idc{evenly}draw (0,20)--(120,20) dashed evenly;
draw (0,10)--(120,10) dashed evenly shifted (3,3);
draw (0, 0)--(120, 0) dashed evenly scaled 1.5;
\eep{-5mm}{3}
Dashed and dotted lines are best drawn using a pen with a circular nib \xs{sec:pen}.
\subsection{Circles, Disks, and Arcs}\label{sec:circle}\index{path!circle}
The command \ikw{fullcircle} draws a \idx{circle} with unit diameter at the origin. Apply transformations \xs{sec:transform} to the circle to modify the size and position.\index{size!of circle} The command \ikw{halfcircle} is similar to \kw{fullcircle} but draws only the part of the circle\index{semicircle} above the $X$ axis. The command \ikw{quartercircle} draws only the first quadrant of the circle.
\bep{140mm}
draw fullcircle scaled 50;
draw halfcircle scaled 40;
draw quartercircle scaled 30;
filldraw fullcircle scaled 20 withcolor 0.3white;
\eep{-10mm}{14}
General \idx{arc}s can be drawn using the \ikw{subpath} command \xs{sec:param}. The path length of a full circle is 8, and so one unit corresponds to $45\dg$. Thus the arcs in the picture below have lengths of $135\dg$, $225\dg$, and $315\dg$.
\bep{140mm}
draw subpath (0, 3) of fullcircle scaled 20;
draw subpath (0, 5) of fullcircle scaled 30;
draw subpath (0, 7) of fullcircle scaled 40;
\eep{-5mm}{38}
Curved arrows can be drawn in the same way. The normal direction of an arc is counterclockwise, but you can use \ikw{reverse} \xs{sec:param} to get a clockwise arc.
\bep{140mm}
drawarrow subpath (0, 4) of fullcircle scaled 20;
drawarrow reverse (subpath (2, 6) of fullcircle scaled 40);
\eep{-10mm}{81}
\subsection{Curves}\label{sec:curves}\index{curve}
The binary operator `\dd'\index{..@\dd} is used like `\ds', but it draws cubic B\'ezier \idx{curve} instead of straight lines.\index{operator!path} The command
\bep{80mm}
draw
\- (0,0) ..\ (20,0) ..\ (20,20) ..
\- (40,20) ..\ (40,0) ..\ (60,0);
\eep{0mm}{94}
The binary operator `\ddd\index{...@\ddd}' is similar to `\dd' but tries to avoid \idx{inflection points}. The difference between `\dd' and `\ddd' is generally small, but can be seen in the following example, in which the lower curve uses `\ddd'.
\bep{120mm}
\verb'z0 = (0,0); z1 = (50,25); z2 = (150,50);'
\verb'draw z0{dir -20} .. z1 .. {dir 30}z2;'
\verb'draw (z0{dir -20} ... z1 ... {dir 30}z2) shifted (0,-10);'
\eep{-10mm}{53}
The binary operator `\dss\index{---@\dss}' is similar to `\ds' but ensures a smooth transition between straight and curved sections of a path, as illustrated in the two examples below.
\bep{100mm}
draw (0,0) -- (25,0) ..\ (50,25);
\eep{0mm}{51}
\bep{100mm}
draw (0,0) --- (25,0) ..\ (50,25);
\eep{0mm}{52}
The direction\index{direction!of curve} of the curve may be specified at a point by a qualifier \verb"{p}", in which \kw{p} is a pair representing a direction \xs{sec:pair}. The qualifier may be placed either before or after the point.
\bep{120mm}
for i = 0 step 30 until 120:
\- draw (0,0)\{dir i\}\dd(100,0);
endfor;
\eep{-15mm}{12}
The curvature of the curve can be specified at its end points using \ikw{curl}. The argument of \kw{curl} can have any positive value; smaller values give smaller curvature.
\bep{130mm}
draw (0,0)\{curl 1\} ..\ (50,30) ..\ \{curl 1\}(100,0);
draw (0,0)\{curl 5\} ..\ (50,-30) ..\ \{curl 5\}(100,0);
\eep{-10mm}{44}
The \ikw{tension} of a curve may be changed between any pair of points. The minimum value of \kw{tension} is $\frac{3}{4}$; the default value is 1; higher values give straighter curves.
\bep{130mm}
for i = 1 upto 5:
\- draw (0,0)\{dir 90\} ..\ tension i ..\ \{dir 270\}(100,0);
endfor;
\eep{-10mm}{43}
Control points\index{control points}\index{point!control} are points that are not on the curve but which ``attract'' the curve. They can be specified between points with syntax ``\kw{controls $p$ and $q$}'', where $p$ and $q$ are points.
\bep{120mm}
z1 = (10,25);
z2 = (90,25);
dotlabel("", z1);
dotlabel("", z2);
draw (0,0) ..\ controls z1 and z2 ..\ (100,0);
\eep{-10mm}{24}
\subsection{Parametric Paths}\label{sec:param}
A path may be considered as a set of points $\{ (X(t), Y(t) \}$, where $t$ is the path \emph{parameter}.\index{path!parametric} Given a value of $t$, we can find the corresponding point $(X(t),Y(t))$ on the path and the direction of the path. Conversely, given a point or a direction on the path, we can find the value of $t$. We can use $t$ to find where curves intersect and to extract parts of curves.
\mpfig{hbtp}{50}{Parametric curves}{fig:param}
We illustrate concepts related to parametric curves using \xf{fig:param}. First we define four key points and draw the path, \kw{a}, through them.
\bex{100mm}
z1 = (0,0);
z2 = (75,75);
z3 = (150,0);
z4 = (225,75);
path a;
a = z1 .. z2 .. z3 .. z4;
draw a;
\eex
The path has a \emph{length} associated with it:
\bex{100mm}
show length a;
\mex{100mm}
\sh\ 3
\eex
It is convenient to think of the path being drawn by a point which moves along it, starting at time 0 and ending at time 3. The ``times'' of the control points are: 0 for \kw{z1}; 1 for \kw{z2}; 2 for \kw{z3}; and 3 for \kw{z2}. The expression ``$\kw{point} \; t \; \kw{of} \; p$'' gives the point on path $p$ corresponding to the time $t$ (note the position of \kw{z5} in the diagram):
\bex{100mm}
z5 = point 2.5 of a;
\eex
We can find the direction of the path, expressed as a tangent vector, at any time.
\bex{100mm}
show direction 0 of a;
\mex{100mm}
\sh\ (-19.5705,47.24738)
\eex
If we prefer, we can work with the arclength instead of the time:
\bex{100mm}
lena = arclength a;
show lena;
t1 = arctime lena/5 of a;
show t1;
z6 = point t1 of a;
\mex{100mm}
\sh\ 378.67822
\-
\sh\ 0.56165
\eex
The expression \kw{ subpath $(t_1,t_2)$ of $p$ } returns the part of the path $p$ between times $t_1$ and $t_2$. The effect of
\bex{100mm}
draw subpath (0,t1) of a shifted (-10,0);
\eex
can be seen in \xf{fig:param} as the short arc on the left of the curve \kw{a}.
We can find the time on a path when the direction first achieves a particular value:
\bex{100mm}
t2 = directiontime (1,-1) of a;
z7 = point t2 of a;
show t2;
\mex{100mm}
\sh\ 1.21132
\eex
The straight line in \xf{fig:param} is drawn as path \kw{b} with the commands:
\bex{100mm}
z8 = (25,0);
z9 = (200,75);
path b;
b = z8 -- z9;
draw b;
\eex
The point of \idx{intersection} of paths \kw{a} and \kw{b} is given by:
\bex{100mm}
z10 = a intersectionpoint b;
\eex
and the command
\bex{100mm}
show a intersectiontimes b;
\mex{100mm}
\sh\ (1.5,0.5)
\eex
shows that the intersection occurs at time 1.5 for path \kw{a} and at time 0.5 for path \kw{b}. If the paths \kw{a} and \kw{b} do not intersect, the result is \kw{(-1,-1)}.
The expression
\bex{120mm}
a cutbefore b
\eex
yields the part of path \kw{a} from \kw{z1} to \kw{z10} and the expression
\bex{120mm}
a cutafter b
\eex
yields the part of path \kw{a} from \kw{z10} to \kw{z4}.
A circle drawn by \mp\ has eight control points \xs{sec:circle}:
\bep{120mm}
\begin{verbatim}
diam =100;
rad = 0.5*diam+8;
path circ;
circ = fullcircle scaled diam;
draw circ;
for i = 0 upto 7:
dotlabel("", point i of circ);
ang := 45 * i;
label(decimal i, (rad*cosd(ang), rad*sind(ang)));
endfor;
\end{verbatim}
\eep{-20mm}{77}
Summary of path expressions:\index{path!expression}\index{expression!path}
\be
\mbox{Path expressions yielding \kw{boolean}:} \\
\ikw{path} \; p &\defeq& \mbox{$p$ is a path} \\
\ikw{cycle} \; p &\defeq& \mbox{$p$ is a cycle (closed path)} \\[2ex]
\mbox{Path expressions yielding \kw{numeric}s:} \\
\ikw{length} \; a &\defeq& \mbox{the value of $t$ at the end of $a$} \\
\ikw{arctime} \; \ell \kw{ of } a &\defeq& \mbox{the value of $t$ at which the length of $a$ is $\ell$} \\
\ikw{directiontime} \; d \kw{ of } a &\defeq& \mbox{the value of $t$ at which $a$ first has the direction $d$} \\
\ikw{arclength} \; a &\defeq& \mbox{the total arc length of $a$} \\[2ex]
\mbox{Path expressions yielding \kw{pair}s:~~~~~} \\
\ikw{point} \; t \kw{ of } a &\defeq& \mbox{the position of $a$ at time $t$} \\
\ikw{direction} \; t \kw{ of } a &\defeq& \mbox{the direction of $a$ at time $t$} \\
\ikw{directionpoint} \; d \kw{ of } a &\defeq& \mbox{the first point at which the direction of $a$ is $d$} \\
a \; \ikw{intersectionpoint} \; b &\defeq& \mbox{the point at which $a$ intersects $b$} \\
a \; \ikw{intersectiontimes} \; b &\defeq& \mbox{the pair $(t_a,t_b)$ of intersection times} \\[2ex]
\mbox{Path expressions yielding \kw{path}s:~~~~~} \\
\ikw{fullcircle} &\defeq& \mbox{the unit circle (origin at centre)} \\
\ikw{unitsquare} &\defeq& \mbox{the unit square (size $1 \times 1$, origin at lower left corner)} \\
\ikw{bbox}\; a &\defeq& \mbox{the bounding box of path $a$} \\
\ikw{reverse} \; a &\defeq& \mbox{the path $a$ drawn backwards} \\
\ikw{subpath} \; (t_1,t_2) \kw{ of } a &\defeq& \mbox{the part of $a$ for which $t_1 \le t \le t_2$} \\[2ex]
a \; \kw{\&} \; b &\defeq& \mbox{the concatenation of paths $a$ and $b$} \index{&@\kw{\&}} \\
a \; \ikw{cutbefore} \; b &\defeq& \mbox{the part of $a$ before its intersection with $b$} \\
a \; \ikw{cutafter} \; b &\defeq& \mbox{the part of $a$ after its intersection with $b$} \\
\ee
\subsection{Path Constructors}
The following functions and macros construct paths:
\be
\ikw{reverse} \; p & \defeq & \mbox{the path $p$ with its direction reversed} \\
\ikw{unitsquare} & \defeq & \kw{(0,0) \ds\ (1,0) \ds\ (1,1) \ds\ (0,1) \ds\ cycle} \\
\ikw{bbox} \; p & \defeq & \kw{llcorner $p$ \ds\ lrcorner $p$ \ds\ urcorner $p$ \ds\ ulcorner $p$ \ds\ cycle}
\ee
The effect of \kw{reverse} is defined by
\be \kw{point} \; t \; \kw{of reverse} \; p & \equiv & \kw{point} \; ( \kw{length} \; p - t ) \; \kw{of} \; p \ee
The \kw{unitsquare} can be transformed \xs{sec:transform} to produce an arbitrary parallelogram.
The macro \kw{bbox}, applied to a picture $p$, returns the bounding box of $p$.
\bep{120mm}
\begin{verbatim}
picture p;
p = btex $\spadesuit \heartsuit \diamondsuit \clubsuit$ etex;
draw p;
draw bbox p;
\end{verbatim}
\eep{0mm}{19}
The command \ikw{buildcycle} is especially useful for boundaries of shaded areas \xs{sec:fill}. Given several paths, \kw{buildcycle} tries to piece them together to form an enclosed figure, which is returned as the result of the expression. Draw the bounding path, if required, \emph{after} shading the interior area with \ikw{filldraw}.\index{shading}\index{area!shaded}
\bep{120mm}
path p[];
p1 = (10,-5) -- (10,50);
p2 = (-5,0) -- (90,0);
p3 = (80,-5) -- (80,10);
p4 = (10,40) for i = 2 upto 9:
\- .. (10*i, 40/i) endfor;
p5 = buildcycle(p1, p2, p3, p4);
filldraw p5 withcolor 0.7 white;
draw p1; draw p2; draw p3; draw p4;
\eep{-15mm}{41}\label{for-loop}
\section{Commands}\label{sec:commands}
\mp\ has two kinds of command: those that draw something and those that do not. We discuss commands that draw first.
\subsection{Drawing Commands}
Execution of any of the commands described in this section adds something to the \kw{currentpicture}.
\subsubsection{\ikw{btex} and \ikw{verbatimtex}}\label{sec:btex}
\index{tex@\TeX}\index{latex@\LaTeX}
The command \kw{btex}~\agl{text}~\kw{etex} invokes \TeX\ to process \agl{text} and returns the result as a picture:
\bep{100mm}
\verb'draw btex $\sqrt{x^2+y^2}$ etex;'
\eep{-2mm}{17}
Commands between \kw{btex} and \kw{etex} are written in \TeX,\index{tex@\TeX} \emph{not} \LaTeX,\index{latex@\LaTeX} and the text is set in HR mode. For example, \verb"$$ ... $$" does not work, but \verb"$\displaystyle ... $" has the same effect. For more elaborate effects, use the TEX package \xs{sec:tex}.
\TeX\ boxes can be used to format \idx{multiple lines} between \kw{btex} and \kw{etex}.\index{line!multiple}
\bep{100mm}
boxit.a(btex
\-\- \verb'\vbox{\hbox{Above}\hbox{Below}}'
etex);
drawboxed(a);
\eep{-5mm}{83}
Text is set in the default font, which is usually \kw{cmr10}. The default font can be changed by assigning to the internal variable \ikw{defaultfont}. The size of the text is determined by the default scale, which is 1.\index{size!of text} The scale can be changed by assigning to the variable \ikw{defaultscale}. \xf{fig-latex-fonts} shows some other fonts.
The command \kw{verbatimtex}~\agl{text}~\kw{etex} is similar, but does not produce a picture. It is used to configure \TeX\ for subsequent processing. For example, the following commands define the font\index{font} commands \verb'\bkm' to be 11pt Bookman and \verb'lit' to be 10pt Typewriter:
\begin{verbatim}
verbatimtex
\font\bkm = pbkli scaled 1100
\font\lit = cmtex10 scaled 1000
etex
\end{verbatim}
These fonts can then be used in a \kw{btex} command:
\bep{100mm}
dotlabel.top(btex\verb'\bkm' server etex, origin);
\eep{0mm}{96}
\begin{figure}
\hrule\vskip6pt
\begin{center}
\begin{tabular}{lll}
Font & Name & Sizes: $s=$ \\ \hline
Bold & \texttt{cmb}$\langle s \rangle$ & $10$ \\
Bold extended & \texttt{cmbx}$\langle s \rangle$ & $5,6,7,8,9,10,12$ \\
Italic & \texttt{cmti}$\langle s \rangle$ & $7,8,9,10,12$ \\
Roman & \texttt{cmr}$\langle s \rangle$ & $5,6,7,8,9,10,12,17$ \\
Sans serif & \texttt{cmss}$\langle s \rangle$ & $8,9,10,12,17$ \\
Sans serif italic & \texttt{cmssi}$\langle s \rangle$ & $8,9,10,12,17$ \\
Slanted & \texttt{cmsl}$\langle s \rangle$ & $8,9,10,12$ \\
Small caps & \texttt{cmcsc}$\langle s \rangle$ & $10$ \\
Typewriter & \texttt{cmtt}$\langle s \rangle$ & $8,9,10,12$ \\
Typewriter italic & \texttt{cmitt}$\langle s \rangle$ & $10$ \\
Typewriter slanted & \texttt{cmsltt}$\langle s \rangle$ & $10$ \\
\end{tabular}
\end{center}
\caption{\LaTeX\ fonts}
\label{fig-latex-fonts}
\index{font}
\vskip6pt\hrule
\end{figure}
The command \kw{verbatimtex} can be used to create an environment in which \LaTeX\ can be used in \kw{btex} commands. \xf{fig-latex-tab} shows how a \LaTeX\ table can be drawn in \mp. The \LaTeX\ command \verb'\end{document}' is supplied automatically.
\begin{figure}[hbtp]
\hrule\medskip
\hspace*{15mm}
\begin{minipage}{100mm}
\begin{verbatim}
verbatimtex
%&latex
\documentclass{article}
\begin{document}
etex
beginfig(1);
draw btex
\begin{tabular}{|c|} \hline
First \\ \hline
Second \\ \hline
Third \\ \hline
\end{tabular}
etex;
endfig;
\end{verbatim}
\end{minipage}
\includegraphics{ltx-1.mps}
\caption{Drawing a \LaTeX\ table}
\label{fig-latex-tab}
\medskip\hrule
\end{figure}
\subsubsection{\kw{clip}}
The command
\bpr \ikw{clip} $p$ \kw{to} $b$ \epr
draws all parts of the picture $p$ that lie within the boundary $b$. The picture $p$ must be given as a picture variable, not a picture expression. The argument $b$ is a path.
\bep{100mm}
for i = -50 step 5 until 50:
\- draw (i,-50) -- (i+100,50);
endfor;
path c;
c = fullcircle scaled 70 shifted (50,0);
clip currentpicture to c;
draw c;
\eep{-10mm}{54}
\subsubsection{\ikw{draw}}\label{sec:draw}
The command
\bpr draw $p$ \epr
draws the path or picture defined by the picture expression $p$. A picture can be erased\index{erase} by drawing it with the background colour:
\be\ikw{undraw} \; p & \defeq & \kw{draw $p$ withcolor background} \ee
\subsubsection{\kw{drawarrow}}\label{sec:arrows}\index{arrow}
The following commands draw paths with arrows. The argument of each of these commands is a path, not a picture.
\be
\ikw{drawarrow} \; p &:& \mbox{draw path $p$ with an arrow at the end} \\
\kw{drawarrow reverse} \; p &:& \mbox{draw path $p$ with an arrow at the start} \\
\ikw{drawdblarrow} \; p &:& \mbox{draw path $p$ with an arrow at both ends} \\
\ee
The size of the arrow head is determined by \ikw{ahlength} and \ikw{ahangle}.\index{size!of arrow head} These internal variables have default values $\kw{ahlength}=4$ and $\kw{ahangle}=45^\circ$, respectively. The code in the following example draws an arrow with default values and another arrow with length 10 and angle $30^\circ$.
\bep{100mm}
begingroup;
\- drawarrow (0,30) -- (60,30);
\- interim ahlength := 10;
\- interim ahangle := 30;
\- drawarrow reverse ((0,0) -- (60,0));
endgroup;
\eep{-10mm}{65}
\subsubsection{\ikw{fill}}\label{sec:fill}
The following commands ``paint'' areas of the figure. The path must be a cycle \xs{sec:lines}, otherwise the paint may leak out.\index{painting}\index{shading}
\be
\ikw{fill} \; p &: & \mbox{paint the area enclosed by path $p$ with black} \\
\ikw{fill} \; p \; \ikw{withcolor} \; c &: & \mbox{paint the area enclosed by path $p$ with colour $c$} \\
\ee
There are some useful macros that use \kw{fill}:
\be
\ikw{filldraw} \; p & \defeq & \kw{draw (fill $p$)} \\
\ikw{filldraw} \; p \; \kw{withcolor} \; c & \defeq & \kw{draw (fill $p$ withcolor $c$)} \\
\ikw{unfill} \; p & \defeq & \kw{fill $p$ withcolor background} \\
\ee
Filling provides an alternative to \kw{cutbefore} and \kw{cutafter}. In this example, \kw{filldraw} erases the part of the line that would be inside the circle at \kw{z2}.
\bep{150mm}
z1 = (0,20); z2 = (0,-20);
draw z1--z2;
filldraw fullcircle scaled 20 shifted z2 withcolor white;
draw fullcircle scaled 20 shifted z1;
draw fullcircle scaled 20 shifted z2;
\eep{-10mm}{37}
\subsubsection{\ikw{label}}\label{sec:labels}
The command
\bpr label \agl{suffix} ( \agl{picture expression} , \agl{pair} ) \epr
writes a label. \agl{picture} describes the label to be written. It is usually a string \xs{sec:string} or \kw{btex \ldots\ etex} \xs{sec:btex}. The \agl{pair} determines the position of the label. The \agl{suffix} may be omitted; if it is present, it must be one of
$$
\kw{.lft} \index{lft@\kw{lft}} \quad
\kw{.rt} \index{rt@\kw{rt}} \quad
\kw{.top} \index{top@\kw{top}} \quad
\kw{.bot} \index{bot@\kw{bot}} \quad
\kw{.ulft} \index{ulft@\kw{ulft}} \quad
\kw{.urt} \index{urt@\kw{urt}} \quad
\kw{.llft} \index{llft@\kw{llft}} \quad
\kw{.lrt} \index{lrt@\kw{lrt}}
$$
and it defines the position of the label with respect to \agl{pair}.
The command \ikw{thelabel} is also similar to \kw{label} but returns the result as a picture without drawing it. Thus:
\be \kw{label} (p,z) & \defeq & \kw{draw thelabel} (p,z) \ee
The command \ikw{dotlabel} is similar to \kw{label} but draws a large dot at the labelled point.
\bep{120mm}
draw (0,0) -- (30,20) -- (-30,20) -- cycle;
label.ulft(btex $(-30,20)$ etex, (-30,20));
label.urt(btex $(30,20)$ etex, (30,20));
dotlabel.bot(btex $(0,0)$ etex, (0,0));
\eep{-5mm}{1}
The command \ikw{dotlabels} provides an abbreviation that can be used when all of the points to be labelled have the form \kw{z}\agl{suffix} and the suffixes are suitable for use as labels.
\bep{120mm}
z.alpha = (0,0);
z.beta = (20,20);
z.gamma = (40,0);
dotlabels.top(alpha, beta, gamma);
\eep{-5mm}{18}
The size of the dots is determined by the internal variable \ikw{dotlabeldiam}. The default value is 3bp. The following assignment makes the dots smaller:
\bpr dotlabeldiam := 1bp; \epr
\index{size!of dots}
\subsection{Non-drawing Commands}
The commands in this section may change \mp's internal state but do not add anything to the \kw{currentpicture}.
\subsubsection{\ikw{drawoptions}}\label{sec:drawoptions}
The command \kw{drawoptions(\agl{text})} adds the options specified by \agl{text} to all drawing commends until it is cancelled by the command \kw{drawoptions()}. The options allowed in \agl{text} include \kw{dashed} \xs{sec:dashes}, \kw{withcolor} \xs{sec:color}, and \kw{withpen} \xs{sec:pen}. For example:
\bex{100mm}
drawoptions(withcolor blue);
drawboxed(fred);
drawoptions();
\eex
The options in the scope of \kw{drawoptions} affect only the commands for which they ``make sense''. For example, if a picture is drawn with \kw{drawoptions(dashed evenly)}, all of its paths will be drawn with dashes, but its labels will not be affected.
\subsubsection{\ikw{filenametemplate}}\label{sec:filenametemplate}
\index{file!name}
\index{name!of output file}
\index{output!file name}
By default, \mp\ reads from a file called \kw{\agl{jobname}.mp} and writes the output created by \kw{beginfig($n$) ... endfig} to \kw{jobname.$n$}. The name of the output file can be changed by including a command of this form near the beginning of the input file:
\bpr filenametemplate \agl{format string} ; \epr
The resulting file name is the \agl{format string} after escape sequences have been processed. \xf{fig:fnt} lists the escape codes that \mp\ recognizes.
\begin{figure}[hbtp]
\hrule\vskip4pt
\begin{center}
\begin{tabular}{ll}
\kw{\%\%} & Percent sign\\
\kw{\%j} & Job name\\
\kw{\%$\,\delta\,$c} & The argument of \ikw{beginfig}\\
\kw{\%$\,\delta\,$y} & Year\\
\kw{\%$\,\delta\,$m} & Month\\
\kw{\%$\,\delta\,$d} & Day\\
\kw{\%$\,\delta\,$H} & Hour\\
\kw{\%$\,\delta\,$M} & Minute\\
\end{tabular}
\end{center}
\caption[Escape sequences for \kw{filenametemplate}]{Escape sequences for \kw{filenametemplate}. The symbol $\,\delta\,$ stands for an optional decimal digit ($0,1,2,\ldots,9$) that sets the size of the string.}
\label{fig:fnt}
\vskip4pt\hrule
\end{figure}
Suppose that the input file is \kw{doc.mp}. By default, \mp\ behaves as if
\bpr filenametemplate "\verb'%j.%c'"; \epr
has been executed and generates figure files called \kw{doc.1}, \kw{doc.2}, etc. If the \mp\ program included the command
\bpr filenametemplate "\verb'doc-%4y-%3c.mps'"; \epr
then the output file names would be \kw{doc-2007-001.mps}, \kw{doc-2007-002.mps}, etc. This is useful for versions of \LaTeX\ that do not recognize numbers as file extensions.
\subsubsection{\ikw{for}}\label{sec:for}
The \mp\ \idx{loop} has the general form:\idc{for}
\bex{160mm}
for \agl{name} = \agl{list}:
\- \agl{seq}
endfor
\eex
Although \emph{list} is not a type of \mp, there are expressions that generate lists \xs{sec:list}. For example:
\bex{100mm}
for n = 1 upto 10:
\- show x;
endfor
\eex
in which \ikw{upto} is an abbreviation, as is \ikw{downto}:
\be
\ikw{upto} & \defeq & \kw{step 1 until} \\
\mbox{and} \qquad \ikw{downto} & \defeq & \kw{step -1 until}
\ee
The numerical values do not have to be integers:
\bex{100mm}
for x = 0.5 step 0.1 until 1.5:
\- show x;
endfor;
\mex{60mm}
\sh\ 0
\sh\ 0.1
\sh\ 0.20001
\sh\ 0.30002
....
\sh\ 0.90005
\eex
A list of expressions is accepted:
\bex{80mm}
for e = 1, 256.1, "done":
\- show e;
endfor;
\mex{60mm}
\sh\ 1
\sh\ 256.1
\sh\ "done"
\eex
\mp\ commands can be nested in fairly arbitrary ways. In the following example, the first point of a path is drawn in the usual way, but the remaining points are generated by a \kw{for} loop. Note that there is no semicolon at the end of the loop body: a semicolon at this position would violate the syntax of \kw{draw}. The semicolon after \kw{endfor} serves to terminate the \kw{draw} command.
\bep{120mm}
draw (1,0)
for i := 0 upto 180:
.. (mexp(5i)*cosd(10i), mexp(5i)*sind(10i))
endfor;
\eep{-5mm}{79}
There are not many \mp\ expressions that yield lists of tokens: one of them is \ikw{scantokens} \xs{sec:list}. Consequently, \kw{for} and \kw{scantokens} are often used together \xs{sec:readfile}.
If there are no natural loop variables, use
\bpr \ikw{forever}: \agl{seq} \ikw{exitif} \agl{pred}; \agl{seq} endfor \epr
or
\bpr forever: \agl{seq} \ikw{exitunless} \agl{pred}; \agl{seq} endfor \epr
A \kw{for} loop can be used to obtain the parts of a picture. The effect of
\bpr for $c$ \ikw{within} \agl{picture expression} : \agl{loop} endfor \epr
is to bind each component of the picture in turn to $c$ and then execute the text in \agl{loop}. Various predicates and selectors may be used in \agl{loop}, including \ikw{stroked}, \ikw{filled}, \ikw{textual}, \ikw{clipped}, \ikw{bounded}, \ikw{pathpart}, \ikw{penpart}, and \ikw{dashpart}. \xf{fig:within} provides a simple example.
\begin{figure}
\hrule\vskip 6pt
\bex{80mm}
draw (0,0) -- (100,0);
filldraw fullcircle scaled 50;
label.bot("line", (50,0));
picture p;
p = currentpicture;
show "p has " \& decimal(length(p))
\- \& \" components.";
\-
n = 0;
string msg;
for i within p:
\- n := n + 1;
\- msg := "Component " \&
\-\- decimal n \& " is";
\- if stroked i:
\-\- msg := msg \& " stroked";
\- fi;
\- if filled i:
\-\- msg := msg \& " filled";
\- fi;
\- if textual i:
\-\- msg := msg \& " textual";
\- fi;
\- show msg;
endfor;
\mex{100mm}
\sh\ "p has 3 components."
\sh\ "Component 1 is stroked"
\sh\ "Component 2 is filled"
\sh\ "Component 3 is textual"
\eex
\caption{Using \kw{for...within} to obtain a partial analysis of a picture.}
\label{fig:within}
\vskip4pt\hrule
\end{figure}
Like its relatives \TeX\ and \textsf{metafont}, \mp\ is more like a macroprocessor than a formal language. This means that it is often possible to arbitrary chunks of text in a \kw{for} loop, not just complete expressions. The shading example on page~\pageref{for-loop} illustrates this kind of usage.
\subsubsection{\ikw{if}}\label{sec:if}
Tests can be used in conditional statements which have the general form
\bex{140mm}
\ikw{if} \agl{pred}: \agl{seq}
\ikw{else}: \agl{seq}
\ikw{fi}
\eex
Compound conditional statements use \ikw{elseif}:
\bex{140mm}
if \agl{pred}: \agl{seq}
elseif \agl{pred}: \agl{seq}
else: \agl{seq}
fi
\eex
There are small inconsistencies in \mp's naming: after getting used to \kw{for}\ldots\kw{endfor}, it is easy to write \kw{if}\ldots\kw{endif}, giving mysterious error messages.
\boxedquote{\kw{for}\ldots\kw{endfor} \qquad but \qquad \kw{if}\ldots\kw{fi}.}
In this example, an \kw{if} command labels points on a curve according to their signs:
\bep{110mm}
save k, p;
path k;
k = (0,0){dir 35} .. {dir 45}(80,0);
draw k;
for t := 0 step 0.1 until 1:
\- pair p;
\- p := point t of k;
\- if ypart p > 0:
\-\- label.top(btex $+$ etex, p);
\- elseif ypart p < 0:
\-\- label.bot(btex $-$ etex, p);
\- fi;
endfor;
\eep{0mm}{97}
\subsubsection{\ikw{message}}\label{sec:message}\index{write!string}\index{output!to console}
The command \kw{message} takes a \kw{string} expression as its argument and displays the string on the console when \mp\ executes.
\subsubsection{\ikw{readfrom}}\label{sec:readfrom}\index{read file}\index{file!read}
The effect of
\bpr readfrom \agl{file name} \epr
is to read one line from the named file and return the line as a string. If the file cannot be read, or if end of file has been reached, the string returned is \ikw{EOF}, which contains just the null character (i.e., $\kw{EOF}=\verb'"\0"'$).
If \kw{readfrom \agl{file name}} is executed again after it has returned \kw{EOF}, the file is read again from the beginning.
See \xs{sec:readfile} for an example of the use of \kw{readfrom}. It is also possible to write to a file \xs{sec:write}.
\subsubsection{\ikw{save}}\label{sec:save}
The command \kw{save}, followed by a list of variable names, saves the values of these variables and restores them again at the end of the scope, effectively making these variables local to the current scope. See also \xs{sec:scope} and \xs{sec:macro}.
\subsubsection{\kw{show} and friends}\label{sec:show}\index{write!expression}\index{output!to console}
The command
\bpr \ikw{show} $e$ \epr
writes \sh\ followed by the value of the expression $e$ to standard output. If the expression cannot be expressed in a simple textual form, \mp\ writes the type instead.
\bex{60mm}
show (0,0) -- (10,0);
\mex{60mm}
\sh\ path
\eex
There are variants of \kw{show} that are used less often but can be handy for debugging:
\be
\ikw{showdependencies} &\defeq& \mbox{the known dependencies for a set of equations} \\
\ikw{showtoken} &\defeq& \mbox{the parameters and replacement text of a macro} \\
\ikw{showvariable} &\defeq& \mbox{the properties associated with a name} \\
\ee
For example,
\bex{120mm}
def hyp(expr a, b) = sqrt(a*a + b*b) enddef;
showtoken hyp;
\eex
produces
\begin{verbatim}
> hyp=macro:
(EXPR0)(EXPR1)->sqrt((EXPR0)*(EXPR0)+(EXPR1)*(EXPR1)) )
\end{verbatim}
The variable \ikw{showstopping} controls the behaviour of \mp\ after it has executed a \kw{show} command. If $\kw{showstopping}>0$, \mp\ pauses after each \kw{show} command.
\subsubsection{\ikw{write}}\label{sec:write}\index{write!to file}\index{file!write}
The effect of the command
\bpr write \agl{string expression} to \agl{file name} \epr
is to write one line to the named file. If the file is not already open, \mp\ opens it before writing. The file is closed when the \mp\ program terminates, or explicitly by executing
\bpr write \ikw{EOF} to \agl{file name} \epr
It is also possible to read from a file: \xs{sec:readfrom}.
\section{Macros}\label{sec:macro}
\mp\ provides many ways of defining \idx{macro}s. Here we describe just the most basic and useful techniques.
\subsection{\kw{def} macros}
Simple macros have the form
\bex{80mm} \ikw{def} \agl{name} = \agl{seq} \kw{enddef} \eex
Simple macros with parameters have the form
\bex{120mm} def \agl{name} ( \agl{parameters} ) = \agl{seq} enddef \eex
Following the macro definition, each occurrence of \agl{name} is replaced by \agl{seq}, with \idx{parameter}s replaced by \idx{argument}s when applicable. If the sequence \agl{seq} ends with an expression, the value of that expression becomes the value of the macro. Note that there is no semicolon after the expression:
\bex{60mm}
def hyp(expr a, b) =
\- sqrt(a*a + b*b)
enddef;
\-
show hyp(3,4);
\mex{30mm}
\vskip 16ex
\sh\ 5
\eex
We can obtain a simple three-dimensional effect by adding a shadow to an outline. If the light source is above and to the left, the shadow should be below and to the right. The macro \kw{shadow} gives a \idx{shadow} to any path that can be filled --- that is, to any closed path.
\bep{150mm}
def shadow(expr p) =
\- filldraw p shifted (3,-3) withcolor 0.7 white;
\- filldraw p withcolor white;
\- draw p;
enddef;
\-
shadow(unitsquare scaled 20);
shadow(fullcircle scaled 20 shifted (40,0));
path p;
p = (0,0)--(0,20)--(20,40)--(50,40)--
\- (30,20)--(30,0)--cycle;
shadow(p shifted (70,-20));
\eep{-10mm}{46}
There are three kinds of macro parameter,\index{parameter!of macro} distinguished by writing one of the keywords \kw{expr}, \kw{suffix}, or \kw{text} before the parameter list.
\begin{itemize}
\item\index{expr@\kw{expr}!macro parameter} An \kw{expr} parameter can be used as a variable in the body of the macro. Its value can be constrained by equations but cannot be re-assigned. The following macro says that the points \kw{a}, \kw{b}, \kw{c}, and \kw{d} are symmetrically placed around the origin but their separation is not known until at least one point has been positioned:
\bex{120mm}
def vx(expr a, b, c, d) =
\- a + c = (0,0);
\- b + d = (0,0);
\- xpart a = xpart d;
\- ypart a = ypart b;
enddef;
\-
vx(z1,z2,z3,z4);
z1 = (1,1);
show z1; show z2; show z3; show z4;
\mex{60mm}
\sh\ (1,1)
\sh\ (-1,1)
\sh\ (-1,-1)
\sh\ (1,-1)
\eex
\item\index{suffix@\kw{suffix}!macro parameter} A \kw{suffix} parameter is bound to an initializing expression but may also be used as a variable name. The macro \kw{showfirst} would be illegal with an \kw{expr} parameter, but is allowed with a \kw{suffix} parameter:
\bpr
def showfirst(suffix a) = show a[0]; enddef;
\epr
\item\index{text@\kw{text}!macro parameter} A \kw{text} parameter is bound to an arbitrary sequence of tokens. When its name is encountered in the body, \mp\ simply substitutes the corresponding argument and parses the result. For example, if we define
\bpr
def doIt(text cmd) = cmd (0,0)--(5,5); enddef;
\epr
then \kw{doIt(draw)} draws the path but \kw{doIt(show)} simply displays it.
\end{itemize}
If a macro has two or more different kinds of parameters, there must be a separate parameter list for each kind:
\bpr def tricky(expr a, b)(suffix p) = ... enddef; \epr
However, the corresponding invocation has just a single list of arguments:
\bpr tricky(2.3, xpart q, z); \epr
\mp\ supports recursion in macros:
\index{macro!recursive}
\index{recursion}
\idc{nest}
\bep{100mm}
def nest(expr hor, ver) =
\- draw fullcircle xscaled hor yscaled ver;
\- if (hor > 5) and (ver > 5):
\-\- nest(0.8 hor, 0.7 ver);
\- fi;
enddef;
\-
nest(60, 100);
\eep{-20mm}{98}
\subsection{\kw{vardef} and other macro forms}
A macro definition may be introduced by \ikw{vardef} instead of \kw{def}. The most useful difference is that the body of a \kw{vardef} macro is a group. A macro such as \kw{area} can be used in the same way as a function in other languages:
\bex{100mm}
vardef area(expr a, b, c) =
\- save s;
\- s := 0.5*(a+b+c);
\- sqrt(s*(s-a)*(s-b)*(s-c))
enddef;
\-
show area(3,4,5);
\mex{30mm}
\vskip 16ex
\sh\ 6
\eex
The name of a \kw{vardef} macro may be a compound containing suffixes. Within the macro, \verb'@' is the last token of the macro call and \verb'#@' is everything that comes before the last token. Macros defined with \ikw{vardef} can be used to define special behaviour for particular variable names. For example, the special relationship between \ikw{x}, \ikw{y}, and \ikw{z} is a consequence of the macro definition
\bpr\verb'vardef z@# = (x@#, y@#) enddef;'\epr
There are other forms of macro definition for which a full description goes beyond the scope of this manual. For example, macros can be used to define unary and binary operators. After defining
\bpr vardef neg primary x = -x enddef; \epr
we can use \kw{neg} to negate numeric values and pairs. For example,
\bex{100mm}
neg((3,4))
\mex{30mm}
\sh\ (-3,-4)
\eex
Similarly, after defining a midpoint operator
\bpr
primarydef p mp q = 0.5[p,q] enddef;
\epr
we can write
\bep{100mm}
z1 = (0,0);
z2 = (0,40);
draw z1 -- z2;
label.rt("mp", z1 mp z2);
\eep{0mm}{42}
The ``suffix'' form of parameter can be used for a number of purposes. For example, this macro takes the position of a label as a parameter:
\index{label!position (as parameter)}%
\bpr
vardef cutla(suffix pos)(expr lab)(suffix a, b) =
drawarrow a.c -- b.c cutbefore bpath a cutafter bpath b;
label.pos(lab, 0.5[a.c,b.c]);
enddef;
\epr
This macro is called with four arguments, of which the first specifies the position of the label:
\bep{100mm}
boxit.a("A"); boxit.b("B");
b.c = a.c + (60,0);
drawunboxed(a, b);
cutla(top, "x", a, b);
\eep{0mm}{86}
\section{Macro Packages}\label{sec:packages}
Many \mp\ macro packages have been written, by Hobby and others. In this section, we describe a few of them. To use a package, include this command at the beginning of your \mp\ program:
\bpr \ikw{input} \agl{package name} \epr
\subsection{Boxes}\label{sec:boxes}
There is a standard macro package, called \ikw{boxes}, for drawing boxes. To use it, include this statement at the beginning of your \mp\ program:
\bpr input boxes \epr
The boxes produced by \kw{boxes} have square corners. To get boxes with both square and rounded corners, use
\bpr input \ikw{rboxes} \epr
\subsubsection{Creating and Drawing Boxes}
To create a box, write
\bpr \ikw{boxit} . \agl{box name} ( \agl{picture expression} ) \epr
The package \ikw{rboxes} provides the command \ikw{rboxit} as well. It works in the same way as \ikw{boxit}, but produces boxes with rounded corners.
To draw boxes, write
\bpr \ikw{drawboxed} ( $b_1,b_2,\ldots,b_n$ ) \epr
where $b_1,b_2,\ldots,b_n$ is a list of box names. The result of drawing a box is shown in \xf{fig-box-var}, in which the shaded inner rectangle corresponds to the picture and the outer rectangle is the box that is drawn. The box can be sized and positioned by applying the suffixes in \xf{fig-box-var} to the box name. For example, if the box name is \kw{bx}, then \kw{bx.c} is its centre, \kw{bx.ne} is its top right corner, and so on.
The values of \ikw{c}, \ikw{dx}, and \ikw{dy} are left unspecified. If \mp\ can infer their values from constraints on the positioning points, it does so. If not, it gives them the default values
\be
\kw{c} & = & (0,0) \\
\ikw{dx} & = & \ikw{defaultdx} \\
\ikw{dy} & = & \ikw{defaultdy}
\ee
The values of \kw{defaultdx} and \kw{defaultdy} can be changed by assignment. For example:
\bpr
defaultdx := 20;
defaultdy := 15;
\epr
\mpfig{hbtp}{29}{Box variables}{fig-box-var}
The command \kw{drawboxed} actually draws the boxes. Consequently, the best way to use boxes is to follow this sequence:
\begin{enumerate}
\item Use \kw{boxit} to create the boxes
\item Write equations that specify positional relations between boxes
\item Use \kw{drawboxed} to draw the boxes
\end{enumerate}
\bep{100mm}
boxit.bl("left");
boxit.bm("middle");
boxit.br("right");
bm.sw - bl.ne = (20,0);
br.nw - bm.se = (20,0);
drawboxed(bl,bm,br);
\eep{0mm}{30}
This example is similar, but illustrates the use of the package \ikw{rboxes}. The macro \ikw{cuta} is defined later \xs{sec:linking}.
\bep{100mm}
boxit.sb("box with square corners");
rboxit.rb("box with rounded corners");
rb.c = sb.c + (100,0);
drawboxed(sb, rb);
cuta(sb,rb);
\eep{-5mm}{75}
\subsubsection{Joining Boxes}\index{boxes!joining}
\mp\ provides a simple and effective way to position boxes relative to one another. The macro \ikw{boxjoin} takes as argument a list of equations, separated by semicolons, describing the relationship between boxes \kw{a} and \kw{b}. The equations can be used to constrain both the positions and the sizes of boxes.
\bep{100mm}
boxjoin(a.sw = b.nw; a.se = b.ne);
boxit.bt("top");
bt.ne - bt.nw = (50,0);
boxit.bm("middle");
boxit.bb("bottom");
drawboxed(bt,bm,bb);
\eep{0mm}{31}
The equation \kw{bt.ne - bt.nw = (50,0)} sets the width for the first box and \kw{boxjoin} ensures that the other boxes have the same width. If it is omitted, the default size of the top box is used as the width:
~\hfill\convertMPtoPDF{mpref.32}{1}{1}
The constraints imposed by \kw{boxjoin} can be removed either by calling \kw{boxjoin} with different equations or an empty argument.
\bep{120mm}
boxjoin(a.e = b.w);
\verb'boxit.b1(btex $b_1$ etex); boxit.b2(btex $b_2$ etex);'
\verb'boxit.b3(btex $b_3$ etex); boxit.b4(btex $b_4$ etex);'
\verb'boxit.b5(btex $b_5$ etex);'
boxjoin();
\verb'boxit.b6(btex $b_6$ etex); b6.n = b1.s - (whatever,10);'
drawboxed(b1,b2,b3,b4,b5,b6);
\eep{0mm}{36}
\subsection{Linking Boxes}\index{boxes!linking}\label{sec:linking}
The path surrounding the box named $b$ is \ikw{bpath}~$b$.\index{path!of box} This provides and simple way of joining boxes with lines or arrows.
\bep{100mm}
boxjoin(a.e = b.w - (20,30));
boxit.scan("scan");
boxit.parse("parse");
drawboxed(scan, parse);
\verb"drawarrow scan.c{dir 0} .. {dir 90}parse.c"
\- cutbefore bpath scan
\- cutafter bpath parse;
\eep{0mm}{33}
Here are some macros that make use of \ikw{bpath}.
\begin{itemize}
\item Join two boxes with an arrow:
\bpr
vardef \ikw{cuta}(suffix a, b) =
\- drawarrow a.c -- b.c cutbefore bpath.a cutafter bpath.b;
enddef;
\epr
\item Join two boxes with an arrow that follows a given path:
\bpr
vardef \ikw{cutpa}(suffix a, b)(expr p) =
\- drawarrow p cutbefore bpath a cutafter bpath b;
enddef;
\epr
\item Join two boxes with a line labelled at the midpoint:
\bpr
vardef \ikw{cutll}(suffix pos)(expr lab)(suffix a, b) =
\- draw a.c -- b.c cutbefore bpath a cutafter bpath b;
\- label.pos(lab, 0.5[a.c,b.c]);
enddef;
\epr
\end{itemize}
Here are these macros in action:
\bep{110mm}
\bpr
boxit.a("A");
boxit.b("B");
boxit.c("C");
b.c - a.c = c.c - b.c = (50,0);
drawunboxed(a, b, c);
cuta(a, b);
cutll(bot, btex $\Phi$ etex, b, c);
cutpa(a, c, a.c ..\ 0.5[a.c,c.c]+(0,20) ..\ c.c);
\epr
\eep{0mm}{90}
\subsubsection{Oval Boxes}\index{boxes!oval}
The macro \ikw{circleit} is similar to \kw{boxit} except that the picture argument is enclosed in an oval rather than a rectangle. The corner points are not defined, but the other points correspond to \kw{boxit}, as shown in \xf{fig-oval-var}. Use \kw{drawboxed} to draw the picture produced by \kw{circleit} (not ``drawcircled'').
\mpfig{hbtp}{34}{Oval variables}{fig-oval-var}
The path \kw{bpath $c$} created by \kw{circleit} is a circle unless at least one $c.\kw{dx}$, $c.\kw{dy}$, or $c.\kw{dx}-c.\kw{dy}$ is known. If any of these values are known, the path is an oval that contains the picture with a safety margin defined by \ikw{circmargin}, a length with default value \unit{2}{bp}.
Assigning to \kw{defaultdx} and \kw{defaultdy}, as explained above, does \emph{not} work for \kw{circleit}. However, their values can be assigned explicitly, as in this example:
\bep{100mm}
circleit.wd("establishment");
wd.dy = 20;
drawboxed(wd);
\eep{-5mm}{35}
Other commands associated with boxes include:
\index{boxes!outlines}
\be
\ikw{drawboxes} (\ldots) &:& \mbox{draw the outlines of the listed boxes but not their contents} \\
\ikw{drawunboxed} (\ldots) &:& \mbox{draw the contents of the listed boxes but not their outlines} \\
\ikw{pic} \; b &:& \mbox{return the contents of the box $b$ without its outline}
\ee
Thus \kw{drawunboxed(b1,b2)} is an abbreviation for
\bpr
draw pic b1;
draw pic b2;
\epr
\subsubsection{Text in Boxes}\index{boxes!text in}
\mp\ uses \TeX\ to process text in boxes and elsewhere. \TeX\ commands must therefore be used to obtain effects such as multiple lines in a box. For example:
\bep{100mm}
\begin{verbatim}
boxit.two(btex
\vbox{
\hbox{First line}
\hbox{Second line}} etex);
drawboxed(two);
\end{verbatim}
\eep{0mm}{84}
\subsection{Graphs}
John Hobby has written a graph package for \mp. A complete description of this package is beyond our scope, but we have space for a simple example. The file \kw{hist.txt} contains the results of a simulated experiment in which a coin is tossed 50 times and the number of `heads' are recorded. Each line of the file consists of two integers, as in the following extract:
\begin{verbatim}
....
23 96237
24 107870
25 112401
26 107747
27 96453
28 78692
....
\end{verbatim}
Before drawing graphs, the graph macros must be read from \kw{graph.mp}. The following \mp\ code is all that is needed to obtain \xf{fig:tosses}.
\bpr
input graph
\-
beginfig(1);
\- draw begingraph(4in,3in);
\- gdraw("hist.txt");
\- endgraph;
endfig;
\epr
\mpfig{hbtp}{69}{Simulated coin tossing}{fig:tosses}
\subsection{TEX}\label{sec:tex}
\mp\ does not process text between \ikw{btex} and \ikw{etex}. For example, if you write \kw{btex~n~etex}, \mp\ will typeset the character ``n'', not the value of the variable \kw{n}. The package \kw{TEX.mp} provides an operator \ikw{TEX} that overcomes this problem. The expression\index{decimal@\kw{decimal}!in \LaTeX}
\bpr\verb'TEX("$X_{" & decimal(n) & "}$")'\epr
returns a picture that can be used, for example, in a \ikw{label} command. For $n=0,1,2,\ldots$, the pictures will be $X_0,X_1,X_2,\ldots$. The \kw{\&} in this commend is the \mp\ concatenation operator, \emph{not} \TeX's alignment character. If the value of $n$ is 35, for example, the command above constructs the string \verb"$X_{35}$" and sends it to \TeX.
The package also provides two further commands:
\be
\kw{TEXPRE($s$)} && \mbox{defines text that will be passed to \TeX\ before each \kw{TEX} command}\\
\kw{TEXPOST($s$)} && \mbox{defines text that will be passed to \TeX\ after each \kw{TEX} command}\\
\ee
For example, you can use \LaTeX\ in labels by including these two commands at the beginning of your \mp\ program (\kw{char(10)} generates a line break):
\bpr
\verb'TEXPRE("%&latex" & char(10) & "\documentclass{article}\begin{document}");'
\verb'TEXPOST("\end{document}");'
\epr
\subsection{MetaUML}
The package \kw{MetaUML.mp} extends \mp\ so that it can draw \idx{UML diagrams}. This package is included with MIK\TeX\ and is easy to find at SourceForge.
The good news is that \idx{MetaUML} draws very nice UML diagrams when given correct input. The bad news is that rather small errors in the input tend to produce numerous error messages and may even cause \mp\ to loop.
\xf{fig-metauml-diagram} shows a diagram drawn by MetaUML and \xf{fig-metauml-code} shows the code used to produce it. Note that the package \kw{TEX.mp} must be loaded, as well as \kw{metauml.mp}.
\begin{figure}
\hrule\vskip6pt
$$\includegraphics{figs-82.mps}$$
\caption{The UML diagram generated from the code in \xf{fig-metauml-code}}
\label{fig-metauml-diagram}
\vskip6pt\hrule
\end{figure}
\begin{figure}
\hrule\vskip6pt
\begin{verbatim}
input metauml;
input TEX;
beginfig(82);
save art,cow,ifa;
Class.art("Artist")()("+draw()", "+paint()");
Class.cow("Cowboy")()("+draw()", "+shoot()");
Class.ifa("Draw")()("+draw()");
classStereotype.ifa("<>");
cow.w = art.e + (100,0);
z0 = 0.5[art.e,cow.w];
ifa.s = z0 + (0,40);
drawObjects(art,cow,ifa);
draw art.e -- cow.w dashed evenly;
z1 = ifa.s - (0,10);
draw z0 -- z1 dashed evenly;
link(inheritance)(z1--ifa.s);
endfig;
\end{verbatim}
\caption{Using \kw{MetaUML}}
\label{fig-metauml-code}
\vskip6pt\hrule
\end{figure}
\section{Debugging}
It may seem odd to talk about ``debugging'' diagrams, but \mp\ is a programming language. The advantages of the programming language approach should be obvious from earlier parts of this manual; the disadvantages become clear when you actually try to use \mp.
As a simple illustration, suppose that you accidentally write ``\kw{btext}'' instead of ``\kw{btex}''. If you have written a few hundred lines of code, \mp's response may be quite worrying:
\begin{verbatim}
D:\Pubs\MetaPost>mp figs
(figs.mpCreating figs.mpx...
makempx: mpto failed on D:\Pubs\MetaPost\figs.mp.
mp: The operation failed for some reason.
\end{verbatim}
As with other kinds of programming, the best approach to \mp\ is to proceed slowly and carefully with frequent tests. When \mp\ does fail, there is a good chance that the error is in the last few lines that you have written.
Here are a few additional tips for getting errant \mp\ programs to work:
\begin{itemize}
\item Use \kw{show} and its friends \xs{sec:show} to check that variables have the values that you expect.
\item Use commands like \kw{dotlabel("z5", z5)} to check that points are where you think they are. Sometimes, it is even quicker to use \ikw{dotlabels} \xs{sec:labels}.
\item When \mp\ fails, it often generates hundreds of lines of diagnostics. Sometimes, it is easy to see what went wrong. If not, it is often quicker to identify the line of code that \mp\ is complaining about, and to examine that line very carefully, than it is to try and understand the diagnostic.
\item Errors such as ``inconsistent equation'' may occur if you use the same variable names in different figures. You can avoid this problem by using \kw{save} \xs{sec:save} for the variables of each figure.
\end{itemize}
\section{Examples}\label{sec:examples}
In the last section of this manual, we give some complete examples that illustrate the practical use of \mp.
\subsection{Euler Integration}
The goal of this example is to obtain a figure like \xf{fig-euler} illustrating the error, $e$, of first-order Euler integration. If $f'$ is the derivative of $f$:
\be f(x+\Delta x) &\approx& f(x) + f'(x) \, \Delta x \ee
\mpfig{hbtp}{48}{Euler Integration}{fig-euler}
The first step is to draw a suitable path. A B\'ezier curve is the simplest to generate with \mp:
\bpr
path c;
c = (0,0){dir 0} .. (150,100);
draw c;
\epr
Next, we choose a point on the path, $P_1$:
\bpr
t := 0.4;
pair P[];
P1 = point t of c;
\epr
The value of $\Delta x$ is arbitrary, but we should choose a value large enough to make the diagram readable. We can then compute $\Delta y$ using the direction (i.e., slope) of the path at $t$.
\bpr
dx := 60;
(dx, dy) = whatever * direction t of c;
\epr
With $\Delta x$ and $\Delta y$ known, we can locate the other points that we need. $P_4$ is not labelled in \xf{fig-euler}; it is the third vertex of the triangle with hypotenuse $P_1P_3$.
\bpr
P4 = P1 + (dx, 0);
P3 = P4 + (0, dy);
P2 = c intersectionpoint (P4 -- P4+(0,100));
\epr
All that remains is to draw the lines and label the points and lengths:
\begin{verbatim}
draw P1--P4--P2;
draw P1--P3;
dotlabel.ulft(btex $P_1$ etex, P1);
dotlabel.ulft(btex $P_2$ etex, P2);
dotlabel.rt(btex $P_3$ etex, P3);
label.bot(btex $\Delta x$ etex, 0.5[P1,P4]);
label.rt(btex $\Delta y$ etex, 0.5[P4,P3]);
label.rt(btex $e$ etex, 0.5[P3,P2]);
\end{verbatim}
\subsection{The Lorentz Transformation}\label{sec:ex-lor}
The Lorentz transformation for inertial frames with relative velocity $v$ is
\be
x' & = & \gamma x + \gamma \beta c t \\
ct' & = & \gamma \beta x + \gamma c t
\ee
where $c$ is the velocity of light, $\beta = v/c$, and $\gamma = 1/\sqrt{ \rule{0pt}{2ex} 1-v^2/c^2}$. Assuming $c=1$, $v=0.5$, writing \kw{b} for $\beta$, \kw{g} for $\gamma$, and including a translation of 200 units, we can express the transformation in \mp\ as:
\bpr
b = 0.5;
g = sqrt(1 - b * b);
transform t;
xpart t = 200; ypart t = 0;
xxpart t = g; yxpart t = g * b;
xypart t = g * b; yypart t = g;
\epr
We illustrate the scenario shown on the left of \xf{fig-lor}): a light flashes at $a$, is reflected by mirrors at $b$ and $b'$, and returns to the original point, displaced in time, at $a'$. We need eleven points for the diagram; \xf{fig-lor-num} shows the numbering scheme. The scale is determined by two constants, $s$ and $d$:
\bpr
s = 10;
d = 80;
\epr
It is easiest to define the $x$ coordinates and the $y$ coordinates separately:
\bpr
x1 = x2 = x3 = 0;
x4 = x5 = x6 = x7 = x1 + d;
x8 = x9 = x10 = x4 + d;
x11 = x8 + s;
y1 = y4 = y8 = y11 = 0;
y5 = s;
y2 = y9 = y5 + d;
y6 = y2 + d;
y3 = y7 = y10 = y6 + s;
\epr
\mpfig{hbtp}{39}{The Lorentz Transformation}{fig-lor}
\mpfig{hbtp}{49}{Point numbering used in \xf{fig-lor}}{fig-lor-num}
We draw arrows for the axes:
\bpr
drawarrow z1 -- z11;
drawarrow z1 -- z3;
\epr
solid lines for the time lines:
\bpr
draw z1 -- z3;
draw z4 -- z7;
draw z8 -- z10;
\epr
and dashed lines for the light rays:
\bpr
draw z5 -- z2 dashed evenly;
draw z2 -- z6 dashed evenly;
draw z5 -- z9 dashed evenly;
draw z9 -- z6 dashed evenly;
\epr
These commands have drawn into \ikw{currentpicture}. We store them in the picture variable \kw{pic} and clear the current picture using the internal constant \ikw{nullpicture}:
\bpr
picture pic;
pic := currentpicture;
currentpicture := nullpicture;
\epr
We next draw \kw{p} twice, once as above, and once transformed:
\bpr
draw pic;
draw pic transformed t;
\epr
We then label the original diagram:
\begin{verbatim}
label.llft(btex $O$ etex, z1);
label.rt(btex $X$ etex, z11);
label.top(btex $T$ etex, z3);
label.rt(btex $a$ etex, z5);
label.lft(btex $b$ etex, z2);
label.rt(btex $b'$ etex, z9);
label.rt(btex $c$ etex, z6);
\end{verbatim}
and the transformed diagram:
\begin{verbatim}
label.llft(btex $O$ etex, z1 transformed t);
label.rt(btex $X$ etex, z11 transformed t);
label.top(btex $T$ etex, z3 transformed t);
label.rt(btex $a$ etex, z5 transformed t);
label.lft(btex $b$ etex, z2 transformed t);
label.rt(btex $b'$ etex, z9 transformed t);
label.rt(btex $c$ etex, z6 transformed t);
\end{verbatim}
The result is \xf{fig-lor}. Note that the events $b$ and $b'$ are simultaneous in the original diagram but not in the transformed diagram, and that the light rays (dashed lines) have the same slope ($\pm1$) in both diagrams.
This example would be slightly simpler if we included the labels in the first diagram. Then we would not have to write them out twice. Since \mp\ transforms \emph{everything}, however, the labels would be distorted.
\subsection{Dissipation}\label{sec:ex-bc}
\xf{fig-diss} shows how the area between two trajectories of a dissipative system diminishes when measured at constant time intervals. The code for drawing it uses \kw{point\ldots of}\idc{point} to obtain points on the upper and lower curves, and \ikw{buildcycle} to construct the areas for shading.
\mpfig{hbtp}{45}{Area reduction in a dissipative system}{fig-diss}
Pick four points as end points for the curves:
\bpr
z1 = (0,100); z2 = (160,0);
z3 = (0,60); z4 = (150,0);
\epr
Draw two curves, converging towards each other:
\begin{verbatim}
path p[];
p1 = z1{dir 0} .. {dir 270}z2;
p2 = z3{dir 0} .. {dir 270}z4;
\end{verbatim}
Construct pairs of lines joining corresponding points on the curves. The lines are not drawn, but are used as arguments of \kw{buildcycle} to create closed areas, which are shaded with \kw{filldraw}.
\bpr
for i = 0 step 2 until 11:
\- p3 := point i/11 of p1 -- point i/11 of p2;
\- p4 := point (i+1)/11 of p1 -- point (i+1)/11 of p2;
\- filldraw buildcycle(p3, p1, p4, p2) withcolor 0.7 white;
endfor;
\epr
Finally draw the curves \kw{p1} and \kw{p2}, and a couple of lines, to bound the figure.
\bpr
draw p1; draw p2;
draw z1 -- z3; draw z2 -- z4;
\epr
\subsection{Sunflower}
\xf{fig-sunflower} shows a pattern of dots arranged in the way that \idx{sunflower florets} develop. The model for sunflower development was proposed in 1979 by H.~Vogel\footnote{\url{http://en.wikipedia.org/wiki/Fibonacci_numbers}}. The position of the $n$th floret is given in polar coordinates by
$$ r = k \sqrt{n} , \quad \theta = \frac{2\pi}{\phi^2} \, n $$
where $k$ determines the scale and $\phi = \frac{1}{2} (1 + \sqrt{5}) $ is the Golden Ratio.
\mpfig{hbtp}{87}{Position of florets in the head of a sunflower}{fig-sunflower}
Programming \idx{Vogel's formula} in \mp\ is straightforward but for one small problem. Since \mp\ uses degrees, we actually need $ \theta = \frac{360\dg}{\phi^2}$ and, as $n$ gets large, the numerical values exceed \mp's limit of 4096. Consequently, we compute $\theta$ using ``whole turns'' (multiples of~$360\dg$) as the unit, and use \verb'mod 1' to bring the result into the interval $[0,1)$. We can then safely multiply this value by 360 to obtain the desired angle.
\begin{verbatim}
phisq = (0.5 * (1 + sqrt(5))) * (0.5 * (1 + sqrt(5)));
for n = 1 upto 1000:
r := 3 * sqrt(n);
theta := (n / phisq) mod 1;
filldraw fullcircle
shifted (r * cosd(360*theta), r * sind(360*theta));
endfor;
\end{verbatim}
\subsection{The Hanging Chain}\label{sec:ex-chain}
\xf{fig:chain}(a) is intended to accompany an explanation of the forces that determine the shape of a \idx{hanging chain}. The chain itself is shown as a heavy curve with forces $T$ and $T+\Delta T$ acting in the direction of the tangents at each end. The angle between the chain and the horizon is $\theta$ at the lower end and $\theta+\Delta\theta$ at the upper end. The mass of the chain, $\rho g \Delta s$, pulls downwards at the centre of the segment.
\xf{fig:chain-code} shows the \mp\ code for the hanging chain diagram. \xf{fig:chain}(b) shows the relative locations of the eight reference points, \kw{z0}, \ldots, \kw{z7}, used in its construction.
\begin{figure}[hbtp]
\hrule\bigskip
$$ \begin{tabular}{c @{\qquad} c}
\includegraphics{figs-88} & \includegraphics{figs-89} \\
(a) & (b)
\end{tabular} $$
\caption{The Hanging Chain: (a) diagram; (b) reference points.}
\label{fig:chain}
\medskip\hrule
\end{figure}
\begin{figure}[hbtp]
\hrule\medskip
\begin{verbatim}
numeric a[]; a1 = 30; a2 = 50; a3 = 70;
z0 = origin; label.llft(btex $T$ etex, z0);
z1 = z0 + 50 dir a1; label(btex $\theta$ etex, z1 + (20,5));
z3 = z1 + 150 dir a2; label(btex $\theta+\Delta\theta$ etex, z3 + (20,5));
path c; c = z1{dir a1} .. {dir a3}z3;
drawoptions(withpen pencircle scaled 2bp); draw c; drawoptions();
z2 = point 0.5 of c;
z4 = z3 + 50 dir a3; label.urt(btex $T+\Delta T$ etex, z4);
z5 = (xpart z3, ypart z1); z6 = z3 + (30,0);
z7 = z2 - (0,30); label.bot(btex $\rho g \Delta s$ etex, z7);
drawarrow z1--z0; drawarrow z3--z4; drawarrow z2--z7;
draw z3--z6 dashed evenly;
draw z1--z3--z5--cycle;
label.bot(btex $\Delta x$ etex, 0.5[z1,z5]);
label.rt(btex $\Delta y$ etex, 0.5[z3,z5]);
label.ulft(btex $\Delta s$ etex, 0.5[z1,z3]);
\end{verbatim}
\caption{Programming the Hanging Chain}
\label{fig:chain-code}
\medskip\hrule
\end{figure}
\subsection{Histogram}
The \mp\ \kw{graph} package provides facilities for drawing histograms. \xf{fig-hist-marks} shows a customized histogram.
\mpfig{hbtp}{85}{Histogram of Marks}{fig-hist-marks}
We begin by defining a macro to draw a bar of the histogram. The bottom left corner is at $(x,y)$ and the bar has width $w$ and height $h$.
\begin{verbatim}
def shadedbox(expr x, y, w, h) =
path p;
p = (x,y) -- (x,y+h) -- (x+w,y+h) -- (x+w,y) -- cycle;
fill p withcolor blue;
enddef;
\end{verbatim}
Next, we introduce the figure and save some temporary variables.
\begin{verbatim}
beginfig(1);
save maxfreq, freqscale, height, colnum, colmarks, colwidth, width;
\end{verbatim}
The idea is to introduce as few independent variables as possible and to compute the others from then. We need:
the largest frequency, \kw{maxfreq};
the scale for frequencies (points per occurrence), \kw{freqscale};
the number of columns, \kw{numcol};
and the width of a column, \kw{colwidth}.
\begin{verbatim}
maxfreq = 15;
freqscale = 12;
height = maxfreq * freqscale + 10;
colnum = 20;
colmarks = 100 / colnum;
colwidth = 15;
width = colnum * colwidth + 10;
\end{verbatim}
Draw the vertical axis and its scale:
\begin{verbatim}
draw (0,0) -- (0,height);
for n = 0 upto maxfreq:
label.lft(decimal n, (0, freqscale*n));
endfor;
\end{verbatim}
Draw the horizontal axis and its scale:
\begin{verbatim}
draw (0,0) -- (width,0);
for n = 0 upto colnum:
label.bot(decimal(colmarks * n), (colwidth * n, 0));
endfor;
\end{verbatim}
Draw the histogram bars:
\begin{verbatim}
x := 0;
for h = 0,0,0,0,0,0,0,0,1,1,2,4,6,9,5,10,15,6,3,0:
shadedbox(x, 1, colwidth - 2, freqscale * h);
x := x + colwidth;
endfor;
\end{verbatim}
Show the average:
\begin{verbatim}
avg = 3 * 73.2;
z0 = (avg, height);
draw (avg,0) -- z0 withcolor green;
label.top(btex Average = 73.2 etex, z0);
endfig;
\end{verbatim}
\subsection{Desargues' Theorem}
\xf{fig-des-pic} is obtained by the following construction.
\begin{itemize}
\item Choose a centre of projection, $O$.
\item Draw a triangle, $A_1 B_1 C_1$.
\item Draw the lines $O A_1$, $O A_2$, and $O A_3$.
\item Draw another triangle, $A_2 B_2 C_2$, with the same centre of projection. That is $A_2$ lies on $O A_1$, etc.
In \mp, this step is done by mediation. E.g., \kw{a2 = 0.35[a1,o]}.
\item Find the points of intersection of corresponding sides of the triangles. For example, $B_1 C_1$ and $B_2 C_2$ intersect at $P_1$.
In \mp, this step is also done by mediation. E.g.:
\bpr p1 = whatever[b1,c1] = whatever[b2,c2]; \epr
\item Desargues' Theorem states that the three points of intersection, $P_1$, $P_2$, and $P_3$, are collinear.
\end{itemize}
\xf{fig-des-code} shows the \mp\ code used the draw \xf{fig-des-pic}. The label commands have been put at the end to ensure that the black dots are drawn after the coloured lines that go through them.
\mpfig{hbtp}{76}{Desargue's Theorem}{fig-des-pic}
\begin{figure}
\hrule\vskip6pt
\begin{verbatim}
pair a[],b[],c[],p[], o;
o = (300,0);
a1 = (0,0); b1 = (60,135); c1 = (95,20);
draw a1 -- b1 -- c1 -- cycle withcolor red;
draw a1 -- o withcolor blue;
draw b1 -- o withcolor blue;
draw c1 -- o withcolor blue;
a2 = 0.35[a1,o]; b2 = 0.2[b1,o]; c2 = 0.5[c1,o];
draw a2 -- b2 -- c2 -- cycle withcolor green;
p1 = whatever[b1,c1] = whatever[b2,c2];
p2 = whatever[c1,a1] = whatever[c2,a2];
p3 = whatever[a1,b1] = whatever[a2,b2];
draw b1 -- p1 -- b2;
draw a1 -- p2 -- a2;
draw b1 -- p3 -- b2;
draw p1 -- p2 -- p3 dashed evenly;
dotlabel.rt(btex $O$ etex, o);
dotlabel.ulft(btex $A_1$ etex, a1);
dotlabel.lft(btex $B_1$ etex, b1);
dotlabel.bot(btex $C_1$ etex, c1);
dotlabel.bot(btex $A_2$ etex, a2);
dotlabel.llft(btex $B_2$ etex, b2);
dotlabel.urt(btex $C_2$ etex, c2);
dotlabel.lft(btex $P_1$ etex, p1);
dotlabel.bot(btex $P_2$ etex, p2);
dotlabel.top(btex $P_3$ etex, p3);
\end{verbatim}
\caption{Programming Desargues' Theorem}
\label{fig-des-code}
\vskip6pt\hrule
\end{figure}
\subsection{Cobweb Plots}
Cobweb plots are used to illustrate the behaviour of dynamic systems. \xf{fig-cobweb} shows the result of computing 100 iterations of $x \to kx(1-x)$. \xf{fig-cobweb-code} shows the code used to create the diagram. The main points of interest is that the first \kw{for} loop computes two points at each iteration, and that it is simpler to separate the computation of points from their display in the second \kw{for} loop.
\mpfig{hbtp}{80}{Cobweb plot for the logistic map}{fig-cobweb}
\begin{figure}
\hrule\vskip6pt
\begin{verbatim}
save scale, k, seed, xmax;
scale = 200; k = 3.70; seed = 0.3; iters = 100;
label.rt(btex $k=3.70$ (chaos) etex, (10, scale));
draw (0,0) -- (scale,0);
draw (0,0) -- (0,scale);
draw (0,0) -- (scale, scale);
draw (0,0) for x := 0.0 step 1/iters until 1.0:
.. (scale * x, scale * k * x * (1-x))
endfor;
x0 = seed; y0 = 0;
for i := 1 step 2 until iters:
x[i] := x[i-1];
y[i] := k * x[i] * (1 - x[i]);
y[i+1] := y[i];
x[i+1] := y[i+1];
endfor;
draw scale * z0
for i := 1 upto iters: -- scale * z[i]
endfor;
\end{verbatim}
\caption{Coding the cobweb plot in \xf{fig-cobweb}}
\label{fig-cobweb-code}
\vskip6pt\hrule
\end{figure}
\subsection{Three Dimensions}\index{3D}\index{three dimensions}
Although \mp\ is basically two-dimensional, it can be tricked into drawing perspective diagrams, giving the illusion of three dimensions. Many packages have been written for 3D \mp\ pictures \xs{sec:links}. One technique is to use the three components of the type \ikw{color} as $XYZ$ coordinates. We give a simple example to illustrate the idea.
Assume that the viewpoint in 3D space is at $(0,0,-d)$ and that we project onto the plane $z=0$. This projection maps the 3D point $(x,y,z)$ to the 2D point $(tx, ty)$ where $t=d/(z+d)$. The macro \kw{perspective} implements this transformation by converting a colour $\kw{c}=(r,g,b)$ to a pair $(tr,tg)$:
\bpr
vardef perspective(expr c) =
\- t := dist/(bluepart c + dist);
\- (t * redpart c, t * greenpart c)
enddef;
\epr
We use the colour array \kw{tp[]} to represent the vertexes of a cube with side 2 centered at the origin:
\bpr
color tp[];
tp0 = (-1,-1,-1); tp4 = tp0 + (0,0,2);
tp1 = ( 1,-1,-1); tp5 = tp1 + (0,0,2);
tp2 = ( 1, 1,-1); tp6 = tp2 + (0,0,2);
tp3 = (-1, 1,-1); tp7 = tp3 + (0,0,2);
\epr
Since \mp\ supports linear operations on colours, we can scale and translate the cube before using \kw{perspective} with $\kw{dist}=200$ to transform the vertexes to the pair array \kw{p[]}:
\bpr
dist := 200;
pair p[];
for i = 0 upto 7:
\- p[i] := perspective(40*tp[i]+(80,-70,30));
endfor;
\epr
Drawing the edges of the cube gives \xf{fig:cube}:
\bpr
draw p0--p1--p2--p3--cycle;
draw p4--p5--p6--p7--cycle;
draw p0--p4;
draw p1--p5;
draw p2--p6;
draw p3--p7;
\epr
\mpfig{hbtp}{71}{Perspective view of a cube}{fig:cube}
\subsection{Reading a File}\label{sec:readfile}\index{read file}\index{file!read}
This example illustrates the use of \ikw{readfrom} and \ikw{scantokens}. Suppose that the file \kw{"data.txt"} contains these two lines:
\begin{verbatim}
1, 2, x, "Go!"
"pi = ", 3.14159263
\end{verbatim}
The code on the left produces the figure on the right:
\bep{100mm}
boxjoin(a.sw = b.nw; a.se = b.ne);
picture b[];
i = 0;
x = 99;
forever:
\- string line;
\- line := readfrom "data.txt";
\- exitif line = EOF;
\- string token, desc;
\- for token = scantokens line:
\-\- if numeric token:
\-\-\- desc := "Numeric: " \&
\-\-\-\- decimal token;
\-\- elseif string token:
\-\-\- desc := "String: " \& token;
\-\- fi;
\-\- boxit.b[i](desc);
\-\- b[i].e = b[i].w + (100,0);
\-\- drawboxed(b[i]);
\-\- i := i + 1;
\- endfor;
endfor;
\eep{0mm}{72}
The outer \ikw{forever} loop reads each line of the file, checking for end of file. The inner \ikw{for} loop uses \kw{scantokens} to split the line into tokens. The type of each token is checked, using type names as predicates, and put into a descriptor, \kw{desc}. Finally, each descriptor is drawn in a box.
Note that the third token in the file is \kw{x} and it is displayed as \kw{99}, the value of \kw{x} in the program. Tokens in a file are considered to be strings only if they are quoted, like \kw{"Go!"}.
\section{Links}\label{sec:links}
John Hobby's \mp\ page:
\url{http://cm.bell-labs.com/who//hobby/MetaPost.html}
The \TeX\ User's Group --- probably all that you will need:
\url{http://www.tug.org/metapost.html}
A FAQ from the UK:
\url{http://www.tex.ac.uk/cgi-bin/texfaq2html?label=MP}
Urs Oswald's \emph{Very Brief Tutorial}:
\url{http://www.ursoswald.ch/metapost/tutorial.html}
Marc van Dongen's contributions to \mp:
\url{http://www.cs.ucc.ie/~dongen/mpost/mpost.html}
\textsf{MetaFun} by Hans Hagen:
\url{http://wiki.contextgarden.net/MetaFun}
A WYSIWYG interface for
\mp: \url{http://w3.mecanica.upm.es/metapost/metagraf.php}
A \mp\ generator for 3D:
\url{http://www.gnu.org/software/3dldf/LDF.html}
\clearpage
\addcontentsline{toc}{section}{Index}
\printindex
\end{document}