% tap.mp % L. Nobre G. % 2006 numeric NumberOfColors, HalfSideLength, HalfAngleRange, CornerMargin; numeric ThicknesFactor, TolerancFactor, BorderThFactor; NumberOfColors = 7; HalfSideLength = 22mm; ThicknesFactor = 0.25; % Maximum TraceThickness over Half Side ThinnessFactor = 0.15; % Minimum TraceThickness over Half Side TolerancFactor = 0.92; % Side Gaps over Thickness BorderThFactor = 1.3; % White borders around strokes HalfAngleRange = 10; % The name says it all CornerMargin = 0.4; % Length without traces over Half Side def RandomStep = begingroup numeric margin; margin = ThicknesFactor-ThinnessFactor; ThinnessFactor*HalfSideLength + uniformdeviate( margin*HalfSideLength ) endgroup enddef; def PickInteger( expr MaxNum ) = begingroup save aux; numeric aux; aux = ceiling( uniformdeviate( MaxNum ) ); if aux = 0: aux := 1; fi; ( aux ) endgroup enddef; def PickColor = ( 0.2white+0.6*( uniformdeviate(1) , uniformdeviate(1), uniformdeviate(1) ) ) enddef; vardef LocateIndex[] = dotlabel.urt( str @, z@ ) enddef; beginfig(1); numeric magicnum; magicnum = HalfSideLength/sqrt(3); z100 = magicnum*( 0, -1 ); z200 = magicnum*( sqrt(3), -1 ); z300 = magicnum*dir( 30 ); z400 = magicnum*( 0, 2 ); z500 = magicnum*dir( 150 ); z600 =-magicnum*( sqrt(3), 1 ); path clippath; clippath = z200--z400--z600--cycle; pen bordpen, auxpen; path auxpath; auxpath = 2z100--z200--2z300--z400--2z500--z600--cycle; auxpath := auxpath rotated 30 scaled (0.25/magicnum); auxpen = makepen auxpath; numeric i, currentcoord, maincoords[], numaincoords, auxfac, auxlen, auxtep; numeric actualang[], lenlimit; auxlen = RandomStep; auxfac = 1 + uniformdeviate( BorderThFactor - 1 ); currentpen := auxpen scaled auxlen; bordpen = currentpen scaled auxfac; lenlimit = ( 1 - CornerMargin )*HalfSideLength; i = 0; currentcoord = uniformdeviate( auxfac*auxlen*TolerancFactor ); forever: i := incr( i ); currentcoord := currentcoord+0.5*auxlen*auxfac; maincoords[i] = currentcoord; actualang[i] = HalfAngleRange - uniformdeviate( 2*HalfAngleRange ) + 30*uniformdeviate( 1 - currentcoord/lenlimit ); auxtep := uniformdeviate( auxfac*auxlen*TolerancFactor )+0.5*auxlen*auxfac; currentcoord := currentcoord + auxtep; exitif currentcoord > lenlimit; endfor; numaincoords = i; numeric j; pair Dir[]; for i = 1 upto numaincoords: j := i; z[j] = (maincoords[i]/HalfSideLength)[z100,z200]; Dir[j] = dir( 90 + actualang[i] ); j := i + numaincoords; z[j] = (maincoords[i]/HalfSideLength)[z300,z200]; Dir[j] = dir( 210 + actualang[i] ); j := i + 2numaincoords; z[j] = (maincoords[i]/HalfSideLength)[z300,z400]; Dir[j] = dir( 210 + actualang[i] ); j := i + 3numaincoords; z[j] = (maincoords[i]/HalfSideLength)[z500,z400]; Dir[j] = dir( -30 + actualang[i] ); j := i + 4numaincoords; z[j] = (maincoords[i]/HalfSideLength)[z500,z600]; Dir[j] = dir( -30 + actualang[i] ); j := i + 5numaincoords; z[j] = (maincoords[i]/HalfSideLength)[z100,z600]; Dir[j] = dir( 90 + actualang[i] ); endfor; % for i=1 upto 6numaincoords: % LocateIndex[i]; % endfor; boolean Filled[]; for i=1 upto 6numaincoords: Filled[i] = false; endfor; numeric Chosen[]; for i=0 upto numaincoords-1: Chosen[i] = 0; endfor; color LookUpColor[]; for i=1 upto NumberOfColors: LookUpColor[i] = PickColor; endfor; numeric ThisInd, ThatInd, ThisCoo, ThatCoo, PathFraction; color ThisColor, ThatColor; path ActualPath, SubPathA, SubPathB; for j=2 step 2 until 6numaincoords: forever: ThisInd := PickInteger( 6numaincoords ); exitunless Filled[ThisInd]; endfor; Filled[ThisInd] := true; ThisCoo := ThisInd mod numaincoords; if Chosen[ThisCoo] = 0: i := PickInteger( NumberOfColors ); ThisColor := LookUpColor[i]; Chosen[ThisCoo] := i; else: ThisColor := LookUpColor[Chosen[ThisCoo]]; fi; forever: ThatInd := PickInteger( 6numaincoords ); exitunless Filled[ThatInd]; endfor; Filled[ThatInd] := true; ThatCoo := ThatInd mod numaincoords; if Chosen[ThatCoo] = 0: i := PickInteger( NumberOfColors ); ThatColor := LookUpColor[i]; Chosen[ThatCoo] := i; else: ThatColor := LookUpColor[Chosen[ThatCoo]]; fi; ActualPath := z[ThisInd]{Dir[ThisInd]} ..z[ThatInd]{-Dir[ThatInd]}; PathFraction := 0.2+uniformdeviate( 0.6 ); SubPathA := subpath (0,PathFraction) of ActualPath; SubPathB := subpath (PathFraction,1) of ActualPath; undraw ActualPath withpen bordpen; draw SubPathA withcolor ThisColor; draw SubPathB withcolor ThatColor; endfor; % draw clippath withpen pencircle scaled 1pt; clip currentpicture to clippath; pair urCorner, ulCorner, llCorner, lrCorner; path FinalCut; urCorner = ( 8.13in, 11.533in ); llCorner = ( 0.118in, 35.5bp ); ulCorner = ( xpart llCorner, ypart urCorner ); lrCorner = ( xpart urCorner, ypart llCorner ); FinalCut = urCorner--ulCorner--llCorner--lrCorner--cycle; picture Tile[]; Tile[1] = currentpicture shifted -z100; Tile[2] = currentpicture rotated 120 shifted -z100; Tile[3] = currentpicture rotated 240 shifted -z100; picture RTile[]; RTile[1]= Tile[1] rotated 180; RTile[2]= Tile[2] rotated 180; RTile[3]= Tile[3] rotated 180; picture DTile[]; for i = 1 upto 9: DTile[i] = nullpicture; endfor; addto DTile[1] also Tile[1]; addto DTile[1] also RTile[1]; addto DTile[2] also Tile[1]; addto DTile[2] also RTile[2]; addto DTile[3] also Tile[1]; addto DTile[3] also RTile[3]; addto DTile[4] also Tile[2]; addto DTile[4] also RTile[1]; addto DTile[5] also Tile[2]; addto DTile[5] also RTile[2]; addto DTile[6] also Tile[2]; addto DTile[6] also RTile[3]; addto DTile[7] also Tile[3]; addto DTile[7] also RTile[1]; addto DTile[8] also Tile[3]; addto DTile[8] also RTile[2]; addto DTile[9] also Tile[3]; addto DTile[9] also RTile[3]; currentpicture := nullpicture; numeric minimalnumber; minimalnumber = ceiling( 0.7*( ypart (urCorner-llCorner) )/HalfSideLength ); pair hor, ver, sta; hor = ( 2*HalfSideLength, 0 ); ver = 2*HalfSideLength*dir( 60 ); sta = ulCorner - minimalnumber*ver; for i = 0 upto minimalnumber: for j = 0 upto minimalnumber: draw DTile[PickInteger( 9 )] shifted ( sta + i*hor + j*ver ); endfor; endfor; clip currentpicture to FinalCut; endfig; end.