MetaFun - Pragma ADE

MetaFun - Pragma ADE MetaFun - Pragma ADE

pragma.ade.com
from pragma.ade.com More from this publisher
29.11.2012 Views

278 p := fullcircle scaled (2*length(loc-ori)) shifted ori ; q := freesquare xyscaled (urcorner s - llcorner s) ; l := point (xpart (p intersectiontimes (ori--loc))) of q ; draw q shifted loc withpen pencircle scaled .5pt ; draw l shifted loc withcolor .625yellow ; draw loc withcolor .625red ; s enddef ; The macro xyscaled is part of METAFUN and scales in two directions at once. The METAPOST primitive intersectiontimes returns a pair of time values of the point where two paths intersect. The first part of the pair concerns the first path. text text text text text text text text text text text textextext text text We are now a small step from the exact placement. If we change the last line of the macro into: (s shifted -l) we get the displacement we want. Although the final look and feel is also determined by the text itself, the average result is quite acceptable. text text text text text text text text text text text text texttext text text Because we also want to pass pictures, and add a bit of offset too, the final implementation is slightly more complicated. The picture is handled with an additional condition, and the offset with the METAFUN macro enlarged. newinternal freelabeloffset ; freelabeloffset := 3pt ; vardef thefreelabel (expr str, loc, ori) = save s, p, q, l ; picture s ; path p, q ; pair l ; interim labeloffset := freelabeloffset ; s := if string str : thelabel(str,loc) else : str shifted -center str shifted loc fi ; setbounds s to boundingbox s enlarged freelabeloffset ; A few applications Free labels

p := fullcircle scaled (2*length(loc-ori)) shifted ori ; q := freesquare xyscaled (urcorner s - llcorner s) ; l := point (xpart (p intersectiontimes (ori--loc))) of q ; setbounds s to boundingbox s enlarged -freelabeloffset ; (s shifted -l) enddef ; Watch how we temporarily enlarge the bounding box of the typeset label text. We will now test this macro on a slightly rotated circle, using labels typeset by TEX. The reverse is there purely for cosmetic reasons, to suit the label texts. defining in funny macros. and on go on Can't we? We can pickup pencircle scaled 1mm ; path p ; p := reverse fullcircle rotated -25 scaled 3cm ; draw p withcolor .625yellow ; pair cp ; cp := center p ; freedotlabel (btex \strut We can etex, point 0 of p, cp) ; freedotlabel (btex \strut go on etex, point 1 of p, cp) ; freedotlabel (btex \strut and on etex, point 2 of p, cp) ; freedotlabel (btex \strut in etex, point 3 of p, cp) ; freedotlabel (btex \strut defining etex, point 4 of p, cp) ; freedotlabel (btex \strut funny etex, point 5 of p, cp) ; freedotlabel (btex \strut macros. etex, point 6 of p, cp) ; freedotlabel (btex \strut Can't we? etex, point 7 of p, cp) ; Unfortunately we can run into problems due to rounding errors. Therefore we use a less readable but more safe expression for calculating the intersection points. Instead of using point loc as endpoint we use loc shifted over a very small distance into the direction loc from ori. In the assignment to l we replace loc by: ( (1+eps) * arclength(ori--loc) * unitvector(loc-ori) ) 13.3 Marking angles A convenient METAPOST macro is unitvector. When we draw a line segment from the origin to the point returned by this macro, the segment has a length of 1 base point. This macro has a wide range of applications, but some basic knowlegde of vector algebra is handy. The following lines of METAPOST code demonstrate the basics behind unitvectors. Marking angles A few applications 279

278<br />

p := fullcircle scaled (2*length(loc-ori)) shifted ori ;<br />

q := freesquare xyscaled (urcorner s - llcorner s) ;<br />

l := point (xpart (p intersectiontimes (ori--loc))) of q ;<br />

draw q shifted loc withpen pencircle scaled .5pt ;<br />

draw l shifted loc withcolor .625yellow ;<br />

draw loc withcolor .625red ;<br />

s<br />

enddef ;<br />

The macro xyscaled is part of METAFUN and scales in two directions at once. The METAPOST primitive<br />

intersectiontimes returns a pair of time values of the point where two paths intersect. The<br />

first part of the pair concerns the first path.<br />

text text text<br />

text text<br />

text<br />

text<br />

text<br />

text<br />

text<br />

text<br />

textextext text<br />

text<br />

We are now a small step from the exact placement. If we change the last line of the macro into:<br />

(s shifted -l)<br />

we get the displacement we want. Although the final look and feel is also determined by the text<br />

itself, the average result is quite acceptable.<br />

text text text<br />

text<br />

text<br />

text<br />

text<br />

text<br />

text<br />

text<br />

text<br />

text texttext text text<br />

Because we also want to pass pictures, and add a bit of offset too, the final implementation is<br />

slightly more complicated. The picture is handled with an additional condition, and the offset<br />

with the METAFUN macro enlarged.<br />

newinternal freelabeloffset ; freelabeloffset := 3pt ;<br />

vardef thefreelabel (expr str, loc, ori) =<br />

save s, p, q, l ; picture s ; path p, q ; pair l ;<br />

interim labeloffset := freelabeloffset ;<br />

s := if string str : thelabel(str,loc)<br />

else : str shifted -center str shifted loc fi ;<br />

setbounds s to boundingbox s enlarged freelabeloffset ;<br />

A few applications Free labels

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!