Functions
From Metapost
relcode This page contains some functions that might be useful. Please add your own. If you know a better implementation, please provide it and/or a link to the original. The standard source of useful functions is MetaFun
Contents |
[edit] Bounding Box
[edit] savebox and restorebox
Functions savebox and restorebox respectively save the current bounding box and restore it.
def savebbox = interim bboxmargin := 0; save _bbox; path _bbox; _bbox = bbox currentpicture; enddef;
def restorebbox = setbounds currentpicture to _bbox; enddef;
[edit] smashdraw and phanthomdraw
Function smashdraw allows drawing things without affecting the current bounding box:
vardef smashdraw text command = savebbox; command; restorebbox; enddef;
Function phanthomdraw is the opposite of smashdraw, it affects the bounding box as if the drawing command had been executed, however, nothing is drawn.
vardef phantomdraw text command = interim bboxmargin := 0; setbounds currentpicture to bbox image(command) -- bbox currentpicture -- cycle; enddef;
Example:
draw fullcircle scaled 10 withcolor blue; smashdraw draw fullcircle scaled 10 shifted (50,50) withcolor red; phantomdraw draw fullcircle scaled 10 shifted (-50,-50);
[edit] drawbefore
Drawbefore lets you draw things under the current drawing.
vardef drawbefore text commands = save pic; picture pic; pic := currentpicture; currentpicture := nullpicture; commands; addto currentpicture also pic; enddef;
[edit] Generating shapes
[edit] polygon
A simple function that returns a regular polygon.
vardef polygon(expr sides) = for i = 0 upto sides - 1: ((1,0) rotated (360/sides * i)) -- endfor cycle enddef;
[edit] wavepath
Function wavepath generates a wave along a given path. You specify the wavelength and the angle at which the wave should intersect the original path.
vardef wavepath(expr apath, wavelength, angle) =
for time = 0 step wavelength until arclength apath:
hide(_ta := arctime time of apath;
_tb := arctime (time + wavelength/2) of apath;)
if time > 0: .. fi
point _ta of apath {(direction _ta of apath) rotated angle} ..
point _tb of apath {(direction _tb of apath) rotated -angle}
endfor
if cycle apath: .. cycle fi
enddef;
[edit] cloud
Function cloud generates a cloud-like shape along a given cyclic path, consisting of a given number of segments.
vardef cloud(expr p, segments) =
save thestep, lasttime, thistime, lastpoint, thisdir, lastdir, cpath, xpath;
thestep = arclength(p)/segments;
numeric lasttime; lasttime = 0;
cloudangle:=5;
cloudperc:=.1;
for i = 1 upto segments:
hide(
numeric thistime;
pair lastpoint, thispoint, lastdir, thisdir;
path cpath, xpath;
thistime = arctime (i if i < segments: + uniformdeviate(0.2) fi)
*arclength(p) / segments of p;
lastpoint = point lasttime of p;
thispoint = point thistime of p;
lastdir = (direction lasttime of p) rotated (-cloudangle + uniformdeviate(10));
thisdir = (direction thistime of p) rotated (cloudangle + uniformdeviate(10));
cpath = lastpoint{lastdir} .. {thisdir}thispoint;
xpath = subpath (1-cloudperc-uniformdeviate(0.1), 1) of cpath reflectedabout(thispoint, thispoint + (thisdir rotated 90));
lasttime := thistime;
)
cpath -- (reverse xpath) & xpath --
endfor
cycle
enddef;
[edit] rounded rectangle
vardef roundedrect(expr pa, pb, rdist) = (xpart pa + rdist, ypart pa) --- (xpart pb - rdist, ypart pa) .. (xpart pb, ypart pa + rdist) --- (xpart pb, ypart pb - rdist) .. (xpart pb - rdist, ypart pb) --- (xpart pa + rdist, ypart pb) .. (xpart pa, ypart pb - rdist) --- (xpart pa, ypart pa + rdist) .. cycle enddef;
