%%%
%%%  File: mf-revu.tex
%%%
%%%  mfpic 0.2.10.1 alfa  Thu 18 Jan 1996
%%%

\magnification=\magstep1

% heading macros
\newskip\myskip\myskip=10pt plus 1pt
\def\doskip{\vskip\myskip}
\long\def\head#1{\doskip\noindent $\bullet$ {\it #1} \par\doskip\nobreak}
\long\def\subhead#1{\doskip {\sl #1} \par\doskip\nobreak}

% abbreviations
\def\LaTeX{{\rm L\raise.42ex\hbox{\kern-.3em a}\kern-.15em\TeX}}
\font\manual=logo10 % may want to use manfnt here instead
\def\MF{{\manual META}\-{\manual FONT}}
\def\PS{{\rm Post}\-{\rm Script}}
\def\texmacro#1{{\tt\char\escapechar #1}}

% verbatim text -- extracted from The TeXbook, pages 380--381.
\def\verbatim{\tt
  \def\par{\leavevmode\endgraf}
  \obeylines \obeyspaces}
{\obeyspaces\global\let =\ }


\centerline{\bf A Review of \MF{} Programming}
\centerline{Geoffrey Tobin ({\tt G.Tobin@latrobe.edu.au}) Thu 18 Jan 1996}

The best reference for \MF{} programming is undoubtedly Professor
Donald E.~Knuth's {\it The \MF{}book}, first published by
Addison-Wesley and copyrighted by the American Mathematical Society
in 1986, ISBN 0-201-13445-4.

However, this document gives reminders of some facets of \MF{}.

\head{Types}

\MF{} has nine ($9$) types of expression:  {\tt boolean}, {\tt numeric},
{\tt pair}, {\tt path}, {\tt pen}, {\tt picture}, {\tt string},
{\tt transform}, and {\it vacuous}.  The first eight ($8$) are
{\it named} types; their names can be used to declare variables (for
example, {\tt string surname;}), or to test the type of a variable or
expression (as in {\tt message "x is " \& if pair x: "indeed" else:
"not" fi \& " a pair";}).  Every undeclared \MF{} variable is
{\tt numeric}.

Statements can be treated as expressions of the {\it vacuous} type.
Expressions of {\tt boolean} type are either {\tt true} or {\tt false},
whereas {\it vacuous} expressions have only one possible value.
The allowed values of all the types, and the range of expressions
available in \MF{}, are described in {\it The \MF{}book}.

\head{Groups}

A {\it group} is an {\it compound} expression of the form
{\tt begingroup A; B; C; D endgroup} which may contain several
statements; its value is that of its last expression, so
{\tt begingroup message "hello"; 123.45 endgroup}
has the value of $123.45$, which is {\tt numeric}.
If the group is empty, or if its last item is a semicolon,
then the group has the {\it vacuous} type.

\head{Macros}

{\it Macros} are the \MF{} equivalent of functions and procedures.
There are two broad classes of macro:  untyped ({\tt def}) and typed
({\tt vardef}).  Typed macros are permitted to have the {\it vacuous}
type: an example is {\tt vardef fred = message "I am called Fred";
enddef;}\ .  In fact, {\tt vardef A = B enddef;} is effectively a
shorthand for {\tt def A = begingroup B endgroup enddef;}\ .

\head{Numerics}

\subhead{\MF{} Numeric Operations}

The arithmetic operators {\tt +}, {\tt -}, {\tt *}, {\tt /} are
primitives in \MF{}.  So are Pythagorean addition ({\tt ++}) and
subtraction ({\tt +-+}):  $x ++ y = \sqrt {x^2 + y^2}$ and
$x +-+ y = \sqrt {x^2 - y^2}$.

Plain \MF{} defines exponentiation ({\tt **}), remainder ({\tt mod})
and integer division ({\tt div}).

\subhead{\MF{} Numeric Relations}

Numeric expressions can be compared:  relations include equality,
({\tt =}), and inequalities ({\tt <>}, {\tt >}, {\tt <}, {\tt >=},
{\tt <=}).

\subhead{\MF{} Numeric Functions}

\MF{} has some useful {\tt numeric} functions built-in.  These
include:  length, sqrt, sind, cosd, mlog, mexp, floor, angle,
uniformdeviate, normaldeviate.

{\bf length $x$} is the absolute value of $x$.

{\bf sqrt $x$} is the square root of $x$.

{\bf sind $x$} is the sine of $x$ degrees.

{\bf cosd $x$} is the cosine of $x$ degrees.

{\bf angle $(x, y)$} is the arctangent of $y/x$.

{\bf mlog $x$} is $256 \hbox{\tt ln} x$, where {\tt ln} is the
logarithm to the base $e$.

{\bf mexp $x$} is $e^{x/256}$.

{\bf floor $x$} is the largest integer less than or equal to $x$.

{\bf uniformdeviate $x$} is a uniformly distributed random number
between $0$ and $x$.

{\bf normaldeviate} is a normally distributed random number with mean
$0$ and standard deviation $1$.

The random number generators can be restarted at a given stage by
assigning a {\tt numeric} value to the primitive internal variable
{\bf randomseed}.

Plain \MF{} defines {\bf ceiling}, {\bf abs} (same as {\bf length}),
{\bf round}, {\bf min} and {\bf max}, among other functions.

\head{Pairs}

Subsequently, we often speak of {\it points} in the graphical sense.
These are represented in \MF{} by values of type {\tt pair}.
Constants of type {\tt pair} have the form $(x, y)$,
where $x$ and $y$ are both {\tt numeric} constants.
A variable $p$ of type {\tt pair} is equal to the
{\tt pair} expression ({\tt xpart} $p$, {\tt ypart} $p$).

\head{Paths}

A {\tt path} represents a type of continuous curve called a
{\bf B\'ezier}, which is comprised of a chain of {\bf segments}.
Each segment has a shape determined by four {\bf control points}.
Two of the control points, the {\it key} points, are the segment's
endpoints; often we let \MF{} determine the other two, as in the
{\tt path} expression $p_1..p_2..p_3$, which has two segments,
from $p_1$ to $p_2$, and from $p_2$ to $p_3$.

\head{Pens}

Pens are a distinctive feature of \MF{}, whereby quite refined
figures can be drawn.  Pens are filled convex shapes that
are moved along {\tt path}s, to alter {\tt picture} pixel values in
often complicated ways.

Two pens are initially present in MF{}, {\tt nullpen} and
{\tt pencircle}.  Since {\tt nullpen} is the single point $(0,0)$,
which contains no pixels, it cannot be seen, so it can be used
for filling a region without fuzzing its boundary.  By contrast,
{\tt pencircle} is circular, with the points $(\pm0.5, 0)$ and
$(0, \pm0.5)$ on its circumference.

Other pens are constructed as convex polygons via {\tt makepen $c$},
where $c$ is a closed {\tt path}; the key points of $c$ become the
vertices of the pen.

Now, {\tt pencircle} and {\tt makepen $c$} are called {\it future}
pens.  They are continuous, whereas pictures are discrete, so pens,
like pairs and paths, must be {\it rendered} discrete before being
applied to a picture.

By contrast, {\tt nullpen}, all {\tt pen} variables, and any
pen expression in parentheses, are already {\it discrete} pens.

{\it Future} pens can be transformed by scaling, translating, and so
on, just as pairs and paths can; but {\it discrete} pens cannot.
An example of an elliptical future pen is {\tt pencircle xscaled 30
yscaled 20}, the discrete pen for which is illustrated on page 148 of
{\it The \MF{}book}.

\head{Pictures}

\MF {\tt picture}s contain pixels arranged as a regular grid of
squares.  One of the pixels has as its boundary the {\it unit square},
which is the {\tt path} $(0,0)--(0,1)--(1,1)-(1,0)--cycle$.  Pictures
are built up from the {\tt nullpicture}, which has all pixels zero
($0$), using {\tt addto}, and their pixels are trimmed using
{\tt cull}.

Picture variables can be assigned:  $v := W;$  where $v$ is a
{\tt picture} variable, and $W$ is a {\tt picture} expression
such as $u + w$, $u - w$, $+u$, $-u$, or combinations of these.
Picture $v$ can have picture $w$ added to it by
{\tt addto $v$ also $w$}, which {\it The MF{}book, page 118} explains
is faster and uses less memory than {\tt $v := v + w$} but is
otherwise the same.

The meaning of $v + w$, for example, is a picture in which each pixel
is the sum of the two pixels that occupy the same position in pictures
$v$ and $w$ respectively.  The effects on pixel values of filling and
drawing are much less predictable, and depend greatly on which
{\tt pen} is used.

Filling a {\it closed} path $c$ in a picture $v$ uses
{\tt addto $v$ contour $c$ {\it <with list>}},

Drawing the outline of a path $f$ uses
{\tt addto $v$ doublepath $c$ {\it <with list>}}.
A {\it <with list>} can be empty, or it can be one or both of the
phrases {\tt withpen {\it <pen expression>}}
and {\tt withweight {\it <numeric expression>}}.
By choosing different pens, drawing is refined, as in calligraphy.
Weights are weighting factors for pixels.

To change all pixels in {\tt picture} variable $v$ that have values
between $2$ and $4$ (inclusive) into $-5$, and all other pixels to
zero, use:
{\tt cull $v$ keeping $(2,4)$ withweight $-5$}.
To zero all pixels with values between $-3$ and $1$ (inclusive),
and to change all other pixels into $2$, use:
{\tt cull $v$ dropping $(-3,1)$ withweight $2$},
If the {\tt withweight} phrase is omitted, then the surviving
pixels have value one ($1$).
{\it Beware} of attempting to change zero-valued pixels to nonzero,
as zero-valued pixels extend to infinity in all directions.

\head{Transforms}

Affine transforms are the natural transformations of Euclidean
geometry:  the linear transformations augmented by translation.
In two dimensions, transforms are completely specified by their
action on three non-collinear points in the plane.  If $T$ is
a {\tt transform}, and $p$ is a pair, then $T$ maps $p$ onto this
{\tt pair}:  $p$ {\tt transformed} $T$.  Thus \MF{} can construct
any affine transform:  for example, plain \MF{} defines the
{\bf identity} transform.  Plain \MF{} also defines a macro named
{\bf inverse} such that
{\bf inverse $T$ transformed $T$ $=$ identity}.

Each transform $T$ has six components, and can be expressed as a
linear transformation followed by a translation.  The translation
components of $T$ are {\tt xpart $T$} and {\tt ypart $T$}, and
the four linear components are {\tt xxpart $T$}, {\tt xypart $T$},
{\tt yxpart $T$} and {\tt yypart $T$}.  Employing the obvious
notation, $T$ is applied as:

$$
   \left(
     \matrix{t_x \cr t_y}
     \left|
       \vphantom{\matrix{t_xy \cr t_yy}}
     \right.
     \matrix{ t_{xx} & t_{yx} \cr t_{xy} & t_{yy}}
   \right)
   \pmatrix{x \cr y}
   =
   \pmatrix{t_x + t_{xx} x + t_{xy} y \cr
            t_y + t_{yx} x + t_{yy} y}
$$

\MF{} also provides seven primitive transforms, listed on page
141 of {\it The \MF{}book}:

\halign
{\indent#\hfil&\quad#\hfil\cr
$(x,y)$ {\tt shifted} $(a,b)$   & $ = (x+a, y+b) $  \cr
$(x,y)$ {\tt scaled}  $s$       & $ = s (x, y) $   \cr
$(x,y)$ {\tt xscaled} $s$       & $ = (sx, y) $    \cr
$(x,y)$ {\tt yscaled} $s$       & $ = (x, sy) $    \cr
$(x,y)$ {\tt slanted} $s$       & $ = (x,y) + s (y, 0) $   \cr
$(x,y)$ {\tt rotated} $\theta$  & $ = (x \cos \theta - y \sin \theta,
                                 x \sin \theta + y \cos \theta) $ \cr
$(x,y)$ {\tt zscaled} $(u,v)$   & $ = (xu - yv, xv + yu) $ \cr
}

These operations are taught in secondary school mathematics;
for example, {\tt slanted} is skewing parallel to the X axis.
Interpreting a pair as a complex number in Cartesian coordinates,
{\tt zscaled} is complex multiplication.

\head{Composite Variables}

\MF{} allows {\it composite} variables --- homogeneous {\it arrays},
heterogeneous {\it suffixes}, and arbitrary combinations of those.
One can declare composite variables, and test whether they
{\it contain} a given structure.  However, these are not fully-fledged
types, since every expression has one of the nine {\it simple} types.
For example, after declaring {\tt path p[];} of what type is {\tt p} ?
It's {\tt numeric}!

Moreover, \MF{} {\it lacks} pointers.  It is not possible for a macro
to return a value that has not one of the nine {\it simple} types.
The allowed syntax {\tt vardef b[] = $\cdots$ enddef;} may suggest
that this macro returns an array, but in fact {\tt b[3]} {\it expands}
to the whole {\it replacement text} of the macro.

Here is a macro that is useful for testing the type of a variable,
suffix or expression:

{
\verbatim
    def type suffix x =
      message str x \& " is "
        \&
        if     known x:     "a known "
        else:               "an unknown "
        fi
        \&
        if     boolean x:   "boolean"
        elseif numeric x:   "numeric"
        elseif pair x:      "pair"
        elseif path x:      "path"
        elseif pen x:       "pen"
        elseif picture x:   "picture"
        elseif string x:    "string"
        elseif transform x: "transform"
        else:               "vacuous"
        fi;
      enddef;
  
}

\bye

%%%
%%%  EOF
%%%
