% Copyright (c) Martin Geisler % You can use this MetaPost code if you find it usefull. % Defines a macro that can draw a Hilbert Curve of degree n with the % upper-left corner at p and sidelength length: def hilbert(expr p, length, n) = begingroup save curve, T; path curve; transform T[]; % Each iteration consists of four copies of the previous curve. % The copies are transformed by these transformation: T[1] = identity scaled 1/2 rotated 90 reflectedabout((0, 0), (0, 1)) shifted (0.5*length, -1*length); T[2] = identity scaled 1/2; T[3] = identity scaled 1/2 shifted (0.5*length, 0*length); T[4] = identity scaled 1/2 reflectedabout((0, 0), (1, -1)) shifted (0.5*length, -0.5*length); % The basic curve: curve = ((0.25, -0.75)*length)--((0.25, -0.25)*length)-- ((0.75, -0.25)*length)--((0.75, -0.75)*length) shifted p; for i = 1 upto n: curve := (curve transformed T[1])--(curve transformed T[2])-- (curve transformed T[3])--(curve transformed T[4]); endfor; % We scale the curve so that if fill the entire square with % side-length length: draw curve scaled ((2**(n+1))/(2**(n+1) - 1)); endgroup enddef; beginfig(0); pickup pencircle scaled 1pt; hilbert((0, 0), 4cm, 0); endfig; beginfig(1); pickup pencircle scaled 1pt; hilbert((0, 0), 4cm, 1); endfig; beginfig(2); pickup pencircle scaled 1pt; hilbert((0, 0), 4cm, 2); endfig; beginfig(3); pickup pencircle scaled 1pt; hilbert((0, 0), 4cm, 3); endfig; beginfig(4); pickup pencircle scaled 0.75pt; hilbert((0, 0), 4cm, 4); endfig; beginfig(5); pickup pencircle scaled 0.5pt; hilbert((0, 0), 4cm, 5); endfig; end.