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 |
Bounding Box
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;
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);
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;
Generating shapes
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;
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;
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;
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;