Functions
From Metapost
(→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 | + | === 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: + | + | |
*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 + | + | lastdir = (direction lasttime of p) rotated (-cloudangle + uniformdeviate(10)); |
- | thisdir = (direction thistime of p) rotated (cloudangle + | + | thisdir = (direction thistime of p) rotated (cloudangle + uniformdeviate(10)); |
cpath = lastpoint{lastdir} .. {thisdir}thispoint; | cpath = lastpoint{lastdir} .. {thisdir}thispoint; | ||
- | xpath = subpath (1-cloudperc- | + | 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;