% PACKAGE FOR METAPOST TO DRAW FINITE STATE MACHINES, GRAPHS, TREES, ETC. % Author: gabriele puppis % declares a grid of equally-spaced nodes % % syntax: matrix.(<#rows>,<#cols>); % % example: matrix.a(2,3); % % parameters: spacing = (60,30) | ... % offset = (0,0) | ... % numbering = (0,0) | ... % % (nodes are identified by [][], % can't be c,h,x,y or any other global variable, % the center/anchor of a node is [][].c/.h, % and start from 0, % so [0][0] is the top left-most node, % [<#rows>-1][<#cols>-1] is the bottom right-most node) vardef matrix@# expr d = pair @#[][].c; pair @#[][].h; pair @#[][].s; path @#[][].f; numeric @#[][].m; for i=0 upto xpart(d)-1: for j=0 upto ypart(d)-1: @#[xpart(numbering)+i][ypart(numbering)+j].c := (xpart(spacing)*j,-ypart(spacing)*i) shifted offset; endfor; endfor; enddef; % declares a tree-shaped arrangement of nodes % % syntax: tree.(<#levels>,); % % example: tree.a(4,2); % % parameters: spacing = (60,30) | ... % offset = (0,0) | ... % numbering = (0,0) | ... % % (nodes are identified by [][], % can't be c,h,x,y or any other global variable, % the center/anchor of a node is [][].c/.h, % and start from 0, % so [0][0] is the root, % [1][0] ... [1][-1] are the children of the root, % and so on) vardef tree@# expr d = pair @#[][].c; pair @#[][].h; pair @#[][].s; path @#[][].f; numeric @#[][].m; for i=0 upto xpart(d)-1: for j=0 upto (ypart(d)**i) - 1: @#[xpart(numbering)+i][ypart(numbering)+j].c = (xpart(spacing) * ((j+0.5)*(ypart(d)**(xpart(d)-i)) - 0.5*(ypart(d)**xpart(d))), -ypart(spacing) * i) shifted offset; endfor; endfor; enddef; % declares a single node % % syntax: put.(x,y); % % example: put.a(100,100); % % (the center/anchor of a node is .c/.h, % can't be c,h,x,y or any other global variable) vardef put@# expr p = pair @#.c; pair @#.h; pair @#.s; path @#.f; numeric @#.m; @#.c := p; enddef; % declares an additional single node inside an existing matrix or tree % (or change the position of an existing node) % % syntax: setpos.[][](x,y); % % example: setpos.a[0][0](100,100); % % (the center/anchor of a node is [][].c/.h) vardef setpos@# expr p = @#.c := p; enddef; % change the position of an existing node % % syntax: movepos.(x,y); % % example: movepos.a(10,10); % movepos.b[0][0](10,10); vardef movepos@# expr p = @#.c := @#.c shifted p; @#.h := @#.h shifted p; enddef; % draws an existing node % % syntax: node.