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