metafun-basics.tex /size: 116 Kb    last modification: 2023-12-21 09:43
1% language=us runpath=texruns:manuals/metafun
2
3\startcomponent metafun-basics
4
5\environment metafun-environment
6
7\startchapter[title={A few more details}]
8
9\startintro
10
11In this chapter we will see how to define a \METAPOST\ graphic, and how to
12include it in a document. Since the exact dimensions of graphics play an
13important role in the placement of a graphic, we will explore the way a bounding
14box is constructed.
15
16We will also pay attention to the usage of units and the side effects of scaling
17and shifting, since they can contradict our expectations in unexpected ways.
18Furthermore we will explore a few obscure areas.
19
20\stopintro
21
22\startsection[title={Making graphics}]
23
24\index{graphics}
25
26In this manual we will use \METAPOST\ in a rather straightforward way, and we
27will try to avoid complicated math as much as possible. We will do a bit of
28drawing, clipping, and moving around. Occasionally we will see some more
29complicated manipulations.
30
31When defined as stand||alone graphic, a \METAPOST\ file looks like this:
32
33\starttyping
34% Let's draw a circle.
35
36beginfig (7) ;
37  draw fullcircle scaled 3cm withpen pencircle scaled 1cm ;
38endfig ;
39
40end .
41\stoptyping
42
43The main structuring components in such a file are the \type {beginfig} and \type
44{endfig} macros. Like in a big story, the file has many sub||sentences, where
45each sub||sentence ends with a semi||colon. Although the \type {end} command at
46the end of the file concludes the story, putting a period there is a finishing
47touch. Actually, after the \type {end} command you can put whatever text you
48wish, your comments, your grocery list, whatever. Comments in \METAPOST, prefixed
49by a percent sign, as in \typ {% Let's draw a circle}, are ignored by the
50interpreter, but useful reminders for the programmer.
51
52Traditionally, if the file is saved as \type {yourfile.mp}, then the file is
53processed by \METAPOST\ by issuing the following command:
54
55\starttyping
56mpost yourfile
57\stoptyping
58
59after which you will have a graphic called \type {yourfile.7}, which contains a
60series of \POSTSCRIPT\ commands. Because \METAPOST\ does all the work, this file
61is efficient and compact. The number of distinct \POSTSCRIPT\ operators used is
62limited, which has the advantage that we can postprocess this file rather easily.
63Alternatively \METAPOST\ can generate \SVG\ output. It does when you say
64
65\starttyping
66outputformat := "svg" ;
67\stoptyping
68
69Here we will not go into details about this format. Even \POSTSCRIPT\ is not
70covered in detail as we use \METAPOST\ mostly in embedded form.
71
72We can view this file in a \POSTSCRIPT\ viewer like \GHOSTVIEW\ or convert the
73graphic to \PDF\ (using \type {mptopdf}) and view the result in a suitable \PDF\
74viewer like \ACROBAT. Of course, you can embed such a file in a \CONTEXT\
75document, using a command like:
76
77\starttyping
78\externalfigure[yourfile.7]
79\stoptyping
80
81We will go in more detail about embedding graphics in \in {chapter}
82[sec:embedding].
83
84If you have installed \CONTEXT, somewhere on your system there resides a file
85\type {mp-tool.mp}. If you make a stand||alone graphic, it's best to put the
86following line at the top of your file:
87
88\starttyping
89input metafun ;
90\stoptyping
91
92By loading this file, the resulting graphic will provide a high resolution
93bounding box, which enables more accurate placement. The file also sets the \typ
94{prologues := 1} so that viewers like \GHOSTVIEW\ can refresh the file when it is
95changed.
96
97{\bf However!} When you use \METAPOST\ in \CONTEXT, you will not run the
98mentioned program at all: you embed your graphic in the document and we will
99discuss this later. You can still use separate files but then you process them as
100follows:
101
102\starttyping
103mtxrun --script metapost somefile.mp
104\stoptyping
105
106Alternatively you can wrap the individual pictures in a \TEX\ file, say \type
107{yourfile.tex}:
108
109\starttyping
110\starttext
111    \startMPpage
112        % code
113    \stopMPpage
114    \startMPpage
115        % code
116    \stopMPpage
117\stoptext
118\stoptyping
119
120and then run:
121
122\starttyping
123context somefile.tex
124\stoptyping
125
126after which you can use the resulting \PDF\ file (if it has more pages you just
127filter the page from that file).
128
129Next we will introduce some more \METAPOST\ commands. From now on, we will omit
130the encapsulating \type {beginfig} and \type {endfig} macros. If you want to
131process these examples yourself, you should add those commands yourself, or if
132you use \CONTEXT\ you don't need them at all. You can for instance wrap them in a
133\type {\startMPpage} \unknown\ \type {\stopMPpage} environment if you want to
134play around.
135
136\startbuffer
137pickup pencircle scaled .5cm ;
138draw unitsquare xscaled 8cm yscaled 1cm withcolor .625white ;
139draw origin withcolor .625yellow ;
140pickup pencircle scaled 1pt ;
141draw bbox currentpicture withcolor .625red ;
142\stopbuffer
143
144\typebuffer
145
146In this example we see a mixture of so called primitives as well as macros. A
147primitive is something hard coded, a built||in command, while a macro is a
148collection of such primitives, packaged in a way that they can be recalled
149easily. Where \type {scaled} is a primitive and \type {draw} a macro, \type
150{unitsquare} is a path variable, an abbreviation for:
151
152\starttyping
153unitsquare = (0,0) -- (1,0) -- (1,1) -- (0,1) -- cycle ;
154\stoptyping
155
156The double dash (\type {--}) is also a macro, used to connect two points with a
157straight line segment. However, \type {cycle} is a primitive, which connects the
158last point of the unitsquare to the first on unitsquare's path. Path variables
159must first be declared, as in:
160
161\starttyping
162path unitsquare ;
163\stoptyping
164
165A large collection of such macros is available when you launch \METAPOST. Consult
166the \METAPOST\ manual for details.
167
168\startlinecorrection[blank]
169\processMPbuffer
170\stoplinecorrection
171
172In the first line of our example, we set the drawing pen to \type {.5cm}. You can
173also specify such a dimension in other units, like points (\type {pt}). When no
174unit is provided, \METAPOST\ will use a big point (\type {bp}) , the \POSTSCRIPT\
175approximation of a point.
176
177The second line does just as it says: it draws a rectangle of certain dimensions
178in a certain color. In the third line we draw a colored dot at the origin of the
179coordinate system in which we are drawing. Finally, we set up a smaller pen and
180draw the bounding box of the current picture, using the variable \type
181{currentpicture}. Normally, all drawn shapes end up in this picture variable.
182
183\stopsection
184
185\startsection[title={Bounding boxes}]
186
187\index{boundingbox}
188
189If you take a close look at the last picture in the previous section, you will
190notice that the bounding box is larger than the picture. This is one of the nasty
191side effects of \METAPOST's \type {bbox} macro. This macro draws a box, but with
192a certain offset. The next example shows how we can manipulate this offset.
193Personally I never use the \type {bbox} macro because this offset is rather
194annoying. Also, the \type {boundingbox} operator combined with \type {enlarged}
195can provide any offset you want.
196
197\startbuffer
198pickup pencircle scaled .5cm ;
199draw unitsquare xscaled 8cm yscaled 1cm withcolor .625white ;
200path bb ; bboxmargin := 0pt ; bb := bbox currentpicture ;
201draw bb withpen pencircle scaled 1pt withcolor .625red ;
202draw origin withpen pencircle scaled 5pt withcolor .625yellow ;
203\stopbuffer
204
205\typebuffer
206
207In the third line we define a path variable. We assign the current bounding box
208to this variable, but first we set the offset to zero. The last line demonstrates
209how to draw such a path. Instead of setting the pen as we did in the first line,
210we pass the dimensions directly.
211
212\startlinecorrection[blank]
213\processMPbuffer
214\stoplinecorrection
215
216Where \type {draw} draws a path, the \type {fill} macro fills one. In order to be
217filled, a path should be closed, which is accomplished by the \type {cycle}
218primitive, as we saw in constructing the \type {unitsquare} path.
219
220\startbuffer
221pickup pencircle scaled .5cm ;
222fill unitsquare xscaled 8cm yscaled 1cm withcolor .625white ;
223path bb ; bboxmargin := 0pt ; bb := bbox currentpicture ;
224draw bb withpen pencircle scaled 1pt withcolor .625red ;
225draw origin withpen pencircle scaled 5pt withcolor .625yellow ;
226\stopbuffer
227
228\typebuffer
229
230This example demonstrates that when we fill the path, the resulting graphic is
231smaller. Where \type {draw} follows the center of a path, \type {fill} stays
232inside the path.
233
234\startlinecorrection[blank]
235\processMPbuffer
236\stoplinecorrection
237
238A third alternative is the \type {filldraw} macro. From the previous examples, we
239would expect a bounding box that matches the one of the drawn path.
240
241\startbuffer
242pickup pencircle scaled .5cm ;
243filldraw unitsquare xscaled 8cm yscaled 1cm withcolor .625white ;
244path bb ; bboxmargin := 0pt ; bb := bbox currentpicture ;
245draw bb withpen pencircle scaled 1pt withcolor .625red ;
246draw origin withpen pencircle scaled 5pt withcolor .625yellow ;
247\stopbuffer
248
249\typebuffer
250
251% The resulting graphic has the bounding box of the fill. Note
252% how the path, because it is stroked with a .5cm pen, extends
253% beyond the border of the bounding box. The way this image
254% shows up depends on the viewer (settings) you use to render
255% the graphic. For example, in \GHOSTVIEW, if you disable
256% clipping to the bounding box, only the positive quadrant of
257% the graphic is shown. Further, if you enable clipping to the
258% bounding box, this image will look exactly like the previous
259% image created with the fill command. In many cases, it may
260% be best to avoid the \type {filldraw} command.
261
262The resulting graphic has the bounding box of the fill. Note how the path,
263because it is stroked with a .5cm pen, extends beyond the border of the previous
264bounding box. The way this image shows up depends on the viewer (settings) you
265use to render the graphic. For example, in \GHOSTVIEW, if you disable clipping to
266the bounding box, only the positive quadrant of the graphic is shown. \footnote
267{Old versions of \METAPOST\ calculated the boundingbox differently for a \type
268{filldraw}: through the middle of the penpath.}
269
270\startlinecorrection[blank]
271\processMPbuffer
272\stoplinecorrection
273
274From the previous examples, you can conclude that the following alternative
275results in a proper bounding box:
276
277\startbuffer
278pickup pencircle scaled .5cm ;
279path p ; p := unitsquare xscaled 8cm yscaled 1cm ;
280fill p withcolor .625white ;
281draw p withcolor .625white ;
282path bb ; bboxmargin := 0pt ; bb := bbox currentpicture ;
283draw bb withpen pencircle scaled 1pt withcolor .625red ;
284draw origin withpen pencircle scaled 5pt withcolor .625yellow ;
285\stopbuffer
286
287\typebuffer
288
289\startlinecorrection[blank]
290\processMPbuffer
291\stoplinecorrection
292
293The \CONTEXT\ distribution comes with a set of \METAPOST\ modules, one of which
294contains the \type {drawfill} macro, which provides the outer bounding box.
295\footnote {Starting from version 1.0 \METAPOST\ calculates the boundingbox
296differently and the distinction between \type {drawfill} and \type {filldraw} is
297gone. We keep them around both for compatibility.} Next we demonstrate its use in
298another, more complicated example.
299
300\startbuffer
301picture finalpicture ; finalpicture := nullpicture ;
302numeric n ; n := 0 ; bboxmargin := 0pt ;
303pickup pencircle scaled .5cm ;
304
305def shape =
306  unitsquare scaled 2cm withcolor .625white ;
307  draw bbox currentpicture
308    withpen pencircle scaled .5mm withcolor .625red ;
309  addto finalpicture also currentpicture shifted(n*3cm,0) ;
310  currentpicture := nullpicture ; n := n+1 ;
311enddef ;
312
313fill shape ; draw shape ; filldraw shape ; drawfill shape ;
314
315currentpicture := finalpicture ;
316\stopbuffer
317
318\typebuffer
319
320Here we introduce a macro definition, \type {shape}. In \METAPOST, the start of a
321macro definition is indicated with the keyword \type {def}. Thereafter, you can
322insert other variables and commands, even other macro definitions. The keyword
323\type {enddef} signals the end of the macro definition. The result is shown in
324\in {figure} [fig:draws and fills]; watch the bounding boxes. Close reading of
325the macro will reveal that the \type {fill}, \type {draw}, \type {filldraw} and
326\type {drawfill} macros are applied to the first \type {unitsquare} path in the
327macro.
328
329\placefigure
330  [here]
331  [fig:draws and fills]
332  {A \type {fill}, \type {draw}, \type {filldraw} and \type
333   {drawfill} applied to the same square.}
334  {\processMPbuffer}
335
336In this macro, \type {bbox} calls a macro that returns the enlarged bounding box
337of a path. By setting \type {bboxmargin} we can influence how much the bounding
338box is enlarged. Since this is an existing variable, we don't have to allocate
339it, like we do with~\type{numeric n}. Unless you take special precautions,
340variables are global by nature and persistent outside macros.
341
342\starttyping
343picture finalpicture ; finalpicture := nullpicture ;
344\stoptyping
345
346Just as \type {numeric} allocates an integer variable, the \type {picture}
347primitive allocates a picture data structure. We explicitly have to set this
348picture to nothing using the built||in primitive \type {nullpicture}.
349
350Later on, we will add the drawn paths as accumulated in \type {currentpicture} to
351this \type {finalpicture} in the following manner.
352
353\starttyping
354addto finalpicture also currentpicture shifted(n*3cm,0) ;
355\stoptyping
356
357Since we want to add a few more and don't want them to overlap, we shift them.
358Therefore we have to erase the current picture as well as increment the shift
359counter.
360
361\starttyping
362currentpicture := nullpicture ; n := n+1 ;
363\stoptyping
364
365The \type {drawfill} macro is one of the \METAFUN\ macros. Another handy macro is
366\type {boundingbox}. When used instead of \type {bbox}, you don't have to set the
367margin to zero.
368
369\startbuffer
370drawoptions (withcolor .625white) ;
371path p ; p := unitsquare scaled 2cm ;
372fill p shifted (3cm,0) ;
373pickup pencircle scaled .5cm ; fill p shifted (6cm,0) ;
374fill p shifted (9cm,0) withpen pencircle scaled .5cm ;
375\stopbuffer
376
377\placefigure
378  [here]
379  [fig:more draws and fills]
380  {The influence of pens on \type {fill}.}
381  {\processMPbuffer}
382
383There is a subtle point in filling a shape. In \in {figure} [fig:more draws and
384fills] you see the influence of the pen on a \type {fill} operation. An indirect
385specification has no influence, and results in a filled rectangle with sharp
386corners. The third rectangle is drawn with a direct pen specification which
387results in a larger shape with rounds corners. However, the bounding box is the
388same in all three cases. The graphic is defined as follows. This time we don't
389use a (complicated) macro.
390
391\typebuffer
392
393When a graphic is constructed, its components end up in an internal data
394structure in a more or less layered way. This means that as long as a graphic is
395not flushed, you may consider it to be a stack of paths and texts with the paths
396being drawn or filled shapes or acting as clipping paths or bounding boxes.
397
398When you ask for the dimensions of a graphic the lower left and upper right
399corner are calculated using this stack. Because you can explicitly set bounding
400boxes, you can lie about the dimensions of a graphic. This is a very useful
401feature. In the rare case that you want to know the truth and nothing but the
402truth, you can tweak the \type {truecorners} numeric variable. We will
403demonstrate this with a few examples.
404
405\startbuffer
406fill fullcircle scaled 1cm withcolor .625yellow ;
407\stopbuffer
408
409\typebuffer
410
411\startlinecorrection[blank]\ruledhbox{\processMPbuffer}\stoplinecorrection
412
413\startbuffer
414fill fullcircle scaled 1cm withcolor .625yellow ;
415setbounds currentpicture to boundingbox currentpicture enlarged 2mm ;
416\stopbuffer
417
418\typebuffer
419
420\startlinecorrection[blank]\ruledhbox{\processMPbuffer}\stoplinecorrection
421
422\startbuffer
423fill fullcircle scaled 1cm withcolor .625yellow ;
424setbounds currentpicture to boundingbox currentpicture enlarged 2mm ;
425interim truecorners := 1 ;
426\stopbuffer
427
428\typebuffer
429
430\startlinecorrection[blank]\ruledhbox{\processMPbuffer}\stoplinecorrection
431
432\startbuffer
433fill fullcircle scaled 1cm withcolor .625yellow ;
434interim truecorners := 1 ;
435setbounds currentpicture to boundingbox currentpicture enlarged 2mm ;
436\stopbuffer
437
438\typebuffer
439
440\startlinecorrection[blank]\ruledhbox{\processMPbuffer}\stoplinecorrection
441
442As you can see here, as soon as we set \type {truecorners} to~1, the bounding box
443settings are ignored. \footnote {Normally you will use grouping to keep the
444interim local. In \METAFUN\ each figure restores this variable at the beginning.}
445
446There are two related macros: \type {bbwidth} and \type {bbheight} that you can
447apply to a path.
448
449\startbuffer
450fill unitcircle xscaled 4cm yscaled 2cm
451    withpen pencircle scaled 1mm withcolor .625red ;
452draw origin -- (bbwidth(currentpicture),0)
453    withpen pencircle scaled 1mm withcolor .625yellow ;
454draw origin -- (0,bbheight(currentpicture))
455    withpen pencircle scaled 1mm withcolor .625white ;
456\stopbuffer
457
458\typebuffer
459
460\startlinecorrection[blank]\processMPbuffer\stoplinecorrection
461
462\stopsection
463
464Yet another helper is \type {boundingcircle}. Its effect can best be demonstrated with
465a few examples:
466
467\startbuffer[a]
468path p ; p := fullsquare scaled 2cm ;
469
470draw                p withpen pencircle scaled 3mm withcolor .625white ;
471draw center         p withpen pencircle scaled 3mm withcolor .625white ;
472draw boundingbox    p withpen pencircle scaled 1mm withcolor .625red ;
473draw boundingcircle p withpen pencircle scaled 1mm withcolor .625yellow ;
474\stopbuffer
475
476\startbuffer[b]
477path p ; p := fullcircle scaled 2cm ;
478
479draw                p withpen pencircle scaled 3mm withcolor .625white ;
480draw center         p withpen pencircle scaled 3mm withcolor .625white ;
481draw boundingbox    p withpen pencircle scaled 1mm withcolor .625red ;
482draw boundingcircle p withpen pencircle scaled 1mm withcolor .625yellow ;
483\stopbuffer
484
485\startbuffer[c]
486path p ; p := fulltriangle scaled 2cm ;
487
488draw                p withpen pencircle scaled 3mm withcolor .625white ;
489draw center         p withpen pencircle scaled 3mm withcolor .625white ;
490draw boundingbox    p withpen pencircle scaled 1mm withcolor .625red ;
491draw boundingcircle p withpen pencircle scaled 1mm withcolor .625yellow ;
492\stopbuffer
493
494\typebuffer[a,b,c]
495
496You can consider the \type {boundingcircle} to be a round boundingbox.
497
498\startlinecorrection[blank]
499\startcombination[nx=3,ny=1,location=middle]
500    {\processMPbuffer[a]} {square}
501    {\processMPbuffer[b]} {circle}
502    {\processMPbuffer[c]} {triangle}
503\stopcombination
504\stoplinecorrection
505
506\startsection[title={Units}]
507
508\index{units}
509
510Like \TEX, \METAPOST\ supports multiple units of length. In \TEX, these units are
511hard coded and handled by the parser, where the internal unit of length is the
512scaled point (\type {sp}), something on the nanometer range. Because \METAPOST\
513is focused on \POSTSCRIPT\ output, its internal unit is the big point (\type
514{bp}). All other units are derived from this unit and available as numeric
515instead of hard coded.
516
517\starttyping
518mm =  2.83464 ; pt =  0.99626 ; dd =  1.06601 ; bp :=  1 ;
519cm = 28.34645 ; pc = 11.95517 ; cc = 12.79213 ; in := 72 ;
520\stoptyping
521
522Careful reading reveals that only the \type {bp} and \type {in} are fixed, while
523the rest of the dimensions are scalar multiples of \type {bp}.
524
525Since we are dealing with graphics, the most commonly used dimensions are \type
526{pt}, \type {bp}, \type {mm}, \type {cm} and~\type {in}.
527
528\startuseMPgraphic{pt}
529  fill fullsquare scaled 72.27pt withcolor .625yellow ;
530  fill fullcircle scaled 72.27pt withcolor white ;
531  label("72.27pt", center currentpicture) ;
532\stopuseMPgraphic
533\startuseMPgraphic{bp}
534  fill fullsquare scaled 72bp withcolor .625yellow ;
535  fill fullcircle scaled 72bp withcolor white ;
536  label("72bp", center currentpicture) ;
537\stopuseMPgraphic
538\startuseMPgraphic{mm}
539  fill fullsquare scaled 25.4mm withcolor .625yellow ;
540  fill fullcircle scaled 25.4mm withcolor white ;
541  label("25.4mm", center currentpicture) ;
542\stopuseMPgraphic
543\startuseMPgraphic{cm}
544  fill fullsquare scaled 2.54cm withcolor .625yellow ;
545  fill fullcircle scaled 2.54cm withcolor white ;
546  label("2.54cm", center currentpicture) ;
547\stopuseMPgraphic
548\startuseMPgraphic{in}
549  fill fullsquare scaled 1in withcolor .625yellow ;
550  fill fullcircle scaled 1in withcolor white ;
551  label("1in", center currentpicture) ;
552\stopuseMPgraphic
553
554\startlinecorrection[blank]
555\hbox to \hsize
556  {\useMPgraphic{pt}\hss
557   \useMPgraphic{bp}\hss
558   \useMPgraphic{mm}\hss
559   \useMPgraphic{cm}\hss
560   \useMPgraphic{in}}
561\stoplinecorrection
562
563The text in the center of the leftmost graphic is typeset by \METAPOST\ as a
564label.
565
566\starttyping
567fill fullsquare scaled 72.27pt withcolor .625yellow ;
568fill fullcircle scaled 72.27pt withcolor white ;
569label("72.27pt", center currentpicture) ;
570\stoptyping
571
572In \METAPOST\ the following lines are identical:
573
574\starttyping
575draw fullcircle scaled 100 ;
576draw fullcircle scaled 100bp ;
577\stoptyping
578
579You might be tempted to omit the unit, but this can be confusing, particularly if
580you also program in a language like \METAFONT, where the \type {pt} is the base
581unit. This means that a circle scaled to 100 in \METAPOST\ is not the same as a
582circle scaled to 100 in \METAFONT. Consider the next definition:
583
584\startbuffer
585pickup pencircle scaled 0 ;
586fill unitsquare
587  xscaled 400pt yscaled -.5cm withcolor .625red ;
588fill unitsquare
589  xscaled 400bp yscaled +.5cm withcolor .625yellow ;
590drawoptions(withcolor white) ;
591label.rt("400 pt", origin shifted (0, -.25cm)) ;
592label.rt("400 bp", origin shifted (0, +.25cm)) ;
593\stopbuffer
594
595\typebuffer
596
597When processed, the difference between a \type {pt} and \type {bp} shows rather
598well. Watch how we use \type {.rt} to move the label to the right; you can
599compare this with \TEX's macro \type {\rlap}. You might want to experiment with
600\type {.lft}, \type {.top}, \type {.bot}, \type {.ulft}, \type {.urt}, \type
601{.llft} and \type {.lrt}.
602
603The difference between both bars is exactly \scratchdimen = 400 bp
604\advance\scratchdimen by -400 pt \the \scratchdimen \space (as calculated by
605\TEX).
606
607\startlinecorrection[blank]
608\processMPbuffer
609\stoplinecorrection
610
611Where \TEX\ is anchored in tradition, and therefore more or less uses the \type
612{pt} as the default unit, \METAPOST, much like \POSTSCRIPT, has its roots in the
613computer sciences. There, to simplify calculations, an inch is divided in 72 big
614points, and .72pt is sacrificed.
615
616When you consider that \POSTSCRIPT\ is a high end graphic programming language,
617you may wonder why this sacrifice was made. Although the difference between \type
618{1bp} and \type {1pt} is miniscule, this difference is the source of much
619(unknown) confusion. When \TEX\ users talk about a \type {10pt} font, a desktop
620publisher hears \type {10bp}. In a similar vein, when we define a papersize
621having a width of \type {600pt} and a height of \type {450pt}, which is papersize
622\type {S6} in \CONTEXT, a \POSTSCRIPT\ or \PDF\ viewer will report slightly
623smaller values as page dimensions. This is because those programs claim the \type
624{pt} to be a \type {bp}. [This confusion can lead to interesting discussions with
625desktop publishers when they have to use \TEX. They often think that their demand
626of a baseline distance of \type {13.4} is met when we set it to \type {13.4pt},
627while actually they were thinking of \type {13.4bp}, which of course in other
628programs is specified using a \type {pt} suffix.]
629
630Therefore, when embedding graphics in \CONTEXT, we strongly recommend that you
631use \type {pt} as the base unit instead. The main reason why we spend so many
632words on this issue is that, when neglected, large graphics may look inaccurate.
633Actually, when taken care of, it is one of the (many) reasons why \TEX\ documents
634always look so accurate. Given that the eye is sensitive to distortions of far
635less than \type {1pt}, you can be puzzled by the fact that many drawing programs
636only provide a bounding box in rounded units. Thereby, they round to the next
637position, to prevent unwanted cropping. For some reason this low resolution has
638made it into the high end \POSTSCRIPT\ standard.
639
640In \CONTEXT\ we try to deal with these issues as well as possible.
641
642\stopsection
643
644\startsection[title={Scaling and shifting}]
645
646\index{scaling}
647\index{shifting}
648
649When we draw a shape, \METAPOST\ will adapt the bounding box accordingly. This
650means that a graphic has its natural dimensions, unless of course we adapt the
651bounding box manually. When you limit your graphic to a simple shape, say a
652rectangle, shifting it to some place can get obscured by this fact. Therefore,
653the following series of shapes appear to be the same.
654
655\startbuffer
656draw
657  unitsquare xscaled 6cm yscaled 1.5cm
658  withpen pencircle scaled 2mm withcolor .625red ;
659\stopbuffer
660
661\typebuffer
662
663\startlinecorrection[blank]\processMPbuffer\stoplinecorrection
664
665\startbuffer
666draw
667  unitsquare shifted (.5,.5) xscaled 6cm yscaled 1.5cm
668  withpen pencircle scaled 2mm withcolor .625red ;
669\stopbuffer
670
671\typebuffer
672
673\startlinecorrection[blank]\processMPbuffer\stoplinecorrection
674
675\startbuffer
676draw
677  unitsquare shifted (-.5,-.5) xscaled 6cm yscaled 1.5cm
678  withpen pencircle scaled 2mm withcolor .625red ;
679\stopbuffer
680
681\typebuffer
682
683\startlinecorrection[blank]\processMPbuffer\stoplinecorrection
684
685\startbuffer
686draw
687  unitsquare xscaled 6cm yscaled 1.5cm shifted (1cm,1cm)
688  withpen pencircle scaled 2mm withcolor .625red ;
689\stopbuffer
690
691\typebuffer
692
693\startlinecorrection[blank]\processMPbuffer\stoplinecorrection
694
695\startbuffer
696draw
697  unitsquare xscaled 6cm yscaled 1.5cm shifted (1.5cm,1cm)
698  withpen pencircle scaled 2mm withcolor .625red ;
699\stopbuffer
700
701\typebuffer
702
703\startlinecorrection[blank]\processMPbuffer\stoplinecorrection
704
705However, when we combine such graphics into one, we will see in what respect the
706scaling and shifting actually takes place.
707
708\startbuffer
709draw
710  unitsquare xscaled 6cm yscaled 2cm
711  withpen pencircle scaled 3.0mm withcolor .625yellow ;
712draw
713  unitsquare shifted (.5,.5) xscaled 6cm yscaled 2cm
714  withpen pencircle scaled 3.0mm withcolor .625red ;
715draw
716  unitsquare xscaled 6cm yscaled 2cm shifted (1cm,1cm)
717  withpen pencircle scaled 3.0mm withcolor .625white ;
718draw
719  unitsquare xscaled 6cm yscaled 2cm shifted (1.5cm,1cm)
720  withpen pencircle scaled 1.5mm withcolor white ;
721draw
722  unitsquare shifted (-.5,-.5) xscaled 6cm yscaled 2cm
723  withpen pencircle scaled 1mm withcolor black ;
724draw origin withpen pencircle scaled 1mm ;
725\stopbuffer
726
727\typebuffer
728
729\startlinecorrection[blank]\processMPbuffer\stoplinecorrection
730
731As you can see, the transformations are applied in series. Sometimes this is not
732what we want, in which case we can use parentheses to force the desired
733behaviour. The lesson learned is that {\em scaling and shifting} is not always
734the same as {\em shifting and scaling}.
735
736\startbuffer
737draw
738  origin -- origin shifted ((4cm,0cm) shifted (4cm,0cm))
739  withpen pencircle scaled 1cm withcolor .625white ;
740draw
741  origin -- origin shifted (4cm,0cm) shifted (4cm,0cm)
742  withpen pencircle scaled 8mm withcolor .625yellow ;
743draw
744  (origin -- origin shifted (4cm,0cm)) shifted (4cm,0cm)
745  withpen pencircle scaled 6mm withcolor .625red ;
746draw
747  origin -- (origin shifted (4cm,0cm) shifted (4cm,0cm))
748  withpen pencircle scaled 4mm withcolor white ;
749\stopbuffer
750
751\typebuffer
752
753\startlinecorrection[blank]\processMPbuffer\stoplinecorrection
754
755Especially when a path results from a call to a macro, using parentheses around a
756path may help, as in the following example.
757
758\startbuffer
759def unitslant = origin -- origin shifted (1,1) enddef ;
760draw
761  unitslant xscaled 5cm yscaled 1cm
762  withpen pencircle scaled 1cm withcolor .625red ;
763draw
764  (unitslant) xscaled 5cm yscaled 1cm
765  withpen pencircle scaled 5mm withcolor .625yellow ;
766\stopbuffer
767
768\typebuffer
769
770\startlinecorrection[blank]\processMPbuffer\stoplinecorrection
771
772The next definition of \type {unitslant} is therefore better.
773
774\startbuffer
775def unitslant = (origin -- origin shifted (1,1)) enddef ;
776draw
777  unitslant xscaled 5cm yscaled 1cm
778  withpen pencircle scaled 5mm withcolor .625red ;
779\stopbuffer
780
781\typebuffer
782
783\startlinecorrection[blank]\processMPbuffer\stoplinecorrection
784
785An even better alternative is:
786
787\startbuffer
788path unitslant ; unitslant = origin -- origin shifted (1,1) ;
789draw
790  unitslant xscaled 5cm yscaled 1cm
791  withpen pencircle scaled 5mm withcolor .625yellow ;
792\stopbuffer
793
794\typebuffer
795
796\startlinecorrection[blank]
797\processMPbuffer
798\stoplinecorrection
799
800\stopsection
801
802\startsection[title={Curve construction}]
803
804\index{curves}
805
806\doifmodeelse{screen}
807  {\def\Xcom{3}\def\Ycom{2}\def\Zcom{\the\textheight}}
808  {\def\Xcom{2}\def\Ycom{3}\def\Zcom{\the\textwidth }}
809
810Chapter 3 of the \METAFONT\ book explains the mathematics behind the construction
811of curves. Both \METAFONT\ and \METAPOST\ implement Bézier curves. The fact that
812these curves are named after Pierre Bézier obscures the fact that the math behind
813them originates with SergeÄ­ BernshteÄ­n.
814
815The points on the curve are determined by the following formula:
816
817\placeformula[-]
818\startformula
819z(t) = (1-t)^3 z_1 + 3 (1-t)^2 t z_2 + 3 (1-t) t^2 z_3 + t^3 z_4
820\stopformula
821
822Here, the parameter $t$ runs from $[0,1]$. As you can see, we are dealing with
823four points. In practice this means that when we construct a curve from multiple
824points, we act on two points and the two control points in between. So, the
825segment that goes from $z_1$ to $z_4$ is calculated using these two points and
826the points that \METAFONT|/|\METAPOST\ calls post control point and pre control
827point.
828
829\startbuffer[a]
830vardef dodrawmidpoints (expr a, b, c, d, n, col, m)  =
831  save e, f, g, h, i, j ; pair e, f, g, h, i, j ;
832  e := .5[a,b] ; f := .5[b,c] ; g := .5[c,d] ;
833  h := .5[e,f] ; i := .5[f,g] ; j := .5[h,i] ;
834  if m= 0 : drawpoints j          elseif
835     m= 1 : draw       a--b--c--d elseif
836     m= 2 : draw       e--f--g    elseif
837     m= 3 : draw       h--i       elseif
838     m= 4 : draw       a--e--h--j elseif
839     m= 5 : draw       j--i--g--d elseif
840     m=11 : drawpoints a--b--c--d elseif
841     m=12 : drawpoints e--f--g    elseif
842     m=13 : drawpoints h--i       elseif
843     m=14 : drawpoints a--e--h--j elseif
844     m=15 : drawpoints j--i--g--d     fi withcolor col ;
845  if n>1 :
846    dodrawmidpoints(a, e, h, j, n-1, col, m) ;
847    dodrawmidpoints(j, i, g, d, n-1, col, m) ;
848  fi ;
849enddef ;
850
851vardef drawmidpoints (expr p, n, col, m) =
852  save a, b, c, d ; pair a, b, c, d ;
853  for x=0 upto length(p)-1 :
854    a := point x   of p ; b := postcontrol x   of p ;
855    d := point x+1 of p ; c := precontrol  x+1 of p ;
856    dodrawmidpoints(a,b,c,d,n,col,m) ;
857  endfor ;
858enddef ;
859\stopbuffer
860
861\startbuffer[b]
862path p ; p := (4cm,4cm)..(6cm,0cm)..(1cm,2cm) ;
863\stopbuffer
864
865\startbuffer[c]
866drawpath          p ;
867drawcontrollines  p withcolor .625yellow ;
868drawcontrolpoints p withcolor .625red ;
869drawpoints        p withcolor .625red ;
870freelabel(btex $z_1$ etex, point       0 of p, center p) ;
871freelabel(btex $z_2$ etex, postcontrol 0 of p, center p) ;
872freelabel(btex $z_3$ etex, precontrol  1 of p, center p) ;
873freelabel(btex $z_4$ etex, point       1 of p, center p) ;
874freelabel(btex $z_5$ etex, postcontrol 1 of p, center p) ;
875freelabel(btex $z_6$ etex, precontrol  2 of p, center p) ;
876freelabel(btex $z_7$ etex, point       2 of p, center p) ;
877\stopbuffer
878
879\startbuffer[x]
880draw boundingbox p enlarged 1cm ;
881setbounds currentpicture to boundingbox p enlarged 1cm ;
882currentpicture := currentpicture xsized (.45*\Zcom) ;
883\stopbuffer
884
885\startlinecorrection[blank]
886\processMPbuffer[a,b,c,x]
887\stoplinecorrection
888
889The previous curve is constructed from the three points $z_1$, $z_4$ and $z_7$.
890The curve is drawn in \METAPOST\ by \type {z1..z4..z7} and is made up out of two
891segments. The first segment is determined by the following points:
892
893\startitemize[packed,n]
894\item point $z_1$ of the curve
895\item the postcontrol point $z_2$ of $z_1$
896\item the precontrol point $z_3$ of $z_4$
897\item point $z_4$ of the curve
898\stopitemize
899
900On the next pages we will see how the whole curve is constructed from these
901quadruples of points. The process comes down to connecting the mid points of the
902straight lines to the points mentioned. We do this three times, which is why
903these curves are classified as third order approximations.
904
905The first series of graphics demonstrates the process of determining the mid
906points. The third order midpoint is positioned on the final curve. The second
907series focuses on the results: new sets of four points that will be used in a
908next stage. The last series only shows the third order midpoints. As you can see,
909after some six iterations we have already reached a rather good fit of the final
910curve. The exact number of iterations depends on the resolution needed. You will
911notice that the construction speed (density) differs per segment.
912
913\startpostponing
914
915% cc .. hh in order to avoid conflicts with c-...
916
917\startbuffer[cc]
918drawpath p ; drawpoints p ; drawcontrolpoints p ;
919\stopbuffer
920
921\startbuffer[dd]
922drawmidpoints(p,1,.625red, 11) ; drawmidpoints(p,1,.625yellow, 1) ;
923\stopbuffer
924
925\startbuffer[ee]
926drawmidpoints(p,1,.625red, 12) ; drawmidpoints(p,1,.625yellow, 2) ;
927\stopbuffer
928
929\startbuffer[ff]
930drawmidpoints(p,1,.625red, 13) ; drawmidpoints(p,1,.625yellow, 3) ;
931\stopbuffer
932
933\startbuffer[gg]
934drawmidpoints(p,1,.625red, 14) ; drawmidpoints(p,1,.625yellow, 4) ;
935\stopbuffer
936
937\startbuffer[hh]
938drawmidpoints(p,1,.625red, 15) ; drawmidpoints(p,1,.625yellow, 5) ;
939\stopbuffer
940
941\startbuffer
942\startcombination[\Xcom*\Ycom]
943  {\processMPbuffer[a,b,cc,x]}          {points}
944  {\processMPbuffer[a,b,cc,dd,x]}       {first  order curve}
945  {\processMPbuffer[a,b,cc,dd,ee,x]}    {second order curve}
946  {\processMPbuffer[a,b,cc,dd,ee,ff,x]} {third  order curve}
947  {\processMPbuffer[a,b,cc,dd,ee,gg,x]} {left   side  curves}
948  {\processMPbuffer[a,b,cc,dd,ee,hh,x]} {right  side  curves}
949\stopcombination
950\stopbuffer
951
952\getbuffer \page
953
954\startbuffer[dd]
955drawmidpoints(p,1,.625red, 11) ;
956drawmidpoints(p,1,.625yellow, 1) ;
957\stopbuffer
958
959\startbuffer[ee]
960for i=11, 12 : drawmidpoints(p,1,.625red, i) ; endfor ;
961drawmidpoints(p,1,.625yellow, 2) ;
962\stopbuffer
963
964\startbuffer[ff]
965for i=11, 12, 13 : drawmidpoints(p,1,.625red, i) ; endfor ;
966drawmidpoints(p,1,.625yellow, 3) ;
967\stopbuffer
968
969\startbuffer[gg]
970for i=11,12,13,14 : drawmidpoints(p,1,.625red, i) ; endfor ;
971drawmidpoints(p,1,.625yellow, 4) ;
972\stopbuffer
973
974\startbuffer[hh]
975for i=11, 12, 13, 14, 15 : drawmidpoints(p,1,.625red, i) ; endfor ;
976drawmidpoints(p,1,.625yellow, 5) ;
977\stopbuffer
978
979\startbuffer
980\startcombination[\Xcom*\Ycom]
981  {\processMPbuffer[a,b,cc,x]}   {points}
982  {\processMPbuffer[a,b,cc,dd,x]} {first  order points}
983  {\processMPbuffer[a,b,cc,ee,x]} {second order points}
984  {\processMPbuffer[a,b,cc,ff,x]} {third  order points}
985  {\processMPbuffer[a,b,cc,gg,x]} {left   side  points}
986  {\processMPbuffer[a,b,cc,hh,x]} {right  side  points}
987\stopcombination
988\stopbuffer
989
990\getbuffer \page
991
992\startbuffer[cc]
993drawpath p ; drawmidpoints (p,1,.625yellow, 0) ;
994\stopbuffer
995
996\startbuffer[dd]
997drawpath p ; drawmidpoints (p,2,.625yellow, 0) ;
998\stopbuffer
999
1000\startbuffer[ee]
1001drawpath p ; drawmidpoints (p,3,.625yellow, 0) ;
1002\stopbuffer
1003
1004\startbuffer[ff]
1005drawpath p ; drawmidpoints (p,4,.625yellow, 0) ;
1006\stopbuffer
1007
1008\startbuffer[gg]
1009drawpath p ; drawmidpoints (p,5,.625yellow, 0) ;
1010\stopbuffer
1011
1012\startbuffer[hh]
1013drawpath p ; drawmidpoints (p,6,.625yellow, 0) ;
1014\stopbuffer
1015
1016\startbuffer
1017\startcombination[\Xcom*\Ycom]
1018  {\processMPbuffer[a,b,cc,x]}                {first  iteration}
1019  {\processMPbuffer[a,b,cc,dd,x]}             {second iteration}
1020  {\processMPbuffer[a,b,cc,dd,ee,x]}          {third  iteration}
1021  {\processMPbuffer[a,b,cc,dd,ee,ff,x]}       {fourth iteration}
1022  {\processMPbuffer[a,b,cc,dd,ee,ff,gg,x]}    {fifth  iteration}
1023  {\processMPbuffer[a,b,cc,dd,ee,ff,gg,hh,x]} {sixths iteration}
1024\stopcombination
1025\stopbuffer
1026
1027\getbuffer \page
1028
1029\stoppostponing
1030
1031% here we pick up the thread, if we would not flush the
1032% pages before the next text, the reader could become
1033% confused
1034
1035The path in these examples is defined as follows:
1036
1037\typebuffer[b]
1038
1039If you are playing with graphics like this, the \METAFUN\ macro \type {randomize}
1040may come in handy:
1041
1042\startbuffer[bb]
1043p := p randomized (1cm,.5cm) ;
1044\stopbuffer
1045
1046\typebuffer[bb]
1047
1048If we apply this operation a couple of times we can see how the (control) points
1049vary. (Using the randomizer saves us the troubles of finding nice example
1050values.) The angle between the tangent as well as the distance from the parent
1051point determine the curve.
1052
1053\startbuffer[xx]
1054currentpicture := currentpicture scaled .5 ;
1055\stopbuffer
1056
1057\startlinecorrection[blank]
1058\hbox to \hsize
1059  {\processMPbuffer[a,b,bb,c,x,xx]\hss
1060   \processMPbuffer[a,b,bb,c,x,xx]\hss
1061   \processMPbuffer[a,b,bb,c,x,xx]\hss
1062   \processMPbuffer[a,b,bb,c,x,xx]}
1063\stoplinecorrection
1064
1065% new thread
1066
1067Just in case you are interested in how such graphical simulations can be
1068organized, we show simplified versions of the macros used here. (In the previous
1069examples we minimized the complexity of the code by using buffers, but describing
1070this mechanism is out of the scope of this section.)
1071
1072\startbuffer[demo]
1073vardef dodrawmidpoints (expr a, b, c, d, n)  =
1074  save e, f, g, h, i, j ; pair e, f, g, h, i, j ;
1075  e := .5[a,b] ; f := .5[b,c] ; g := .5[c,d] ;
1076  h := .5[e,f] ; i := .5[f,g] ; j := .5[h,i] ;
1077  draw j ;
1078  if n>1 :
1079    dodrawmidpoints(a, e, h, j, n-1) ;
1080    dodrawmidpoints(j, i, g, d, n-1) ;
1081  fi ;
1082enddef ;
1083
1084vardef drawmidpoints (expr p, n) =
1085  save a, b, c, d ; pair a, b, c, d ;
1086  for x=0 upto length(p)-1 :
1087    a := point x   of p ; b := postcontrol x   of p ;
1088    d := point x+1 of p ; c := precontrol  x+1 of p ;
1089    dodrawmidpoints(a, b, c, d, n) ;
1090  endfor ;
1091enddef ;
1092\stopbuffer
1093
1094We need to loop over all segments of a curve, where for each segment the left and
1095right side sub curves are handled recursively, upto the requested depth (denoted
1096as \type {n}). For this we define the following macros.
1097
1098\typebuffer[demo]
1099
1100\startbuffer[zero]
1101drawoptions (withpen pencircle scaled 5pt withcolor .625red);
1102\stopbuffer
1103
1104\startbuffer[extra]
1105drawoptions (withpen pencircle scaled 5pt withcolor .625yellow);
1106\stopbuffer
1107
1108We apply this macro to a simple shape:
1109
1110\startbuffer[one]
1111drawmidpoints (fullcircle xscaled 300pt yscaled 50pt, 1) ;
1112\stopbuffer
1113
1114\typebuffer[one]
1115
1116When drawn, this results in the points that makes up the
1117curve:
1118
1119\startlinecorrection[blank]
1120\processMPbuffer[demo,zero,one]
1121\stoplinecorrection
1122
1123We now add an extra iteration (resulting in the yellow points):
1124
1125\startbuffer[two]
1126drawmidpoints (fullcircle xscaled 300pt yscaled 50pt, 2) ;
1127\stopbuffer
1128
1129\typebuffer[two]
1130
1131and get:
1132
1133\startlinecorrection[blank]
1134\processMPbuffer[demo,zero,two,extra,one]
1135\stoplinecorrection
1136
1137We don't even need that much iterations to get a good result. The depth needed to
1138get a good result depends on the size of the pen and the resolution of the device
1139on which the curve is visualized.
1140
1141\startbuffer[zero]
1142drawoptions (withpen pencircle scaled 2pt withcolor .625red) ;
1143\stopbuffer
1144
1145\startbuffer[three]
1146for i=1 upto 7 :
1147  drawmidpoints (fullcircle
1148    xscaled (300pt+i*10pt) yscaled (50pt+i*10pt), i) ;
1149endfor ;
1150\stopbuffer
1151
1152\typebuffer[three]
1153
1154Here we show 7 iterations in one graphic.
1155
1156\startlinecorrection[blank]
1157\processMPbuffer[demo,zero,three]
1158\stoplinecorrection
1159
1160In practice it is not that trivial to determine the depth needed. The next
1161example demonstrates how the resolution of the result depends on the length and
1162nature of the segment.
1163
1164\startbuffer[four]
1165drawmidpoints (fullsquare
1166  xscaled 300pt yscaled 50pt randomized (20pt,10pt), 5) ;
1167\stopbuffer
1168
1169\typebuffer[four]
1170
1171\startlinecorrection[blank]
1172\processMPbuffer[demo,zero,four]
1173\stoplinecorrection
1174
1175\stopsection
1176
1177\startsection[title={Inflection, tension and curl}]
1178
1179\index{inflection}
1180\index{tension}
1181\index{curl}
1182
1183The \METAPOST\ manual describes the meaning of \type {...} as \quotation {choose
1184an inflection||free path between these points unless the endpoint directions make
1185this impossible}. To use the words of David Arnold: a point of inflection is
1186where a path switches concavity, from concave up to concave down, for example.
1187
1188It is surprisingly difficult to find nice examples that demonstrate the
1189difference between \type {..} and \type {...}, as it is often \quote {impossible}
1190to honour the request for less inflection. We will demonstrate this with a few
1191graphics.
1192
1193In the four figures on the next pages, you will see that \type {...} is not
1194really suited for taming wild curves. If you really want to make sure that a
1195curve stays within certain bounds, you have to specify it as such using control
1196or intermediate points. In the figures that follow, the gray curves draw the
1197random path using \type {..} on top of yellow curves that use the \type {...}
1198connection. As you can see, in only a few occasions do the yellow \quote
1199{inflection} free curves show up.
1200
1201For those who asked for the code that produces these pictures, we now include it
1202here. We use a macro \type {sample} which we define as a usable graphic (nearly
1203all examples in this manual are coded in the document source).
1204
1205\startbuffer
1206\startuseMPgraphic{sample}
1207def sample (expr rx, ry) =
1208  path p, q ; numeric n, m, r, a, b ;
1209  color c ; c := \MPcolor{lightgray} ;
1210  a := 3mm ; b := 2mm ; r := 2cm ; n := 7 ; m := 5 ;
1211  q := unitsquare scaled r xyscaled (n,m) shifted (.5r,.5r) ;
1212  draw q withpen pencircle scaled (b/4) withcolor .625yellow;
1213  for i=1 upto n : for j=1 upto m :
1214    p := (fullcircle scaled r randomized (r/rx,r/ry))
1215      shifted ((i,j) scaled r) ;
1216    pickup pencircle scaled a ;
1217    draw for k=0 upto length(p) :
1218      point k of p ..  endfor cycle withcolor c ;
1219    draw for k=0 upto length(p) :
1220      point k of p ... endfor cycle withcolor c ;
1221    pickup pencircle scaled b ;
1222    draw for k=0 upto length(p) :
1223      point k of p ..  endfor cycle withcolor .625yellow ;
1224    draw for k=0 upto length(p) :
1225      point k of p ... endfor cycle withcolor .625white ;
1226    for k=0 upto length(p) :
1227      draw point k of p withcolor .625red ;
1228    endfor ;
1229  endfor ; endfor ;
1230  setbounds currentpicture to q ;
1231enddef ;
1232\stopuseMPgraphic
1233\stopbuffer
1234
1235\typebuffer \getbuffer
1236
1237As you see, not so much code is needed. The graphics themselves were produced
1238with a couple of commands like:
1239
1240\startbuffer
1241\placefigure
1242  {Circles with minimized inflection and 25\% randomized points.}
1243  {\startMPcode
1244     \includeMPgraphic{sample} ; sample(4,4) ;
1245   \stopMPcode}
1246\stopbuffer
1247
1248\typebuffer
1249
1250\startpostponing
1251
1252\placefigure
1253  {Circles with minimized inflection and 25\% randomized points.}
1254  {\startMPcode\includeMPgraphic{sample} ; sample(4,4) ; \stopMPcode}
1255
1256\placefigure
1257  {Circles with minimized inflection and 33\% randomized points.}
1258  {\startMPcode\includeMPgraphic{sample} ; sample(3,3) ; \stopMPcode}
1259
1260\page
1261
1262\placefigure
1263  {Circles with minimized inflection and 50\% randomized points.}
1264  {\startMPcode\includeMPgraphic{sample} ; sample(2,2) ; \stopMPcode}
1265
1266\placefigure
1267  {Circles with minimized inflection and 100\% randomized points.}
1268  {\startMPcode\includeMPgraphic{sample} ; sample(1,1) ; \stopMPcode}
1269
1270\page
1271
1272\stoppostponing
1273
1274The tension specifier can be used to influence the curvature. To quote the
1275\METAPOST\ manual once more: \quotation {The tension parameter can be less than
1276one, but it must be at least $3/4$}. The following paths are the same:
1277
1278\starttyping
1279z1 .. z2
1280z1 .. tension 1 .. z2
1281z1 .. tension 1 and 1 .. z2
1282\stoptyping
1283
1284The triple dot command \type {...} is actually a macro that makes the following
1285commands equivalent. Both commands will draw identical paths.
1286
1287\starttyping
1288z1 ... z2
1289z1 .. tension atleast 1 .. z2
1290\stoptyping
1291
1292The \type {atleast} directive tells \METAPOST\ to do some magic behind the
1293screens. Both the $3/4$ and the \type {atleast} lead directly to the question:
1294\quotation {What, exactly, is the influence of the tension directive?} We will
1295try to demystify the \type {tension} specifier through a sequence of graphics.
1296
1297\startbuffer
1298u := 1cm ; z1 = (0,0) ; z2 = (2u,4u) ; z3 = (4u,0) ;
1299def sample (expr p, c) =
1300  draw p withpen pencircle scaled 2.5mm withcolor white ;
1301  draw p withpen pencircle scaled 2.0mm withcolor c ;
1302enddef ;
1303for i=.75 step .05 until 1 :
1304  sample (z1 .. tension i .. z2 .. z3, .625red) ;
1305endfor ;
1306for i=1 step .05 until 2 :
1307  sample (z1 .. tension i .. z2 .. z3, .625yellow) ;
1308endfor ;
1309sample (z1 .. z2 .. z3, .625white) ;
1310sample (z1 ... z2 ... z3, .625white) ;
1311\stopbuffer
1312
1313\typebuffer
1314
1315Indeed values less than .75 give an error message, but large values are okay. As
1316you can see, the two gray curves are the same. Here, \type {atleast 1} means~1,
1317even if larger values are useful.
1318
1319\startlinecorrection[blank]
1320\processMPbuffer
1321\stoplinecorrection
1322
1323\startbuffer
1324u := 1cm ; z1 = (0,0) ; z2 = (2u,4u) ; z3 = (4u,0) ;
1325def sample (expr p, c) =
1326  draw p withpen pencircle scaled 2.5mm withcolor white ;
1327  draw p withpen pencircle scaled 2.0mm withcolor c ;
1328enddef ;
1329for i=.75 step .05 until 1 :
1330  sample (z1 .. tension i and 2i .. z2 .. z3, .625red) ;
1331endfor ;
1332for i=1 step .05 until 2 :
1333  sample (z1 .. tension i and 2i .. z2 .. z3, .625yellow) ;
1334endfor ;
1335sample (z1 .. z2 .. z3, .625white) ;
1336sample (z1 ... z2 ... z3, .625white) ;
1337\stopbuffer
1338
1339Curves finally are made up out of points, and each point has two control points.
1340Since the \type {tension} specifier finally becomes a control point, it is not
1341surprising that you may specify two tension values. If we replace the tension in
1342the previous example by
1343
1344\starttyping
1345.. tension i and 2i ..
1346\stoptyping
1347
1348we get the following graphic:
1349
1350\startlinecorrection[blank]
1351\processMPbuffer
1352\stoplinecorrection
1353
1354\startbuffer
1355u := 1cm ; z1 = (0,0) ; z2 = (2u,4u) ; z3 = (4u,0) ;
1356def sample (expr p, c) =
1357  draw p withpen pencircle scaled 2.5mm withcolor white ;
1358  draw p withpen pencircle scaled 2.0mm withcolor c ;
1359enddef ;
1360for i=.75 step .05 until 1 :
1361  sample (z1 .. tension 2i and i .. z2 .. z3, .625red) ;
1362endfor ;
1363for i=1 step .05 until 2 :
1364  sample (z1 .. tension 2i and i .. z2 .. z3, .625yellow) ;
1365endfor ;
1366sample (z1 .. z2 .. z3, .625white) ;
1367sample (z1 ... z2 ... z3, .625white) ;
1368\stopbuffer
1369
1370If we swap both values (\type {.. tension 2i and i ..}) we get:
1371
1372\startlinecorrection[blank]
1373\processMPbuffer
1374\stoplinecorrection
1375
1376\startbuffer[a]
1377u := 1cm ; z1 = (0,0) ; z2 = (2u,4u) ; z3 = (4u,0) ;
1378def sample (expr p, c) =
1379  drawpath          p withpen pencircle scaled 2.5mm withcolor c ;
1380  drawcontrollines  p withcolor c ;
1381  drawpoints        p ;
1382  drawcontrolpoints p ;
1383enddef ;
1384\stopbuffer
1385
1386We mentioned control points. We will now draw a few extreme tensions and show the
1387control points as \METAPOST\ calculates them.
1388
1389\startbuffer[b]
1390sample (z1 .. tension 0.75 .. z2 .. z3, .625red) ;
1391sample (z1 .. tension 2.00 .. z2 .. z3, .625yellow) ;
1392sample (z1 ..                 z2 .. z3, .625white) ;
1393\stopbuffer
1394
1395\typebuffer[b]
1396
1397First we will show the symmetrical tensions.
1398
1399\startlinecorrection[blank]
1400\processMPbuffer[a,b]
1401\stoplinecorrection
1402
1403The asymetrical tensions are less prominent. We use the following values:
1404
1405\startbuffer[b]
1406sample (z1 .. tension   .75 and 10    .. z2 .. z3, .625red) ;
1407sample (z1 .. tension 10    and   .75 .. z2 .. z3, .625yellow) ;
1408sample (z1 ..                            z2 .. z3, .625white) ;
1409\stopbuffer
1410
1411\typebuffer[b]
1412
1413\startlinecorrection[blank]
1414\processMPbuffer[a,b]
1415\stoplinecorrection
1416
1417What happens when you use the \METAPOST\ maximum value of \type {infinity}
1418instead of 10? Playing with this kind of graphic can be fun, especially when we
1419apply a few tricks.
1420
1421\startbuffer
1422def sample (expr p, c) =
1423  draw p withpen pencircle scaled 2.5mm withcolor white ;
1424  draw p withpen pencircle scaled 2.0mm withcolor c ;
1425enddef;
1426
1427u := 1cm ; z1 = (0,0) ; z2 = (2u,4u) ; z3 = (4u,0) ;
1428
1429for i=0 step .05 until 1 :
1430  sample(z1 .. tension (.75+i) .. z2 .. z3, i[.625red,.625yellow]) ;
1431endfor;
1432\stopbuffer
1433
1434\typebuffer
1435
1436Here we change the color along with the tension. This clearly demonstrates that
1437we're dealing with a non linear phenomena.
1438
1439\startlinecorrection[blank]
1440\processMPbuffer
1441\stoplinecorrection
1442
1443We can (misuse) transparant colors to illustrate how the effect becomes less with
1444growing tension.
1445
1446\startbuffer
1447def sample (expr p) (text c)=
1448  draw p withpen pencircle scaled 2.0mm withcolor c ;
1449enddef;
1450
1451u := 1cm ; z1 = (0,0) ; z2 = (2u,4u) ; z3 = (4u,0) ;
1452
1453for i=0 step .05 until 1 :
1454  sample(z1 .. tension (.75+i) .. z2 .. z3, transparent(1,1-i,.625red)) ;
1455endfor;
1456\stopbuffer
1457
1458\typebuffer
1459
1460\startlinecorrection[blank]
1461\processMPbuffer
1462\stoplinecorrection
1463
1464A third magic directive is \type {curl}. The curl is attached to a point between
1465\type {{ }}, like \type {{curl 2}}. Anything between curly braces is a direction
1466specifier, so instead of a \type {curl} you may specify a vector, like \type
1467{{(2,3)}}, a pair of numbers, as in \type {{2,3}}, or a direction, like \type
1468{{dir 30}}. Because vectors and angles are straightforward, we will focus a bit
1469on \type {curl}.
1470
1471\starttyping
1472z0 .. z1 .. z2
1473z0 {curl 1} .. z1 .. {curl 1} z2
1474\stoptyping
1475
1476So, a \type {curl} of~1 is the default. When set to~1, the begin and|/|or end
1477points are approached. Given the following definitions:
1478
1479\startbuffer[a]
1480u := 1cm ; z1 = (0,0) ; z2 = (2u,4u) ; z3 = (4u,0) ;
1481def sample (expr p, c) =
1482  draw p withpen pencircle scaled 2.5mm withcolor white ;
1483  draw p withpen pencircle scaled 2.0mm withcolor c ;
1484enddef ;
1485\stopbuffer
1486
1487\typebuffer[a]
1488
1489We can draw three curved paths.
1490
1491\startbuffer[b]
1492sample (z1 {curl 0} .. z2 .. {curl 0} z3, .625red) ;
1493sample (z1 {curl 2} .. z2 .. {curl 2} z3, .625yellow) ;
1494sample (z1 {curl 1} .. z2 .. {curl 1} z3, .625white) ;
1495\stopbuffer
1496
1497\typebuffer[b]
1498
1499The third (gray) curve is the default situation, so we could have left the \type
1500{curl} specifier out of the expression.
1501
1502\startlinecorrection[blank]
1503\processMPbuffer[a,b]
1504\stoplinecorrection
1505
1506\startbuffer[b]
1507sample (z1 {curl        0} .. z2 .. {curl        0} z3, .625red) ;
1508sample (z1 {curl infinity} .. z2 .. {curl infinity} z3, .625yellow) ;
1509sample (z1 {curl        1} .. z2 .. {curl        1} z3, .625white) ;
1510\stopbuffer
1511
1512The curly specs have a lower bound of zero and no upper bound. When we use
1513\METAPOST\ maximum value of \type {infinity} instead of~2, we get:
1514
1515\startlinecorrection[blank]
1516\processMPbuffer[a,b]
1517\stoplinecorrection
1518
1519These curves were defined as:
1520
1521\typebuffer[b]
1522
1523It may sound strange, but internally \METAPOST\ can handle
1524larger values than \type {infinity}.
1525
1526\startbuffer[b]
1527sample (z1 {curl  infinity} .. z2 .. {curl  infinity} z3, .625red) ;
1528sample (z1 {curl 4infinity} .. z2 .. {curl 4infinity} z3, .625yellow) ;
1529sample (z1 {curl 8infinity} .. z2 .. {curl 8infinity} z3, .625white) ;
1530\stopbuffer
1531
1532\typebuffer[b]
1533
1534Although this is quite certainly undefined behaviour, interesting effects can be
1535achieved. When you turn off \METAPOST's first stage overflow catcher by setting
1536\type {warningcheck} to zero, you can go upto 8 times \type {infinity}, which,
1537being some $2^{15}$, is still far from what today's infinity is supposed to be.
1538
1539\startlinecorrection[blank]
1540\processMPbuffer[a,b]
1541\stoplinecorrection
1542
1543As the built||in \METAPOST\ command \type {..} accepts the \type {curl} and \type
1544{tension} directives as described in this section, you will now probably
1545understand the following plain \METAPOST\ definitions:
1546
1547\starttyping
1548def --  = {curl 1} .. {curl 1}    enddef ;
1549def --- = .. tension infinity ..  enddef ;
1550def ... = .. tension atleast 1 .. enddef ;
1551\stoptyping
1552
1553These definitions also point out why you cannot add directives to the left or
1554right side of \type {--}, \type {---} and \type {...}: they are directives
1555themselves!
1556
1557\stopsection
1558
1559\startsection[title={Transformations}]
1560
1561\index{transformations}
1562
1563A \type {transform} is a vector that is used in what is called an affine
1564transformation. To quote the \METAPOST\ manual:
1565
1566\startquotation
1567If $p=(p_x,p_y)$ is a pair and $T$ is a transform, then
1568\type {p transform T} is a pair of the form:
1569
1570\startformula
1571(t_x + t_{xx} p_x + t_{xy} p_y, t_y + t_{yx} p_x + t_{yy} p_y)
1572\stopformula
1573
1574where the six numeric quantities $(t_x, t_y, t_{xx}, t_{xy},
1575t_{yx}, t_{yy})$ determine T.
1576\stopquotation
1577
1578In literature concerning \POSTSCRIPT\ and \PDF\ you will find many references to
1579such transformation matrices. A matrix of $(s_x,0,0,s_y,0,0)$ is scaling by $s_x$
1580in the horizontal direction and $s_y$ in the vertical direction, while
1581$(1,0,t_x,1,0,t_y)$ is a shift over $t_x,t_y$. Of course combinations are also
1582possible.
1583
1584Although these descriptions seem in conflict with each other in the nature and
1585order of the transform components in the vectors, the concepts are the same. You
1586normally populate transformation matrices using \type {scaled}, \type {shifted},
1587\type {rotated}.
1588
1589\starttyping
1590transform t ; t := identity shifted (a,b) rotated c scaled d ;
1591path p ; p := fullcircle transformed t ;
1592\stoptyping
1593
1594The previous lines of code are equivalent to:
1595
1596\starttyping
1597path p ; p := fullcircle shifted (a,b) rotated c scaled d ;
1598\stoptyping
1599
1600You always need a starting point, in this case the identity matrix \type
1601{identity}: $(0,0,1,0,0,1)$. By the way, in \POSTSCRIPT\ the zero vector is
1602$(1,0,0,1,0,0)$. So, unless you want to extract the components using \type
1603{xpart}, \type {xypart}, \type {xxpart}, \type {ypart}, \type {yxpart} and|/|or \
1604\type {yypart}, you may as well forget about the internal representation.
1605
1606You can invert a transformation using the \type {inverse} macro, which is defined
1607as follows, using an equation:
1608
1609\starttyping
1610vardef inverse primary T =
1611  transform T_ ; T_ transformed T = identity ; T_
1612enddef ;
1613\stoptyping
1614
1615Using transform matrices makes sense when similar transformations need to be
1616applied on many paths, pictures, pens, or other transforms. However, in most
1617cases you will use the predefined commands \type {scaled}, \type {shifted}, \type
1618{rotated} and alike. We will now demonstrate the most common transformations in a
1619text example.
1620
1621\startbuffer[a]
1622draw btex \bfd MetaFun etex ;
1623draw boundingbox currentpicture withcolor .625yellow ;
1624\stopbuffer
1625
1626\typebuffer[a]
1627
1628Before an independent \METAPOST\ run, the \typ {btex ... etex}'s are filtered
1629from the file and passed on to \TEX. After that, the \DVI\ file is converted to a
1630list of pictures, which is consulted by \METAPOST. This is no longer the case in
1631\LUATEX\ where we use \MPLIB, so users don't have to worry about these issues:
1632just ignore what is mentioned in the official \METAPOST\ manual.
1633
1634We can manipulate the pictures representing text like any graphic as well as draw
1635it with \type {draw}.
1636
1637\startlinecorrection[blank]
1638\processMPbuffer[a]
1639\stoplinecorrection
1640
1641We show the transformations in relation to the origin and make the origin stand
1642out a bit more by painting it a bit larger in white first.
1643
1644\startbuffer[c]
1645draw origin withpen pencircle scaled 1.5mm withcolor white ;
1646draw origin withpen pencircle scaled 1mm withcolor .625red
1647\stopbuffer
1648
1649\typebuffer[c]
1650
1651The origin is in the lower left corner of the picture.
1652
1653\startlinecorrection[blank]
1654\processMPbuffer[a,c]
1655\stoplinecorrection
1656
1657Because the transformation keywords are proper english, we let the pictures speak
1658for themselves.
1659
1660% shifted
1661
1662\startbuffer[b]
1663currentpicture := currentpicture shifted (0,-1cm) ;
1664\stopbuffer
1665
1666\page[preference] \typebuffer[b] \page[no]
1667
1668\startlinecorrection[blank]
1669\processMPbuffer[a,b,c]
1670\stoplinecorrection
1671
1672% rotated
1673
1674\startbuffer[b]
1675currentpicture := currentpicture rotated 180 ;
1676\stopbuffer
1677
1678\page[preference] \typebuffer[b] \page[no]
1679
1680\startlinecorrection[blank]
1681\processMPbuffer[a,b,c]
1682\stoplinecorrection
1683
1684% rotatedaround
1685
1686\startbuffer[b]
1687currentpicture := currentpicture rotatedaround(origin,30) ;
1688\stopbuffer
1689
1690\page[preference] \typebuffer[b] \page[no]
1691
1692\startlinecorrection[blank]
1693\processMPbuffer[a,b,c]
1694\stoplinecorrection
1695
1696% scaled
1697
1698\startbuffer[b]
1699currentpicture := currentpicture scaled 1.75 ;
1700\stopbuffer
1701
1702\page[preference] \typebuffer[b] \page[no]
1703
1704\startlinecorrection[blank]
1705\processMPbuffer[a,b,c]
1706\stoplinecorrection
1707
1708% scaled
1709
1710\startbuffer[b]
1711currentpicture := currentpicture scaled -1 ;
1712\stopbuffer
1713
1714\page[preference] \typebuffer[b] \page[no]
1715
1716\startlinecorrection[blank]
1717\processMPbuffer[a,b,c]
1718\stoplinecorrection
1719
1720% xscaled
1721
1722\startbuffer[b]
1723currentpicture := currentpicture xscaled 3.50 ;
1724\stopbuffer
1725
1726\page[preference] \typebuffer[b] \page[no]
1727
1728\startlinecorrection[blank]
1729\processMPbuffer[a,b,c]
1730\stoplinecorrection
1731
1732% xscaled
1733
1734\startbuffer[b]
1735currentpicture := currentpicture xscaled -1 ;
1736\stopbuffer
1737
1738\page[preference] \typebuffer[b] \page[no]
1739
1740\startlinecorrection[blank]
1741\processMPbuffer[a,b,c]
1742\stoplinecorrection
1743
1744% yscaled
1745
1746\startbuffer[b]
1747currentpicture := currentpicture yscaled .5 ;
1748\stopbuffer
1749
1750\page[preference] \typebuffer[b] \page[no]
1751
1752\startlinecorrection[blank]
1753\processMPbuffer[a,b,c]
1754\stoplinecorrection
1755
1756% yscaled
1757
1758\startbuffer[b]
1759currentpicture := currentpicture yscaled -1 ;
1760\stopbuffer
1761
1762\page[preference] \typebuffer[b] \page[no]
1763
1764\startlinecorrection[blank]
1765\processMPbuffer[a,b,c]
1766\stoplinecorrection
1767
1768% slanted
1769
1770\startbuffer[b]
1771currentpicture := currentpicture slanted .5 ;
1772\stopbuffer
1773
1774\page[preference] \typebuffer[b] \page[no]
1775
1776\startlinecorrection[blank]
1777\processMPbuffer[a,b,c]
1778\stoplinecorrection
1779
1780% slanted
1781
1782\startbuffer[b]
1783currentpicture := currentpicture slanted -.5 ;
1784\stopbuffer
1785
1786\page[preference] \typebuffer[b] \page[no]
1787
1788\startlinecorrection[blank]
1789\processMPbuffer[a,b,c]
1790\stoplinecorrection
1791
1792% zscaled
1793
1794\startbuffer[b]
1795currentpicture := currentpicture zscaled (.75,.25) ;
1796\stopbuffer
1797
1798\page[preference] \typebuffer[b] \page[no]
1799
1800\startlinecorrection[blank]
1801\processMPbuffer[a,b,c]
1802\stoplinecorrection
1803
1804% reflectedabout
1805
1806\startbuffer[b]
1807currentpicture := currentpicture
1808  reflectedabout(llcorner currentpicture,urcorner currentpicture) ;
1809\stopbuffer
1810
1811\page[preference] \typebuffer[b] \page[no]
1812
1813\startlinecorrection[blank]
1814\processMPbuffer[a,b,c]
1815\stoplinecorrection
1816
1817% reverse counterclockwise turningnumber
1818
1819A path has a certain direction. When the \type {turningnumber} of a path is
1820larger than zero, it runs in clockwise direction. The \METAPOST\ primitive \type
1821{reverse} changes the direction, while the macro \type {counterclockwise} can be
1822used to get a path running in a well defined direction.
1823
1824\startbuffer
1825drawoptions(withpen pencircle scaled 2pt withcolor .625red) ;
1826path p ; p := fullcircle scaled 1cm ;
1827drawarrow                          p ;
1828drawarrow reverse                  p shifted (2cm,0) ;
1829drawarrow counterclockwise         p shifted (4cm,0) ;
1830drawarrow counterclockwise reverse p shifted (6cm,0) ;
1831drawarrow reverse counterclockwise p shifted (8cm,0) ;
1832\stopbuffer
1833
1834\typebuffer
1835
1836\startlinecorrection[blank]
1837\processMPbuffer
1838\stoplinecorrection
1839
1840\stopsection
1841
1842\startsection[title={Only this far}]
1843
1844When you take a close look at the definitions of the Computer Modern Roman fonts,
1845defined in the \METAFONT\ book, you will notice a high level of abstraction.
1846Instead of hard coded points you will find points defined in terms of \quote
1847{being the same as this point} or \quote {touching that point}. In this section
1848we will spend some time on this touchy aspect.
1849
1850\startbuffer[a]
1851pickup pencircle scaled 2mm ;
1852path p ; p := fullsquare scaled 2cm ;
1853draw p withcolor .625white ;
1854\stopbuffer
1855
1856\startlinecorrection[blank]
1857\processMPbuffer[a]
1858\stoplinecorrection
1859
1860This rectangle is a scaled instance of the predefined \METAFUN\ path \type
1861{fullsquare} which is centered around the origin.
1862
1863\typebuffer[a]
1864
1865On this path, halfway between two of its corners, we define a point \type {q}:
1866
1867\startbuffer[b]
1868pair q ; q := .5[llcorner p, lrcorner p] ;
1869\stopbuffer
1870
1871\typebuffer[b]
1872
1873We draw this point in red, using:
1874
1875\startbuffer[c]
1876draw q withcolor .625red ;
1877\stopbuffer
1878
1879\typebuffer[c]
1880
1881As you can see, this point is drawn on top of the path.
1882
1883\startlinecorrection[blank]
1884\processMPbuffer[a,b,c]
1885\stoplinecorrection
1886
1887There are four of those midpoints, and when we connect them, we get:
1888
1889\startbuffer[c]
1890draw q -- q rotated 90 -- q rotated 180 --
1891  q rotated 270 -- cycle withcolor .625red ;
1892\stopbuffer
1893
1894\startlinecorrection[blank]
1895\processMPbuffer[a,b,c]
1896\stoplinecorrection
1897
1898Because path \type {p} is centered around the origin, we can simply rotate point
1899\type {q} a few times.
1900
1901\typebuffer[c]
1902
1903There are situations, where you don't want the red path to be drawn inside
1904another path, or more general: where you want points to touch instead of being
1905overlayed.
1906
1907\startlinecorrection[blank]
1908\processMPbuffer[a,b,c]
1909\stoplinecorrection
1910
1911We can achieve this by defining point \type {q} to be located on top of the
1912midpoint.
1913
1914\startbuffer[b]
1915pair q ; q := top .5[llcorner p, lrcorner p] ;
1916\stopbuffer
1917
1918\typebuffer[b]
1919
1920The predefined macro \type {top} moves the point over the distance similar to the
1921current pen width.
1922
1923\startlinecorrection[blank]
1924\processMPbuffer[a,b,c]
1925\stoplinecorrection
1926
1927Because we are dealing with two drawing operations, and since the path inside is
1928drawn through the center of points, we need to repeat this move in order to draw
1929the red path really inside the other one.
1930
1931\startbuffer[b]
1932pair q ; q := top top .5[llcorner p, lrcorner p] ;
1933\stopbuffer
1934
1935\typebuffer[b]
1936
1937Operations like \type {top} and its relatives \type {bot}, \type {lft} and \type
1938{rt} can be applied sequentally.
1939
1940\startlinecorrection[blank]
1941\processMPbuffer[a,b,c]
1942\stoplinecorrection
1943
1944We already showed that \type {q} was defined as a series of rotations.
1945
1946\typebuffer[c]
1947
1948As an intermezzo we will show an alternative definition of \type {q}. Because
1949each point is rotated 90 degrees more, we can define a macro that expands into
1950the point and rotates afterwards. Because each consecutive point on the path is
1951rotated an additional 90 degrees, we use the \METAPOST\ macro \type {hide} to
1952isolate the assignment. The \type {hide} command executes the hidden command and
1953afterwards continues as if it were never there. You must not confuse this with
1954grouping, since the hidden commands are visible to their surroundings.
1955
1956\startbuffer[c]
1957def qq = q hide(q := q rotated 90) enddef ;
1958draw qq -- qq -- qq -- qq -- cycle withcolor .625red ;
1959\stopbuffer
1960
1961\typebuffer[c]
1962
1963The macro \type {top} uses the characteristics of the current pen to determine
1964the displacement. However, for the more complicated pen shapes we need a
1965different trick to get an inside path. Let's start by defining an elliptical
1966path.
1967
1968\startbuffer[a]
1969pickup pencircle xscaled 3mm yscaled 5mm rotated 30 ;
1970path p ; p := fullcircle xscaled 6cm yscaled 3cm ;
1971draw p withcolor .625white ;
1972\stopbuffer
1973
1974\typebuffer[a]
1975
1976We draw this path using a non standard pen. In the \METAFONT\ manual you will
1977find methods to draw shapes with similar pens, where the pen is also turning, as
1978it does in real calligraphy. Here we stick to a more simple one.
1979
1980\startlinecorrection[blank]
1981\processMPbuffer[a]
1982\stoplinecorrection
1983
1984We construct the inner path from the points that make up the curve. Watch how we
1985use a for loop to compose the new path. When used this way, no semi colon may be
1986used to end the loop, since it would isolate the color directive.
1987
1988\startbuffer[b]
1989draw point 0 of p
1990  for i=1 upto length(p) : -- point (i) of p endfor
1991  withcolor .625red ;
1992\stopbuffer
1993
1994\typebuffer[b]
1995
1996The points are still located on the original path.
1997
1998\startlinecorrection[blank]
1999\processMPbuffer[a,b]
2000\stoplinecorrection
2001
2002We can move the points to the inside by shifting them over the penwidth in the
2003direction perpendicular to the point. Because we use this transformation more
2004than once, we wrap it into a macro. This also keeps the code readable.
2005
2006\startbuffer[b]
2007vardef inside expr pnt of p =
2008  (point pnt of p shifted
2009     -(penoffset direction pnt of p of currentpen))
2010enddef ;
2011draw inside 0 of p
2012  for i=1 upto length(p) : -- inside i of p endfor
2013  withcolor .625red ;
2014\stopbuffer
2015
2016\typebuffer[b]
2017
2018Whenever you define a pen, \METAPOST\ stores its characteristics in some private
2019variables which are used in the \type {top} and alike directives. The \type
2020{penoffset} is a built in primitive and is defined as the \quotation {point on
2021the pen furthest to the right of the given direction}. Deep down in \METAPOST\
2022pens are actually simple paths and therefore \METAPOST\ has a notion of a point
2023on the penpath. In the \METAFONT\ book and \METAPOST\ manual you can find in
2024depth discussions on pens.
2025
2026\startlinecorrection[blank]
2027\processMPbuffer[a,b]
2028\stoplinecorrection
2029
2030We're still not there. Like in a previous example, we need to shift over twice
2031the pen width. To get good results, we should determine the width of the pen at
2032that particular point, which is not trivial. The more general solution, which
2033permits us to specify the amount of shifting, is as follows.
2034
2035\startbuffer[b]
2036vardef penpoint expr pnt of p =
2037  save n, d ; numeric n, d ;
2038  (n,d) = if pair pnt : pnt else : (pnt,1) fi ;
2039  (point n of p shifted
2040     ((penoffset direction n of p of currentpen) scaled d))
2041enddef ;
2042\stopbuffer
2043
2044\typebuffer[b]
2045
2046When the point specification is extended with a distance, in which case we have a
2047pair expression, the point and distance are derived from this specification.
2048First we demonstrate the simple case:
2049
2050\startbuffer[c]
2051draw penpoint 0 of p
2052  for i=1 upto length(p)-1 : .. penpoint i of p endfor .. cycle
2053  withcolor .625red ;
2054\stopbuffer
2055
2056\typebuffer[c]
2057
2058\startlinecorrection[blank]
2059\processMPbuffer[a,b,c]
2060\stoplinecorrection
2061
2062In the next graphic, we draw both an inner and and outer path.
2063
2064\startbuffer[c]
2065draw penpoint (0,-2) of p
2066  for i=1 upto length(p)-1 : .. penpoint (i,-2) of p endfor .. cycle
2067  withcolor .625red ;
2068draw penpoint (0,+2) of p
2069  for i=1 upto length(p)-1 : .. penpoint (i,+2) of p endfor .. cycle
2070  withcolor .625yellow ;
2071\stopbuffer
2072
2073\typebuffer[c]
2074
2075\startlinecorrection[blank]
2076\processMPbuffer[a,b,c]
2077\stoplinecorrection
2078
2079\startbuffer[a]
2080path p, q, r ;
2081
2082p := fullcircle scaled 3cm ;
2083q := p shifted (7cm,0cm) ;
2084r := center p -- center q ;
2085\stopbuffer
2086
2087\startbuffer[b]
2088pair pr, qr ;
2089
2090pr := p intersectionpoint r ;
2091qr := q intersectionpoint r ;
2092
2093r := r cutbefore pr cutafter qr ;
2094\stopbuffer
2095
2096\startbuffer[c]
2097r := r cutbefore (point 5pt on r) ;
2098r := r cutafter (point -5pt on r) ;
2099\stopbuffer
2100
2101\startbuffer[cc]
2102r := r cutends 5pt ;
2103\stopbuffer
2104
2105\startbuffer[d]
2106draw p withpen pencircle scaled 10pt withcolor .625red ;
2107draw q withpen pencircle scaled 10pt withcolor .625yellow ;
2108draw r withpen pencircle scaled 20pt withcolor .625white ;
2109\stopbuffer
2110
2111\startbuffer[dd]
2112draw r withpen pencircle scaled 20pt withcolor .625white ;
2113draw p withpen pencircle scaled 10pt withcolor .625red ;
2114draw q withpen pencircle scaled 10pt withcolor .625yellow ;
2115\stopbuffer
2116
2117Another case when \type {top} and friends cannot be applied in a general way is
2118the following. Consider the three paths:
2119
2120\typebuffer[a]
2121
2122We draw these paths with:
2123
2124\typebuffer[d]
2125
2126The line is drawn from center to center and since the line has a non zero width
2127and a round line cap, it extends beyond this point.
2128
2129\startlinecorrection[blank]
2130\processMPbuffer[a,d]
2131\stoplinecorrection
2132
2133If we want the line to stop at the circular paths, we can cut off the pieces that
2134extend beyond those paths.
2135
2136\typebuffer[b]
2137
2138This time we get:
2139
2140\startlinecorrection[blank]
2141\processMPbuffer[a,b,d]
2142\stoplinecorrection
2143
2144Due to the thicker line width used when drawing the straight line, part of that
2145line is still visible inside the circles. So, we need to clip off a bit more.
2146
2147\typebuffer[c]
2148
2149The \type {point ... on} operation is a \METAFUN\ macro that takes a dimension.
2150
2151\startlinecorrection[blank]
2152\processMPbuffer[a,b,c,d]
2153\stoplinecorrection
2154
2155In order to save you some typing, \METAFUN\ provides a macro \type {cutends} that
2156does the same job:
2157
2158\typebuffer[cc]
2159
2160This time we draw the path in a different order:
2161
2162\typebuffer[dd]
2163
2164That way we hide the still remaining overlapping part of the line.
2165
2166\startlinecorrection[blank]
2167\processMPbuffer[a,b,cc,dd]
2168\stoplinecorrection
2169
2170\stopsection
2171
2172\startsection[title={Directions}]
2173
2174\index{directions}
2175
2176Quite often you have to tell \METAPOST\ in what direction a line should be drawn.
2177A direction is specified as a vector. There are four predefined vectors: \type
2178{up}, \type {down}, \type {left}, \type {right}. These are defined as follows:
2179
2180\starttyping
2181pair up, down, left, right ;
2182up = -down = (0,1) ; right = -left = (1,0) ;
2183\stoptyping
2184
2185We can use these predefined pairs as specifications and in calculations.
2186
2187\startbuffer
2188dotlabel.top("up"   , up    * 1cm) ;
2189dotlabel.bot("down" , down  * 1cm) ;
2190dotlabel.lft("left" , left  * 1cm) ;
2191dotlabel.rt ("right", right * 1cm) ;
2192
2193drawoptions (withpen pencircle scaled .25mm withcolor .625 red) ;
2194
2195drawarrow origin -- up    * 1cm ;
2196drawarrow origin -- down  * 1cm ;
2197drawarrow origin -- left  * 1cm ;
2198drawarrow origin -- right * 1cm ;
2199\stopbuffer
2200
2201\typebuffer
2202
2203\startlinecorrection[blank]
2204\processMPbuffer
2205\stoplinecorrection
2206
2207This graphic can also be defined in a more efficient (but probably more cryptic)
2208way. The next definition demonstrates a few nice tricks. Instead of looping over
2209the four directions, we loop over their names. Inside the loop we convert these
2210names, or strings, into a pair by scanning the string using \type {scantokens}.
2211The \type {freedotlabel} macro is part of \METAFUN\ and takes three arguments: a
2212label string (or alternatively a picture), a point (location), and the \quote
2213{center of gravity}. The label is positioned in the direction opposite to this
2214center of gravity.
2215
2216\startbuffer
2217pair destination ;
2218for whereto = "up", "down", "left", "right" :
2219  destination := scantokens(whereto) * 1cm ;
2220  freedotlabel(whereto, destination, origin) ;
2221  drawarrow origin -- destination
2222    withpen pencircle scaled .25mm withcolor .625 red ;
2223endfor ;
2224\stopbuffer
2225
2226\typebuffer
2227
2228So, in this code fragment, we use the string as string and (by means of \type
2229{scantokens}) as a point or vector.
2230
2231\startlinecorrection[blank]
2232\processMPbuffer
2233\stoplinecorrection
2234
2235The previous definition is a stepping stone to the next one. This time we don't
2236use points, but the \type {dir} command. This command converts an angle into an
2237unitvector.
2238
2239\startbuffer
2240pair destination ;
2241for whereto = 0 step 30 until 330 :
2242  destination := dir(whereto) * 1.5cm ;
2243  freedotlabel(decimal whereto, destination, origin) ;
2244  drawarrow origin -- destination
2245    withpen pencircle scaled .25mm withcolor .625 red ;
2246endfor ;
2247\stopbuffer
2248
2249\typebuffer
2250
2251In \METAPOST\ the angles go counter clockwise, which is not that illogical if you
2252look at it from the point of view of vector algebra.
2253
2254\startlinecorrection[blank]
2255\processMPbuffer
2256\stoplinecorrection
2257
2258\stopsection
2259
2260\startsection[title={Analyzing pictures}]
2261
2262\index{pictures+analyzing}
2263
2264{\em Unless you really want to know all details, you can safely skip this
2265section. The \METAPOST\ features discussed here are mainly of importance when you
2266write (advanced) macros.}
2267
2268% Later we will discuss in detail how you can use either \METAPOST\ or \TEX\ to
2269% typeset text (\in {section} [sec:text] and \in {chapter} [sec:typesetting]), so
2270% here we limit our exploration to a quick introduction. The most direct way of
2271% processing text in \METAPOST\ is using the \type {infont} operator.
2272%
2273% \startbuffer[mp]
2274% draw "this string will become a sequence of glyphs (MP)"
2275%   infont defaultfont scaled defaultscale ;
2276% \stopbuffer
2277%
2278% \typebuffer[mp]
2279%
2280% The text between \type {"} is passed to \TEX, and the resulting \DVI\ will be
2281% converted into a picture with textual components. So, we get:
2282%
2283% \startlinecorrection[blank]
2284% \midaligned{\processMPbuffer[mp]}
2285% \stoplinecorrection
2286%
2287% The same string typeset by \TEX\ shows up as:
2288%
2289% \blank
2290% \midaligned{this string will become a sequence of glyphs (\TeX)}
2291% \blank
2292%
2293% The following \METAPOST\ features are not covered by the \METAPOST\ manual, but
2294% most of them are discussed in the appendix of the \type {graph} package written
2295% by John Hobby.
2296%
2297%It is possible to disassemble a picture by means of a special for loop using the
2298%\type {within} specifier. The following code walks over a picture and draws the
2299%components with their bounding boxes.
2300%
2301% \startbuffer[show]
2302% for i within currentpicture :
2303%   draw boundingbox i withcolor .625yellow ;
2304% endfor ;
2305% \stopbuffer
2306%
2307% \typebuffer[show]
2308%
2309% We can use the disassemble loop feature to look into the previously shown
2310% example text.
2311%
2312% \startlinecorrection[blank]
2313% \processMPbuffer[mp,show]
2314% \stoplinecorrection
2315%
2316% The second line is typeset by \TEX. The resulting \DVI\ code is converted into a
2317% series of pictures, which \METAPOST\ pastes into one picture. You may also notice
2318% that in the set of pictures that originate in \TEX, the space is replaced by a
2319% shift (this is because \TEX\ knows no space).
2320%
2321% An interesting aspect of this \quote {loop over a picture} feature, is that it
2322% can provide insight in how \TEX\ is composing a paragraph.
2323%
2324% \startbuffer
2325% draw btex \framed[width=fit,align=middle]{\input tufte \relax} etex ;
2326% for i within currentpicture :
2327%   draw boundingbox i withpen pencircle scaled .2pt withcolor .625yellow ;
2328% endfor ;
2329% \stopbuffer
2330%
2331% \startlinecorrection[blank]
2332% \processMPbuffer
2333% \stoplinecorrection
2334%
2335% You may also notice, that rules produced by \TEX\ are converted to straight line
2336% segments. Because the line extends 50\% of its linewidth beyond a point, there is
2337% a slight overshoot. This picture was defined in a few lines:
2338%
2339% \typebuffer
2340%
2341% If we use a Times Roman instead of a Palatino, we get quite
2342% different results.
2343%
2344% \startlinecorrection[blank]
2345% \startMPenvironment
2346%   %\let\fontclass\empty
2347%   \usetypescript[times][texnansi]
2348%   \switchtobodyfont[times,10pt]
2349% \stopMPenvironment
2350% \processMPbuffer
2351% \stoplinecorrection
2352%
2353% In \CONTEXT, you can easily change the body font for
2354% \METAPOST\ graphics with directives like:
2355%
2356% \starttyping
2357% \startMPenvironment
2358%   \usetypescript[times][texnansi]
2359%   \switchtobodyfont[times,10pt]
2360% \stopMPenvironment
2361% \stoptyping
2362%
2363% This font has far less kerning. Even more interesting is the Lucida Bright
2364% Handwriting font, which is defined in such a way that no kerning is needed at
2365% all.
2366%
2367% \startlinecorrection[blank]
2368% \resetMPenvironment
2369% \startMPenvironment
2370%   %\let\fontclass\empty
2371%   \usetypescript[lucida][texnansi]
2372%   \switchtobodyfont[lucida,hw,10pt]
2373% \stopMPenvironment
2374% \processMPbuffer
2375% \stoplinecorrection
2376%
2377% You can ask for the number of components with \type {length}. A component can be
2378% a stroked or filled path, or a text resulting from an \type {infont} operation.
2379% If the (last) path is a clip path, or when the whole picture has a forced
2380% boundingbox, the picture is treated as a whole. We will demonstrate this later.
2381
2382We can decompose \METAPOST\ pictures using a \type {within} loop. You may wonder
2383if such a \type {within} loop construct has any real application, and as you can
2384expect, it has. In \in {section} [sec:color circles] a macro is defined that
2385draws a colored circle. If you want the inverted alternative, you can pass the
2386inverted color specification, but wouldn't it be more convenient if there was an
2387operator that did this for you automatically? Unfortunately there isn't one so we
2388have to define one ourselves in a macro.
2389
2390\startbuffer
2391colorcircle(4cm,(.4,.6,.8),(.4,.8,.6),(.6,.4,.8)) ;
2392addto currentpicture also inverted currentpicture shifted (5cm,0) ;
2393\stopbuffer
2394
2395\startlinecorrection[blank]
2396\processMPbuffer
2397\stoplinecorrection
2398
2399These circles were drawn using:
2400
2401\typebuffer
2402
2403When we \type {draw} a path, or stroke a path, as it is called officially, we
2404actually perform an addition:
2405
2406\starttyping
2407addto currentpicture doublepath somepath
2408\stoptyping
2409
2410The \type {fill} command is actually:
2411
2412\starttyping
2413addto currentpicture contour somepath
2414\stoptyping
2415
2416We will need both \type {doublepath} and \type {contour} operations in the
2417definition of \type {inverted}.
2418
2419When \METAPOST\ has digested a path into a picture, it keeps track of some
2420characteristics. We can ask for them using \type {part...} operators. The
2421following operators can be applied to a transform vector (one of \METAPOST's data
2422types), but also to a picture. Say that we have drawn a circle:
2423
2424\startbuffer[a]
2425draw fullcircle
2426  xscaled 3cm yscaled 2cm
2427  dashed dashpattern(on 3mm off 3mm)
2428  withpen pencircle scaled 1mm
2429  withcolor .625red ;
2430picture p ; p := currentpicture ;
2431\stopbuffer
2432
2433\typebuffer[a]
2434
2435This circle looks like:
2436
2437\startlinecorrection[blank]
2438\processMPbuffer[a]
2439\stoplinecorrection
2440
2441We can now ask for some of the characteristics of \type {currentpicture}, like
2442its color. We could write the values to the log file, but it is more convenient
2443to put them on paper.
2444
2445\startbuffer[b]
2446label.rt("redpart: "   & decimal redpart   p, (4cm,+.5cm)) ;
2447label.rt("greenpart: " & decimal greenpart p, (4cm,  0cm)) ;
2448label.rt("bluepart: "  & decimal bluepart  p, (4cm,-.5cm)) ;
2449\stopbuffer
2450
2451\typebuffer[b]
2452
2453Here the \type {&} glues strings together, while the decimal operator converts a
2454number into a string.
2455
2456The result has no typographic beauty |<|keep in mind that here we use \METAPOST\
2457to typeset the text|>|but the result serves its purpose.
2458
2459\startlinecorrection[blank]
2460\processMPbuffer[a,b]
2461\stoplinecorrection
2462
2463We can also ask for the path itself (\type {pathpart}), the pen (\type {penpart})
2464and the dashpattern (\type {dashpart}), but these can only be assigned to
2465variables of the corresponding type.
2466
2467A path can be stroked or filled, in which case it is a cyclic path. It can have a
2468non natural bounding box, be a clip path, consist of line segments or contain
2469text. All these characteristics can be tested.
2470
2471\startbuffer[b]
2472label.rt("filled: "  & condition filled         p, (4cm,+1.25cm)) ;
2473label.rt("stroked: " & condition stroked        p, (4cm,+0.75cm)) ;
2474label.rt("textual: " & condition textual        p, (4cm,+0.25cm)) ;
2475label.rt("clipped: " & condition clipped        p, (4cm,-0.25cm)) ;
2476label.rt("bounded: " & condition bounded        p, (4cm,-0.75cm)) ;
2477label.rt("cycle: "   & condition cycle pathpart p, (4cm,-1.25cm)) ;
2478\stopbuffer
2479
2480\typebuffer[b]
2481
2482\startlinecorrection[blank]
2483\processMPbuffer[a,b]
2484\stoplinecorrection
2485
2486In this code snippet, \type {condition} is a macro that takes care of translating
2487a boolean value into a string (like \type {decimal} does with a numeric value).
2488
2489\starttyping
2490def condition primary b =
2491  if b : "true" else : "false" fi
2492enddef ;
2493\stoptyping
2494
2495Clip paths and bounding boxes are kind of special in the sense that they can
2496obscure components. The following examples demonstrate this. In case of a clip
2497path or bounding box, the \type {pathpart} operator returns this path. In any
2498case that asking for a value does not make sense |<|a clipping path for instance
2499has no color|>| a zero (null) value is returned.
2500
2501\startbuffer[b]
2502n := 1 ;
2503for i within currentpicture : n := n + 1 ;
2504  label("n: "       & decimal           n & " / " &
2505        "length: "  & decimal   length  i & " / " &
2506        "stroked: " & condition stroked i & " / " &
2507        "clipped: " & condition clipped i & " / " &
2508        "bounded: " & condition bounded i , (0,-n*.5cm)) ;
2509endfor ;
2510\stopbuffer
2511
2512\startbuffer[c]
2513\startlinecorrection[blank]
2514\framed[offset=overlay,frame=off,background=color,backgroundcolor=gray]{\processMPbuffer[a,b]}
2515\stoplinecorrection
2516\stopbuffer
2517
2518\startbuffer[a]
2519draw      fullcircle withpen pencircle scaled 6mm ;
2520clip      currentpicture to fullcircle ;
2521setbounds currentpicture to fullcircle ;
2522\stopbuffer
2523
2524\typebuffer[a] \getbuffer[c]
2525
2526\startbuffer[a]
2527draw      fullcircle withpen pencircle scaled 6mm ;
2528setbounds currentpicture to fullcircle ;
2529clip      currentpicture to fullcircle ;
2530\stopbuffer
2531
2532\typebuffer[a] \getbuffer[c]
2533
2534\startbuffer[a]
2535clip      currentpicture to fullcircle ;
2536draw      fullcircle withpen pencircle scaled 6mm ;
2537setbounds currentpicture to fullcircle ;
2538\stopbuffer
2539
2540\typebuffer[a] \getbuffer[c]
2541
2542\startbuffer[a]
2543clip      currentpicture to fullcircle ;
2544setbounds currentpicture to fullcircle ;
2545draw      fullcircle withpen pencircle scaled 6mm ;
2546\stopbuffer
2547
2548\typebuffer[a] \getbuffer[c]
2549
2550\startbuffer[a]
2551setbounds currentpicture to fullcircle ;
2552clip      currentpicture to fullcircle ;
2553draw      fullcircle withpen pencircle scaled 6mm ;
2554\stopbuffer
2555
2556\typebuffer[a] \getbuffer[c]
2557
2558\startbuffer[a]
2559setbounds currentpicture to fullcircle ;
2560draw      fullcircle withpen pencircle scaled 6mm ;
2561clip      currentpicture to fullcircle ;
2562\stopbuffer
2563
2564\typebuffer[a] \getbuffer[c]
2565
2566The description lines were generated by the following loop:
2567
2568\typebuffer[b]
2569
2570% % The following is no longer valid in MetaFun:
2571%
2572% If we have a textual picture, we can also ask for the text and font. Take the
2573% following picture:
2574%
2575% \startbuffer[a]
2576% picture p ;
2577% p := "MetaFun" normalinfont "rm-lmr10" scaled 2 rotated 30 slanted .5 ;
2578% p := p shifted (0,-ypart center p) ;
2579% currentpicture := p ;
2580% \stopbuffer
2581%
2582% \typebuffer[a]
2583%
2584% Here we can ask for:
2585%
2586% \startbuffer[b]
2587% label.rt("textpart: " & textpart p, (4cm,+0.25cm)) ;
2588% label.rt("fontpart: " & fontpart p, (4cm,-0.25cm)) ;
2589% \stopbuffer
2590%
2591% \typebuffer[b]
2592%
2593% and get:
2594%
2595% \startlinecorrection[blank]
2596% \processMPbuffer[a,b]
2597% \stoplinecorrection
2598%
2599% We use \type {normalinfont} instead of \type {infont} because in \METAFUN\ this
2600% operator is overloaded and follows another route for including text.
2601%
2602% If we're dealing with a path, the transformations have ended up in the path
2603% specification. If we have a text picture, we can explicitly ask for the transform
2604% components.
2605%
2606% \startbuffer[b]
2607% label.rt("xpart: "  & decimal xpart  p, (4cm,+1.25cm)) ;
2608% label.rt("ypart: "  & decimal ypart  p, (4cm,+0.75cm)) ;
2609% label.rt("xxpart: " & decimal xxpart p, (4cm,+0.25cm)) ;
2610% label.rt("xypart: " & decimal xypart p, (4cm,-0.25cm)) ;
2611% label.rt("yxpart: " & decimal yxpart p, (4cm,-0.75cm)) ;
2612% label.rt("yypart: " & decimal yypart p, (4cm,-1.25cm)) ;
2613% \stopbuffer
2614%
2615% \typebuffer[b]
2616%
2617% \startlinecorrection[blank]
2618% \processMPbuffer[a,b]
2619% \stoplinecorrection
2620%
2621% We will now define the \type {inverted} macro using these primitives. Because we
2622% have to return a picture, we cannot use \type {draw} and \type {fill} but need to
2623% use the low level operators. Because a picture can consist of more than one path,
2624% we need a temporary picture \type {pp}.
2625%
2626% \starttyping
2627% vardef inverted expr p =
2628%   save pp ; picture pp ; pp := nullpicture ;
2629%   for i within p :
2630%     addto pp
2631%     if stroked i or filled i :
2632%       if filled i : contour else : doublepath fi pathpart i
2633%       dashed dashpart i withpen penpart i
2634%     else :
2635%       also i
2636%     fi
2637%     withcolor white-(redpart i, greenpart i, bluepart i) ;
2638%   endfor ;
2639%   pp
2640% enddef ;
2641% \stoptyping
2642%
2643% We probably need to handle a few more border cases, but for general purposes,
2644% this macro works as expected.
2645
2646The textual capabilities built in \METAPOST\ are rather limited but in \CONTEXT\
2647we have overloaded the relevant operators. There we hook into the normal font
2648handler. The native text related operators are:
2649
2650\starttyping
2651draw "MetaFun" infont "somefont" scaled 2 rotated 30 slanted .5 ;
2652draw btex MetaFun etex scaled 2 rotated 30 slanted .5 ;
2653\stoptyping
2654
2655The \type {infont} operator directly calls for a font and in stock \METAPOST\ is
2656limited to (eight bit) \TYPEONE\ fonts. In \CONTEXT\ you can do this:
2657
2658\startbuffer[a]
2659draw "MetaFun" infont "SerifBold*default" xscaled 5 rotated 5 slanted .5 ;
2660\stopbuffer
2661
2662\typebuffer[a]
2663
2664The specification is a regular \CONTEXT\ font specification.
2665
2666\startlinecorrection[blank]
2667\processMPbuffer[a]
2668\stoplinecorrection
2669
2670The \type {btex ... etex} variant in normal \METAPOST\ delegates to \TEX\ and in \MKII\
2671indeed we filter them and process them between runs (or at runtime). In \MKIV\ they are
2672also handled by \TEX\ but in an even more integrated and immediate way.
2673
2674The two primitives \type {textpart} and \type {fontpart} that can be used to disassemble
2675a picture don't apply to \METAFUN\ as contrary to \METAPOST\ we don't convert the result
2676to a picture. In later chapters we will discuss text in more detail.
2677
2678From the previous examples it may be clear that each picture has some associated
2679data stored with it. From the \type {bounded} boolean test we can conclude that
2680the bounding box is part of this data. Internally \METAPOST\ keeps track of two
2681bounding boxes: the natural one, and the forced one. The forced one is actually a
2682component of the picture which applies to all previously added graphics. You can
2683calculate the bounding box from the \type {llcorner} and \type {urcorner} or if
2684you like \type {ulcorner} and \type {lrcorner} and the \METAFUN\ command \type
2685{boundingbox} does so.
2686
2687The four corners that make up the bounding box are either the natural ones, or
2688the ones forced by \type {setbounds}. You can force \METAPOST\ to report the
2689natural ones by setting \type {truecorners} to~1. The next example demonstrates
2690this feature.
2691
2692\startbuffer
2693pickup pencircle scaled 2mm ; path p, q ;
2694draw fullcircle
2695  scaled 4cm slanted .5 withcolor .625white ;
2696setbounds currentpicture to
2697  boundingbox currentpicture enlarged -5mm ;
2698interim truecorners := 0 ; p := boundingbox currentpicture ;
2699interim truecorners := 1 ; q := boundingbox currentpicture ;
2700pickup pencircle scaled 1mm ;
2701draw p withcolor .625red ;
2702draw q withcolor .625yellow ;
2703\stopbuffer
2704
2705\typebuffer
2706
2707We use \type {interim} because \type {truecorners} is an internal \METAPOST\
2708variable.
2709
2710\startlinecorrection[blank]
2711\processMPbuffer
2712\stoplinecorrection
2713
2714% % we already redefined infont so it's kind of dangerous to provide this example
2715%
2716% Since \METAPOST\ can handle fonts (it can even generate font metric files) it is
2717% no surprise that we can also ask for the natural size of a font. For this we use
2718% \type {fontsize}. However, you should beware of the fact that the size reported
2719% is in base points. Since this is \METAPOST's native unit, this is no problem in
2720% calculations, but it may look confusing when you \type {show} this size on your
2721% terminal and get less that 10 reported for a \type {cmr10} font.
2722%
2723% \starttyping
2724% show fontsize "cmr10" ;
2725% \stoptyping
2726%
2727% In order to demonstrate that \type {fontsize} is useful, we extend the \type
2728% {infont} command. In the process we show a few macro definition tricks. What we
2729% want is a \TEX\ like specification of a font size:
2730%
2731% \startbuffer[txt]
2732% draw "MetaFun" infont defaultfont at 20pt ;
2733% \stopbuffer
2734%
2735% \typebuffer[txt]
2736%
2737% We can store the current meaning of a primitive or macro in a new macro. We do so
2738% with \type {infont}:
2739%
2740% \startbuffer[a]
2741% let normalinfont = infont ;
2742% \stopbuffer
2743%
2744% \typebuffer[a]
2745%
2746% We can only know the size if we know the name of the font, so we have to redefine
2747% \type {infont} to pick up this name.
2748%
2749% \startbuffer[b]
2750% numeric lastfontsize ; lastfontsize = fontsize defaultfont ;
2751% \stopbuffer
2752%
2753% \startbuffer[c]
2754% primarydef infont primary name = % patched: def should work too
2755%   hide(lastfontsize := fontsize name)
2756%   normalinfont name
2757% enddef ;
2758% \stopbuffer
2759%
2760% \typebuffer[c]
2761%
2762% Because we are replacing an operator, and since \METAPOST\ expects one, we have
2763% to use \type {def} instead of \type {vardef} (which is actually a kind of
2764% variable). For the same reason, we have to pick up a \type {primary}. If we would
2765% use a \typ {expr name}, we would end up in an unwanted look ahead. The \type
2766% {hide} macro hides the assignment and makes this macro behave like a \type
2767% {vardef} with respect to hiding expressions. We may not put a semi colon after
2768% the \type {)} because it would stop \METAPOST\ from reading on, and thereby
2769% invoke an error message.
2770%
2771% We can now define \type {at}. This macro picks up an expression (which can be
2772% more than just a number) and return a scale transform that normalizes the given
2773% size to the design size.
2774%
2775% \startbuffer[d]
2776% def at expr size =
2777%   scaled (size/lastfontsize)
2778% enddef ;
2779% \stopbuffer
2780%
2781% \typebuffer[d]
2782%
2783% Because this macro is defined global, and therefore can be used apart from \type
2784% {infont}, we predefine the size:
2785%
2786% \typebuffer[b]
2787%
2788% When defined this way \type {at} a comfortable 20 points, the string \type
2789% {MetaFun} comes out as follows:
2790%
2791% \startlinecorrection[blank]
2792% \processMPbuffer[a,b,c,d,txt]
2793% \stoplinecorrection
2794
2795\stopsection
2796
2797\startsection[title={Filling}]
2798
2799\index{filling}
2800\index{reversing}
2801
2802In most cases a path ends up being drawn or filled. When filling a path, it
2803doesn't matter in what direction the path runs, as long as it's closed you're
2804fine. You can however change the direction any time along the path. Here is an
2805example of what happens when you fill a path that is partially reversed.
2806
2807\startbuffer
2808fill fullsquare rotated 45 scaled 2cm
2809    withcolor .625 red ;
2810fill fullcircle scaled 2cm -- reverse fullcircle scaled 1cm -- cycle
2811    withcolor .625 yellow ;
2812\stopbuffer
2813
2814\typebuffer
2815
2816You'll notice that the inner circle is not filled:
2817
2818\startlinecorrection[blank]
2819\processMPbuffer
2820\stoplinecorrection
2821
2822Now watch the following:
2823
2824\startbuffer
2825fill
2826    fullsquare rotated 45 scaled 2cm
2827 -- fullcircle scaled 2cm
2828 -- cycle
2829    withcolor .625 red ;
2830\stopbuffer
2831
2832\typebuffer
2833
2834This results in:
2835
2836\startlinecorrection[blank]
2837\processMPbuffer
2838\stoplinecorrection
2839
2840Compare this with:
2841
2842\startbuffer
2843fill
2844    fullsquare rotated 45 scaled 2cm
2845 -- reverse fullcircle scaled 2cm -- cycle
2846 -- cycle
2847    withcolor .625 red ;
2848\stopbuffer
2849
2850\typebuffer
2851
2852giving:
2853
2854\startlinecorrection[blank]
2855\processMPbuffer
2856\stoplinecorrection
2857
2858The normal filling happens according to the non||zero winding rule. An alternative is the
2859odd||even rule. There we don't need the reverse trick:
2860
2861\startbuffer
2862eofill fullsquare rotated 45 scaled 2cm
2863 -- fullcircle scaled 2cm -- cycle
2864    withcolor .625 red ;
2865\stopbuffer
2866
2867\typebuffer
2868
2869The \type {eofill} is a \METAFUN\ extension. Hopefully the next explains a bit
2870how this works (you can find explanations on the Internet).
2871
2872\startlinecorrection[blank]
2873\processMPbuffer
2874\stoplinecorrection
2875
2876\startuseMPgraphic{demo}
2877    def DrawIt(text how) =
2878        path p ; p := ((0,0) .. (1,0) .. (1,1) .. (0,1) .. (1,0) .. (2,1) .. cycle) scaled 2cm ;
2879        how p withcolor .625 yellow ;
2880        draw p withcolor .625 red ;
2881        for i=0 step 0.05 until 1  :
2882            fill arrowheadonpath (p,i)
2883            withcolor .625 red ;
2884        endfor ;
2885        draw  (0.5,0.5) scaled 2cm                 withpen pencircle scaled .5mm withcolor .375 white ;
2886        draw ((0.5,0.5) scaled 2cm -- llcorner p)  withpen pencircle scaled .5mm withcolor .375 white ;
2887        draw  (1.5,1.5) scaled 2cm                 withpen pencircle scaled .5mm withcolor .375 white ;
2888        draw ((1.5,1.5) scaled 2cm -- urcorner p)  withpen pencircle scaled .5mm withcolor .375 white ;
2889    enddef ;
2890\stopuseMPgraphic
2891
2892\startlinecorrection[blank]
2893    \startcombination[distance=4em]
2894      {\startMPcode \includeMPgraphic{demo} DrawIt(eofill) \stopMPcode} {\type{eofill}}
2895      {\startMPcode \includeMPgraphic{demo} DrawIt(fill)   \stopMPcode} {\type{fill}}
2896    \stopcombination
2897\stoplinecorrection
2898
2899In the case of a normal fill, the non||zero winding rule is applied: a winding
2900number is calculated by subtracting 1 each time the line (from inside an area to
2901someplace outside) is crossed clockwise while 1 is added each time we cross
2902anti||clockwise. When the total is non zero the area is filled. Here we run in one
2903direction and therefore we always get a fill. In the previous example where we
2904used a reverse, an anti||clockwise crossing was nilled by a clockwise one.
2905
2906The leftmost shape uses \type {eofill} and therefore the odd||even rule gets
2907applied. This time we follow the line and when it gets crossed en even number of
2908times the area will not be filled.
2909
2910Here is another example:
2911
2912\startbuffer
2913eofill for i=1 upto 12: fullcircle scaled ((i/12)*cm) -- endfor cycle ;
2914\stopbuffer
2915
2916\typebuffer
2917
2918The successive larger circle are unfilled and basically form one path:
2919
2920\startlinecorrection[blank]
2921\processMPbuffer
2922\stoplinecorrection
2923
2924A glyph is often constructed from more than one path and eventually the shape is
2925filled with an odd||even fill (\type {eofill}) operation. Take the following
2926sequence:
2927
2928\startbuffer
2929pickup pencircle scaled 1mm ;
2930draw fullsquare scaled 2cm ;
2931draw fullsquare scaled 2cm shifted (1cm,0) ;
2932draw fullsquare scaled 2cm shifted (0,1cm) ;
2933\stopbuffer
2934
2935\typebuffer
2936
2937\startlinecorrection[blank]
2938\processMPbuffer
2939\stoplinecorrection
2940
2941We can use a sequence of \type {nofill} ending with a \type {eofill} to create
2942a combined shape. This is not done in \METAPOST\ but in the backend.
2943
2944\startbuffer
2945nofill fullsquare scaled 2cm ;
2946nofill fullsquare scaled 2cm shifted (1cm,0) ;
2947eofill fullsquare scaled 2cm shifted (0,1cm) ;
2948\stopbuffer
2949
2950\typebuffer
2951
2952\startlinecorrection[blank]
2953\processMPbuffer
2954\stoplinecorrection
2955
2956As this is used for glyphs, we demonstrate this mechanism with a simple \type {O}
2957shape:
2958
2959\startbuffer
2960nofill fullcircle xyscaled (2cm,3cm) ;
2961eofill fullcircle xyscaled (1cm,2cm) ;
2962\stopbuffer
2963
2964\typebuffer
2965
2966\startlinecorrection[blank]
2967\processMPbuffer
2968\stoplinecorrection
2969
2970Another backend related feature is \type {fillup}. This is just a combination
2971of a fill and a draw in one go. It can save some bytes in the output file.
2972
2973\startbuffer
2974draw image (
2975    pickup pencircle scaled 5mm ;
2976    fill   fullsquare scaled 2cm ;
2977    draw   fullsquare scaled 2cm ;
2978    fillup fullsquare scaled 2cm shifted (4cm,0) ;
2979) withcolor .625red ;
2980\stopbuffer
2981
2982\typebuffer
2983
2984\startlinecorrection[blank]
2985\processMPbuffer
2986\stoplinecorrection
2987
2988\stopsection
2989
2990\startsection[title={Pitfalls}]
2991
2992When writing macros, you need to be careful in what
2993operations apply to what object. There is for instance a
2994difference between the following code:
2995
2996\startbuffer
2997pickup pencircle scaled 2pt ;
2998draw  (0,0)--(0,1)--(1,1)  scaled 1cm withcolor .625 red ;
2999draw ((0,0)--(0,1)--(1,1)) scaled 2cm withcolor .625 yellow ;
3000\stopbuffer
3001
3002\typebuffer
3003
3004\startlinecorrection[blank]
3005\processMPbuffer
3006\stoplinecorrection
3007
3008The \type {scaled} operates on the previous expression which in the first case is
3009the point \type {(1,1)} and in the second case the whole path.
3010
3011\startbuffer
3012pickup pencircle scaled 2pt ;
3013draw  (0,0)--(0,1)--(1,1)--cycle  scaled 1cm withcolor .625 red ;
3014draw ((0,0)--(0,1)--(1,1)--cycle) scaled 2cm withcolor .625 yellow ;
3015\stopbuffer
3016
3017\typebuffer
3018
3019\startlinecorrection[blank]
3020\processMPbuffer
3021\stoplinecorrection
3022
3023Here the last element in the first case is not the cycle, and the next
3024alternative does not help us much in discovering what is going on. (Well, at
3025least something {\em is} going on, because the result seems to have some
3026dimensions.)
3027
3028\startbuffer
3029pickup pencircle scaled 2pt ;
3030draw  (1,1)--cycle  scaled 1cm withcolor .625 red ;
3031draw ((1,1)--cycle) scaled 1cm withcolor .625 yellow ;
3032\stopbuffer
3033
3034\typebuffer
3035
3036\startlinecorrection[blank]
3037\processMPbuffer
3038\stoplinecorrection
3039
3040The next lines demonstrate that we're dealing with the dark sides of \METAPOST,
3041and from that we may conclude that in case of doubt it's best to add parenthesis
3042when such fuzzy situations threaten to occur.
3043
3044\startbuffer
3045pickup pencircle scaled 2pt ;
3046draw  (0,1)--(1,1)--cycle  scaled 1cm withcolor .625 red ;
3047draw ((0,1)--(1,1)--cycle) scaled 1cm withcolor .625 yellow ;
3048\stopbuffer
3049
3050\typebuffer
3051
3052\startlinecorrection[blank]
3053\processMPbuffer
3054\stoplinecorrection
3055
3056There are more cases where the result may surprise you. Take the following code:
3057
3058\startbuffer
3059drawarrow ((0,0)--(10,0))
3060  withpen pencircle scaled 2pt
3061  withcolor red randomized (.4,.9) ;
3062currentpicture := currentpicture scaled 8 ;
3063\stopbuffer
3064
3065\typebuffer
3066
3067\startlinecorrection[blank]
3068\processMPbuffer
3069\stoplinecorrection
3070
3071The arrow is made up out of two pieces and each piece gets a different shade of
3072red. This is because the attributes are collected and applied to each of the
3073components that make up the arrow. Because for each component the attribute code
3074is expanded again, we get two random colors. One way around this is to apply the
3075color afterwards.
3076
3077\startbuffer
3078draw
3079  image (drawarrow ((0,0)--(10,0)) withpen pencircle scaled 2pt)
3080  scaled 8 withcolor red randomized (.4,.9) ;
3081\stopbuffer
3082
3083\typebuffer
3084
3085\startlinecorrection[blank]
3086\processMPbuffer
3087\stoplinecorrection
3088
3089Here the \type {image} macro creates a picture and as you can see, this provides
3090a way to draw within a draw operation.
3091
3092Once you see the benefits of \type {image}, you will use it frequently. Another
3093handy (at first sight strange) macro is \type {hide}. You can use this in
3094situations where you don't want code to interfere.
3095
3096\starttyping
3097def mydraw text t =
3098  boolean error ; error := false ;
3099  def withpencil expr p = hide (error := true) enddef ;
3100  draw t ;
3101  if error : message "pencils are not supported here" fi ;
3102enddef ;
3103mydraw fullcircle scaled 10cm withpencil sharp ;
3104\stoptyping
3105
3106Here, setting the boolean normally interferes with the draw operation, but by
3107hiding the assignment, this code becomes valid. This code will bring the message
3108to your terminal and log file.
3109
3110Once you start using expressions you have a good chance of encountering messages
3111with regard to redundant expressions. The following code is for instance a
3112recipe for problems:
3113
3114\starttyping
3115z1 = (1,0) ; z1 = (2,0) ;
3116\stoptyping
3117
3118Changing the \type {=} into \type {:=} helps, but this may not be what you want.
3119
3120Because the \type {z}||variables are used frequently, they are reset each figure.
3121You can also reset them yourself, using the \type {clearxy} macro. The \METAFUN\
3122version clears all \type {z}||variables, unless you explictly specify what
3123variables to reset. \footnote {This version resulted from a discussion on the
3124\METAFONT\ discussion list and is due to Bogus\l{}aw Jackowski.} If you want to
3125play with this macro, see what happens when you run the following code:
3126
3127\starttyping
3128show x0 ; z0 = (10,10) ;
3129show x0 ; x0 := whatever ; y0 := whatever ;
3130show x0 ; z0 = (20,20) ;
3131show x0 ; clearxy 0 ;
3132show x0 ; z0 = (30,30) ;
3133\stoptyping
3134
3135So, the following calls are all legal:
3136
3137\starttyping
3138clearxy ; clearxy 1 ; clearxy 1, 8, 10 ;
3139\stoptyping
3140
3141Keep in mind that for each figure a full clear is done anyway. You should not
3142confuse this command with \type {clearit}, which clears \type {currentpicture}.
3143
3144\stopsection
3145
3146\startsection[title={\TeX\ versus \MetaPost}]
3147
3148If you are defining your own \TEX\ and \METAPOST\ macros, you will notice that
3149there are a couple of essential differences between the two macro languages. In
3150\TEX\ the following code is invalid. \footnote {In \ETEX\ the calculation can be
3151done in less lines using a \type {\numexpr}.}
3152
3153\starttyping
3154\def\fancyplied#1%
3155  {\ifnum#1=0
3156     \message{zero argument}%
3157   \fi
3158   \count0=#1 \multiply \count0 by \count0
3159   \count2=#1 \multiply \count2 by 2
3160   \count4=#1 \divide   \count4 by 2
3161   \advance \count0 by \count2
3162   \advance \count0 by \count4
3163   \count4 }
3164\hskip \fancyplied{3} pt
3165\stoptyping
3166
3167This is because \TEX\ is very strict in what tokens it expects next. In
3168\METAPOST\ however, you can use \type {vardef}'d macros to hide nasty
3169intermediate calculations.
3170
3171\starttyping
3172vardef fancyplied expr x =
3173  if x=0 : message "x is zero" ; (x*x+2x+x/2)
3174enddef ;
3175a := a shifted (fancyplied 3pt,0) ;
3176\stoptyping
3177
3178Hiding intermediate calculations and manipulations is a very strong point of
3179\METAPOST.
3180
3181Another important difference between both languages is the way grouping is
3182implemented. Because \TEX\ is dealing with a flow of information, strong grouping
3183is a must and therefore part of the language. Occasionally you run into
3184situations where you wished that you could reach over a group (for instance in
3185order to pass a value).
3186
3187In \METAPOST\ grouping behaves quite different. First of all, it provides the
3188mechanism that hides processing from the current flow. The previously mentioned
3189\type {vardef} is implicitly grouped. Contrary to \TEX, in \METAPOST\ all
3190assignments are global by default, even in a group. If you assign a variable
3191inside a group it is persistent unless you first save the variable (or macro)
3192using the \type {save} operator.
3193
3194So, in the next code snippet, the value of \type {\value} inside the box is {\em
3195no} but after the box is typeset, it will be {\em yes} again.
3196
3197\starttyping
3198\def\value{yes} \hbox{\def\value{no}\value} \value
3199\stoptyping
3200
3201To make a value local in \METAPOST, the following code is needed.
3202
3203\starttyping
3204string value ; value := "yes" ;
3205def intermezzo
3206  begingroup ;
3207    save value ; string value ; value := "no" ;
3208  endgroup ;
3209enddef ;
3210\stoptyping
3211
3212Once you start writing your own \METAPOST\ macros, you will appreciate this
3213\quote {always global} behaviour. As with other differences between the two
3214languages, they make sense if you look at what the programs are supposed to do.
3215
3216\stopsection
3217
3218\startsection[title={Internals and Interims}]
3219
3220\index{internals}
3221\index{interims}
3222
3223Related to grouping is the internal numeric datatype. When numeric variables are
3224defined as interim, you can quickly overload them inside a group.
3225
3226\starttyping
3227newinternal mynumber ; mynumber := 1 ;
3228
3229begingroup ; ... interim mynumber := 0 ; ... ; endgroup ;
3230\stoptyping
3231
3232You can only \type {interim} a variable if it is already defined using \type
3233{newinternal}.
3234
3235Among the \METAPOST\ macros is one called \type {drawdot}. This macro is kind of
3236redundant because, at least at first sight, you can use draw to achieve the same
3237result. There is however a very subtle difference: a dot is slightly larger than
3238a drawn point. We guess that it's about the device pixel, so you may not even
3239notice it. It may even be due to differences in accuracy of the methods to render
3240them.
3241
3242\startbuffer
3243pickup pencircle scaled 50pt ;
3244drawdot origin shifted (-120pt,0) ; draw origin shifted (-60pt,0) ;
3245drawdot origin ; draw origin withcolor white ;
3246setbounds currentpicture to boundingbox currentpicture enlarged 1pt ;
3247\stopbuffer
3248
3249\typebuffer
3250
3251\startlinecorrection[blank]
3252\processMPbuffer
3253\stoplinecorrection
3254
3255\stopsection
3256
3257\startsection[title=Named colors]
3258
3259The \type {withcolor} operator accepts a color expression but in \METAFUN\ it
3260also accepts a string indicating a color defined at the \TEX\ end. Most helpers
3261that deal with colors are able to deal with named colors as well. Here are some
3262examples. First we define a few colors:
3263
3264\startbuffer
3265\definecolor[MyColor1][r=.5]
3266\definecolor[MyColor2][g=.5]
3267\definecolor[MyColor3][b=.5]
3268\definecolor[MyColor4][s=.8]
3269\stopbuffer
3270
3271\typebuffer \getbuffer
3272
3273Here we access them:
3274
3275\startbuffer
3276fill fullcircle scaled 12 withcolor "MyColor1" ;
3277fill fullcircle scaled 10 withcolor "MyColor2" ;
3278fill fullcircle scaled  8 withcolor complementary "MyColor3" ;
3279fill fullcircle scaled  6 withcolor complemented "MyColor3" ;
3280fill fullcircle scaled  4 withcolor "MyColor4" randomized 2 ;
3281fill fullcircle scaled  2 withcolor "MyColor4" randomized 2 ;
3282addbackground
3283    withcolor .5[resolvedcolor("MyColor4"),resolvedcolor("MyColor2")] ;
3284currentpicture := currentpicture ysized 4cm ;
3285\stopbuffer
3286
3287\typebuffer
3288
3289And get:
3290
3291\startlinecorrection[blank]
3292\processMPbuffer
3293\stoplinecorrection
3294
3295\stopsection
3296
3297\startsection[title=Formatted text]
3298
3299Text support in \METAFUN\ has evolved quite a bit over years. For compatibility
3300reasons we keep old methods around but in practice one can probably do all with
3301the following:
3302
3303\starttabulate[|T|p|]
3304\NC textext[.anchor](str)        \NC position a text relative to the origin \NC \NR
3305\NC thetextext[.anchor](str,pos) \NC position a text relative to the given position \NC \NR
3306\NC rawtextext[.anchor](str,pos) \NC idem but with less checking \NC \NR
3307\stoptabulate
3308
3309If needed all functionality could be combined in one call (textext) but we keep
3310it this way.
3311
3312You need to keep in mind that text in \METAPOST\ is not a first class object but
3313something virtual that is known to \METAFUN\ as something with path like properties
3314but is actually dealt with in the backend. This means that timing is important.
3315
3316\starttyping
3317\startMPinitializations
3318picture p ; p := image(draw textext("Foo"););
3319\stopMPinitializations
3320
3321\startMPcode
3322    picture q ; q := image(draw textext("Bar"););
3323    picture r ; r := image(draw textext("Gnu"););
3324    draw p ;
3325    draw q shifted (2cm,0) ;
3326    draw r shifted (4cm,0) ;
3327\stopMPcode
3328\stoptyping
3329
3330This will work out well because an initialization is part of a figure, but
3331this will fail:
3332
3333\starttyping
3334\startMPinclusions
3335picture p ; p := image(draw textext("Foo"););
3336\stopMPinclusions
3337\stoptyping
3338
3339because inclusions happen before the local textexts get initialized and
3340due to the multipass implementation are not seeN a second time. The order of
3341processing is:
3342
3343\starttabulate[|l|c|c|]
3344\BC action          \BC first pass  \BC second pass \NC \NR
3345\NC definitions     \NC yes \NC     \NC \NR
3346\NC extensions      \NC yes \NC     \NC \NR
3347\NC inclusions      \NC yes \NC     \NC \NR
3348\NC begin figure    \NC yes \NC yes \NC \NR
3349\NC initializations \NC yes \NC yes \NC \NR
3350\NC metapost code   \NC yes \NC yes \NC \NR
3351\NC end figure      \NC yes \NC yes \NC \NR
3352\stoptabulate
3353
3354The graph package (that comes with \METAPOST) has some pseudo typesetting on
3355board needed to format numbers. Because we don't want to interfere with the
3356definitions of macros used in that package we provide another set of macros for
3357formatting: \type {fmttext}, \type {thefmttext} and \type {rawfmttext}.
3358
3359\startbuffer
3360\startMPcode
3361draw thefmttext("\bf@3.2f done",123.45678) withcolor darkred ;
3362\stopMPcode
3363\stopbuffer
3364
3365\typebuffer
3366
3367Here we pass one variable to the format but there can be more: \inlinebuffer. In
3368\LUA\ the \type {%} is used as format directive but that does not work well in
3369\TEX\ and \LUA\ which is why we use \type {@} instead. The formatting is done
3370with the formatters subsystem which is an extension to the regular \LUA\ \type
3371{format} function. More information can be found in \type {clf-mkiv.pdf} but one
3372extension is not mentioned there: \type {%!texexp!}. This directive takes one
3373argument by default but optionally can take one or two extra arguments: the
3374format of the base number and one for the exponent. The following code
3375demonstrates this:
3376
3377\startbuffer
3378\startMPcode{doublefun}
3379draw image (
3380  draw thefmttext.rt("@!texexp!", 10.4698E30,              (0,-1LineHeight)) ;
3381  draw thefmttext.rt("@1!texexp!",10.4698E30,              (0,-2LineHeight)) ;
3382  draw thefmttext.rt("@2!texexp!",10.4698E30,"@2.3f",      (0,-3LineHeight)) ;
3383  draw thefmttext.rt("@3!texexp!",10.4698E30,false,"@2i",  (0,-4LineHeight)) ;
3384  draw thefmttext.rt("@3!texexp!",10.4698E30,"@2.3f","@2i",(0,-5LineHeight)) ;
3385) withcolor darkblue ;
3386\stopMPcode
3387\stopbuffer
3388
3389\typebuffer
3390
3391We switch to double mode because we use large numbers.
3392
3393\startlinecorrection[blank]
3394    \getbuffer
3395\stoplinecorrection
3396
3397Of course this extra formatter is also supported in the \type {context}
3398command:
3399
3400\startbuffer
3401\startluacode
3402context("%!texexp!, ",    10.4698E30)
3403context("%1!texexp!, ",   10.4698E30)
3404context("%2!texexp!, ",   10.4698E30,"@2.3f")
3405context("%3!texexp! and ",10.4698E30,false,"@2i")
3406context("%3!texexp!",     10.4698E30,"@2.3f","@2i")
3407\stopluacode
3408\stopbuffer
3409
3410\typebuffer
3411
3412This gives: \inlinebuffer . In \in {figure} [fig:formatters] we see some more
3413formatters.
3414
3415\startbuffer
3416for i=1 upto 12 :
3417    draw
3418        thefmttext("\letterpercent 3!date!","month,space,year",2019,i)
3419        shifted (0,i *cm / 2);
3420    draw
3421        thefmttext("@3!date!","month,space,year",2019,i)
3422        shifted (4cm,i *cm / 2);
3423endfor ;
3424
3425for i=1 upto 20 :
3426    draw
3427        thefmttext(decimal i)
3428        shifted (1cm,-i/2*cm);
3429    draw
3430        thefmttext("@!month!",i)
3431        shifted (4cm,-i/2*cm);
3432    draw
3433        thefmttext("@!weekday!",i)
3434        shifted (7cm,-i/2*cm);
3435    draw
3436        thefmttext("@!monthshort!",i)
3437        shifted (10cm,-i/2*cm);
3438    draw
3439        thefmttext("@3!dayoftheweek!",i,1,2018)
3440        shifted (13cm,-i/2*cm);
3441endfor ;
3442\stopbuffer
3443
3444\typebuffer
3445
3446\startplacefigure[title=formatters,reference=fig:formatters]
3447    \framed{\scale[width=.8\textwidth]{\processMPbuffer}}
3448\stopplacefigure
3449
3450\stopsection
3451
3452\startsection[title=Lists (aka suffixed variables)]
3453
3454Sometimes graphics are constructed using lists. There are a few helpers (and
3455maybe there will be some more) that can make things a bit easier. Say that we
3456do this:
3457
3458\startbuffer
3459pair a[] ;
3460a[1] := (0,0) ; a[2] := (1,0) ;
3461a[3] := (1,1) ; a[4] := (0,1) ;
3462a[5] := (1,1) ; a[6] := (2,0) ;
3463
3464draw topath(a,--) ysized 2cm
3465    withpen pencircle scaled 1mm
3466    withcolor .625red ;
3467\stopbuffer
3468
3469\typebuffer
3470
3471\startlinecorrection[blank]
3472\processMPbuffer
3473\stoplinecorrection
3474
3475The \type {topath} macro converts the list into a path, in this case an ugly one.
3476
3477Say that we want to get rid of the sixth entry. For that we can use the \type
3478{dispose} macro. You can use the dispose for any type (except a macro).
3479
3480\startbuffer
3481dispose(a[6]) ;
3482draw topath(a,--) ysized 2cm
3483    withpen pencircle scaled 1mm
3484    withcolor .625yellow ;
3485\stopbuffer
3486
3487\typebuffer
3488
3489\startlinecorrection[blank]
3490\processMPbuffer
3491\stoplinecorrection
3492
3493We still have some duplicate entries here:
3494
3495\startbuffer
3496dispose(a[6]) ;
3497drawpoints topath(a,--) ysized 2cm
3498    withpen pencircle scaled 1mm
3499    withcolor .625red ;
3500drawpointlabels topath(a,--) ysized 2cm ;
3501\stopbuffer
3502
3503\typebuffer
3504
3505\startlinecorrection[blank]
3506\processMPbuffer
3507\stoplinecorrection
3508
3509These can be removed with:
3510
3511\startbuffer
3512uniquelist(a) ;
3513draw topath(a,--) ysized 2cm
3514    withpen pencircle scaled 1mm
3515    withcolor .625yellow ;
3516drawpoints topath(a,--) ysized 2cm
3517    withpen pencircle scaled 1mm
3518    withcolor .625red ;
3519drawpointlabels topath(a,--) ysized 2cm ;
3520\stopbuffer
3521
3522\typebuffer
3523
3524\startlinecorrection[blank]
3525\processMPbuffer
3526\stoplinecorrection
3527
3528Sometimes a list needs to be sorted and here is the solution:
3529
3530\startbuffer
3531sortlist(a,nothing) ;
3532draw topath(a,--) ysized 2cm
3533    withpen pencircle scaled 1mm
3534    withcolor .625red ;
3535\stopbuffer
3536
3537\typebuffer
3538
3539\startlinecorrection[blank]
3540\processMPbuffer
3541\stoplinecorrection
3542
3543The second argument can be an operator that takes a pair variable:
3544
3545\startbuffer
3546sortlist(a,xpart) ;
3547draw topath(a,--) ysized 2cm
3548    withpen pencircle scaled 3mm
3549    withcolor .625red ;
3550sortlist(a,ypart) ;
3551draw topath(a,--) ysized 2cm
3552    withpen pencircle scaled 2mm
3553    withcolor .625yellow ;
3554\stopbuffer
3555
3556\typebuffer
3557
3558\startlinecorrection[blank]
3559\processMPbuffer
3560\stoplinecorrection
3561
3562Constructing a list can be sped up with the \type {tolist} macro.
3563
3564\startbuffer
3565pair a[], b[], c[], d[] ;
3566tolist(a,1,(0,0),(1,0),(1,1),(0,1)--(1,1)--(2,2)) ;
3567tolist(b,0,(0,0),(1,0),(1,1),(0,1)--(1,1)--(2,2)) ;
3568tolist(c,(0,0),(1,0),(1,1),(0,1)--(1,1)--(2,2)) ;
3569tolist(d,(0,0),(1,0),(1,1)) ;
3570
3571draw image (
3572    draw topath(a,--) shifted (0,0) ;
3573    draw topath(b,--) shifted (3,0) ;
3574    draw topath(c,--) shifted (6,0) ;
3575    draw topath(d,--) shifted (9,0) ;
3576) ysized 2cm withpen pencircle scaled 1mm withcolor .625red ;
3577\stopbuffer
3578
3579\typebuffer
3580
3581\startlinecorrection[blank]
3582\processMPbuffer
3583\stoplinecorrection
3584
3585\stopsection
3586
3587\startsection[title=Segmented paths]
3588
3589\index {segmented paths}There are all kind of helpers in \METAFUN\ and some are
3590discussed here. In \in {figure} [fig:segmentedpaths] we see a few macros that
3591return a (smooth) path made from segments. You can for instance use these to do
3592things that use the points on a path, like anchoring text.
3593
3594\startbuffer
3595def DrawSomePath(text t) =
3596    drawpath        t withcolor .625red ;
3597    drawpoints      t withcolor white ;
3598    drawpointlabels t ;
3599enddef ;
3600
3601DrawSomePath(circularpath(5) scaled 12cm) ;
3602DrawSomePath(squarepath  (5) scaled  8cm) ;
3603DrawSomePath(linearpath  (5) scaled  4cm) ;
3604\stopbuffer
3605
3606\typebuffer
3607
3608\startplacefigure[title={A few segmented paths.},reference=fig:segmentedpaths]
3609    \processMPbuffer
3610\stopplacefigure
3611
3612\index {crossing paths}The following examples demonstrates two mechanisms. In the
3613image two paths are drawn on top of each other but one of them has holes where
3614the other one crosses. The \type {crossingunder} macro was written by Alan
3615Braslau as part of the node based diagram builder. In the process the arrow
3616drawing code was adapted to accept a picture.
3617
3618\startbuffer[a]
3619drawarrow image (
3620    draw ((fullcircle scaled 2.25cm) crossingunder (fullsquare scaled 2cm))
3621        withpen pencircle scaled 1mm withcolor .625green ;
3622    draw  (fullsquare scaled 2cm)
3623        withpen pencircle scaled 1mm withcolor .625blue ;
3624) ;
3625drawarrow image (
3626    draw  (fullsquare scaled 4cm)
3627        withpen pencircle scaled 1mm withcolor .625red ;
3628    draw ((fullcircle scaled 5cm) crossingunder (fullsquare scaled 4cm))
3629        withpen pencircle scaled 1mm withcolor .625yellow ;
3630) ;
3631\stopbuffer
3632
3633\startbuffer[b]
3634drawarrow image (
3635    draw ((fullsquare scaled 2cm) crossingunder (fullcircle scaled 2.25cm))
3636        withpen pencircle scaled 1mm withcolor .625blue ;
3637    draw  (fullcircle scaled 2.25cm)
3638        withpen pencircle scaled 1mm withcolor .625green ;
3639) ;
3640drawarrow image (
3641    draw  (fullcircle scaled 5cm)
3642        withpen pencircle scaled 1mm withcolor .625yellow ;
3643    draw ((fullsquare scaled 4cm) crossingunder (fullcircle scaled 5cm))
3644        withpen pencircle scaled 1mm withcolor .625red ;
3645) ;
3646\stopbuffer
3647
3648\typebuffer[a]
3649
3650The next variant uses a different order:
3651
3652\typebuffer[b]
3653
3654The results are shown in \in {figure} [fig:crossingunder]. The internal variable
3655\type {crossingscale} can be used to make the gap wider or narrower. The gap has
3656a default value of 20.
3657
3658\startplacefigure[title=Crossing paths without touching,reference=fig:crossingunder]
3659    \startcombination
3660        {\processMPbuffer[a]} {}
3661        {\processMPbuffer[b]} {}
3662    \stopcombination
3663\stopplacefigure
3664
3665\stopsection
3666
3667\startsection[title=Grouping]
3668
3669The grouping model in \METAPOST\ is kind of special. Basically anything that
3670happens in a group is processed in some nested action and doesn't interfere with
3671the outside. However, the last value put (back) into the input is picked up after
3672the group. A \type {vardef} acts that way:
3673
3674\startbuffer
3675vardef foo (expr i, j) =
3676  save ii, jj ; ii := 2*i ; jj :=j/2 ;
3677  (i, j) -- (ii,jj)
3678enddef ;
3679
3680draw (foo(1,2) .. foo(5,1) .. foo(12,3))
3681    ysized 1cm
3682    withpen pencircle scaled 2mm
3683    withcolor darkred ;
3684
3685draw boundingbox currentpicture withcolor darkyellow ;
3686\stopbuffer
3687
3688\typebuffer
3689
3690This weird shape comes out:
3691
3692\startlinecorrection[blank]
3693    \processMPbuffer
3694\stoplinecorrection
3695We save two variables, and then give new local numerics with their names some
3696values. Then we \quote {return} a path. A \type {vardef} automatically starts
3697with a \type {begingroup} and ends with an \type {endgroup}. The next example
3698shows how we can use that grouping trick directly. The \type {--} has to come
3699before the \type {begingroup}.
3700
3701\startbuffer
3702vardef turtle expr p =
3703  save a ; pair a ; a := point 0 of p ; a
3704  for i = 1 upto length(p) if cycle p : - 1 fi :
3705    -- begingroup a := a shifted point i of p ; a endgroup
3706  endfor
3707  if cycle p : -- cycle fi
3708enddef ;
3709
3710draw        ((0, 0) -- (10, 0) -- (100, 10) -- (-5,20) -- cycle)
3711    withpen pencircle scaled 2 withcolor darkred ;
3712draw turtle ((0, 0) -- (10, 0) -- (100, 10) -- (-5,20) -- cycle)
3713    withpen pencircle scaled 2 withcolor darkyellow ;
3714\stopbuffer
3715
3716\typebuffer
3717
3718Turtle graphics use relative positions. Actually they use one number and switch
3719direction but the above is okay too. Effectively we loop over the path and use
3720each point as a relative move, so we recalculate it.
3721
3722\startlinecorrection[blank]
3723    \processMPbuffer
3724\stoplinecorrection
3725
3726We could have said \type {-- hide(a := a shifted point i of p) a} because the
3727\type {hide} macro does that the grouping trick.
3728
3729\stopsection
3730
3731\startsection[title=External files]
3732
3733You can put code in an external file and load that one when needed. The low level
3734command is \type {input}:
3735
3736\starttyping
3737input myfile ;
3738input myfile.mp ;
3739input myfile.mpiv ;
3740input myfile.mpxl ;
3741input "myfile.mpxl" ;
3742\stoptyping
3743
3744In \CONTEXT\ we have modules and their name starts with \type {mp-} and the
3745suffix can depend on what version you use (\type {mpii}, \type {mpiv}, \type
3746{mpxl}) but that will be dealt with automatically.
3747
3748\starttyping
3749loadmodule("mine") ;
3750\stoptyping
3751
3752This will locate \type {mp-mine} with the proper suffix and often a module will
3753be set up to be loaded only once. For loading files \LUAMETAFUN\ provides:
3754
3755\starttyping
3756loadfile("somefile.mp") ;
3757\stoptyping
3758
3759Which is a bit more robust than the \type {input} commands that is kind of fuzzy
3760because it takes a sequence of tokens or a string. When you embed code in a
3761document source there are some environments that permit loading of definitions
3762and extensions.
3763
3764\starttyping
3765\startMPdefinitions
3766   % code passed to the library directly
3767\stopMPdefinitions
3768
3769\startMPextensions
3770   % code passed to the library but via tex (expansion step)
3771\stopMPextensions
3772\stoptyping
3773
3774\stopsection
3775
3776\startsection[title=Instances]
3777
3778The library supports several numbering models. The default is \type {scaled} that
3779uses integers that represent a (relatively small) float. Although you can go up
3780to 32K it's wise to stay below 4096. The \type {double} number model supports 64
3781bit floating point and the \type {decimal} model arbitrary precision. In \LUATEX\
3782there is also \type {binary} for arbitrary precision but in \LUAMETATEX\ that
3783model is not provided.
3784
3785You can use different models and instances alongside. In \MKIV\ and \LMTX\ we have
3786a few predefined. The \type {metafun} instance is the default. Here we show the
3787ones that use \METAFUN:
3788
3789\starttyping[style=\ttx]
3790\defineMPinstance[metafun]   [format=metafun,extensions=yes,initializations=yes]
3791\defineMPinstance[minifun]   [format=minifun,extensions=yes,initializations=yes]
3792\defineMPinstance[extrafun]  [format=metafun,extensions=yes,initializations=yes]
3793\defineMPinstance[lessfun]   [format=metafun]
3794\defineMPinstance[doublefun] [format=metafun,extensions=yes,initializations=yes,method=double]
3795\defineMPinstance[decimalfun][format=metafun,extensions=yes,initializations=yes,method=decimal]
3796\defineMPinstance[mprun]     [format=metafun,extensions=yes,initializations=yes]
3797\defineMPinstance[simplefun] [format=metafun,method=double] % for internal usage
3798\stoptyping
3799
3800All instances will load additional definitions btu extensions (expanded
3801definitions) and initializations (before each graphic) are optional.
3802
3803\starttyping
3804\startMPdefinitions
3805\stopMPdefinitions
3806
3807\startMPextensions
3808\stopMPextensions
3809
3810\startMPinitializations
3811\stopMPinitializations
3812\stoptyping
3813
3814You can search the sources of manuals and test suite for examples of usage, but here are
3815some:
3816
3817\startbuffer
3818\defineMPinstance[foo][definitions=yes]
3819\defineMPinstance[bar][definitions=yes]
3820
3821\startMPdefinitions{foo}
3822    vardef p = image (
3823        draw fullsquare scaled 1cm withcolor "darkgreen" ;
3824        draw textext("1") ;
3825    )
3826    enddef ;
3827\stopMPdefinitions
3828
3829\startMPdefinitions{bar}
3830    vardef p = image (
3831        draw (fullsquare rotated 45) scaled 1cm withcolor "darkyellow" ;
3832        draw textext("2") ;
3833    )
3834    enddef ;
3835\stopMPdefinitions
3836\stopbuffer
3837
3838\typebuffer \getbuffer
3839
3840We use both as:
3841
3842\startbuffer[demo-1]
3843\startMPcode{foo}
3844    draw p ;
3845    draw image (
3846        draw fullcircle scaled 1cm withcolor "darkblue" ;
3847        draw textext("3") withcolor "darkred" ;
3848    ) ;
3849    draw p ;
3850\stopMPcode
3851\stopbuffer
3852
3853\startbuffer[demo-2]
3854\startMPcode{bar}
3855    draw p ;
3856    draw image (
3857        draw fullcircle scaled 1cm withcolor "darkblue" ;
3858        draw textext("4") withcolor "darkred" ;
3859    ) ;
3860\stopMPcode
3861\stopbuffer
3862
3863\typebuffer[demo-1,demo-2]
3864
3865\startlinecorrection
3866\startcombination[nx=2,ny=1]
3867    {\getbuffer[demo-1]} {foo}
3868    {\getbuffer[demo-2]} {bar}
3869\stopcombination
3870\stoplinecorrection
3871
3872\stopsection
3873
3874\stopchapter
3875
3876\stopcomponent
3877