Functions

From Metapost

(Difference between revisions)
(cloud)
(cloud)
 
(6 intermediate revisions not shown)
Line 1: Line 1:
 +
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 [http://tex.loria.fr/formats/context/metafun-p.pdf#search=%22metafun%22 MetaFun]
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 [http://tex.loria.fr/formats/context/metafun-p.pdf#search=%22metafun%22 MetaFun]
Line 16: Line 17:
  enddef;
  enddef;
-
=== smashdraw and phanthom draw ===
+
=== smashdraw and phanthomdraw ===
Function smashdraw allows drawing things without affecting the current bounding box:
Function smashdraw allows drawing things without affecting the current bounding box:
Line 39: Line 40:
  phantomdraw draw fullcircle scaled 10 shifted (-50,-50);
  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 ==
== Generating shapes ==
Line 78: Line 90:
   thestep = arclength(p)/segments;
   thestep = arclength(p)/segments;
   numeric lasttime; lasttime = 0;
   numeric lasttime; lasttime = 0;
 +
  cloudangle:=5;
 +
  cloudperc:=.1;
   for i = 1 upto segments:
   for i = 1 upto segments:
     hide(
     hide(
Line 83: Line 97:
       pair lastpoint, thispoint, lastdir, thisdir;
       pair lastpoint, thispoint, lastdir, thisdir;
       path cpath, xpath;
       path cpath, xpath;
-
 
+
       thistime = arctime (i if i < segments: + uniformdeviate(0.2) fi)
-
       thistime = arctime (i if i < segments: + symrand(0.2) fi)
+
       *arclength(p) / segments of p;
       *arclength(p) / segments of p;
       lastpoint = point lasttime of p;
       lastpoint = point lasttime of p;
       thispoint = point thistime of p;
       thispoint = point thistime of p;
-
       lastdir = (direction lasttime of p) rotated (-cloudangle + symrand(10));
+
       lastdir = (direction lasttime of p) rotated (-cloudangle + uniformdeviate(10));
-
       thisdir = (direction thistime of p) rotated (cloudangle + symrand(10));
+
       thisdir = (direction thistime of p) rotated (cloudangle + uniformdeviate(10));
       cpath = lastpoint{lastdir} .. {thisdir}thispoint;
       cpath = lastpoint{lastdir} .. {thisdir}thispoint;
-
       xpath = subpath (1-cloudperc-symrand(0.1), 1) of cpath reflectedabout(thispoint, thispoint + (thisdir rotated 90));
+
       xpath = subpath (1-cloudperc-uniformdeviate(0.1), 1) of cpath reflectedabout(thispoint, thispoint + (thisdir rotated 90));
       lasttime := thistime;
       lasttime := thistime;
     )
     )
     cpath -- (reverse xpath) & xpath --
     cpath -- (reverse xpath) & xpath --
   endfor
   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
   cycle
  enddef;
  enddef;

Current revision as of 14:32, 3 September 2010

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