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;
Personal tools