# wood pattern with metapost

I need to draw few diagrams like this with MetaPost.

So I want to create a wood-pattern-filling-function and use it few times. Is there a good way to do it?

I think to generate a random function, draw its the integer level curves and xscale the picture --- the obtained picture should remind wood pattern. However I do not know how to do such things in MetaPost. The Thruston's answer seems to be relevant --- hope someone could help me, I just started to use MetaPost.

P.S. I want to thank Toby Thurston for help. Here is a modification of his code, which produces a better result:

prologues := 3;
outputtemplate := "%j%c.svg";
outputformat := "svg";

vardef wavy expr pa =
point 0 of pa
for a = s step s until arclength(pa):
.. point arctime(a) of pa of pa
shifted (sind(a)*up+unitvector(direction arctime(a) of pa of pa)
rotated 90 scaled ((1/8)*normaldeviate))
endfor
enddef;

beginfig(1);
numeric s; s = 10;
path p, q;
p = (left--right) scaled 200 shifted (-10*up);
for i=-10 upto 10:
p:= wavy p shifted ((2+.7*normaldeviate)*up);
draw p withpen pencircle xscaled 1/2 yscaled 1/8 rotated 15;
endfor

q = unitsquare shifted -(1/2,1/2) xscaled 144 yscaled 21;
clip currentpicture to q; undraw q withpen pencircle scaled 1; draw q;

endfig;

end


In addition to @mickep 's answer: Sadly, there was no macro to automatically fit a woodBlock into an arbitrary path, now i've added one ( https://github.com/jemmybutton/fiziko/commit/bd24d7fa1144c722ede76e1b75378dc4ea0c1c50 ) You give it a closed path and an angle as arguments and it returns a wood texture picture (without the outline; upd: actually, no, let the outline be). For example, the following code produces something similar to the picture in the question:

input fiziko.mp;
pair A, B, C, D, E, F, C', E', F';
numeric totalWidth, width, height, breadth, a[];
path p[];
totalWidth := 5cm;
width := 2cm;
height := 3cm;
A := (0, 0);
B := (totalWidth, 0);
C := (1/2totalWidth, 0);
E := (xpart(C), height);
D := 3/4[C, E];
F := (xpart(E) + width, 0);
C' = whatever[C shifted (0, breadth), F shifted (0, breadth)]
= whatever[C shifted (breadth, 0), E shifted (breadth, 0)];
E' = whatever[E shifted (breadth, 0), C shifted (breadth, 0)]
= whatever[E shifted ((unitvector(E-F) scaled breadth) rotated 90), F shifted ((unitvector(E-F) scaled breadth) rotated 90)];
F' = whatever[C shifted (0, breadth), F shifted (0, breadth)]
= whatever[E shifted ((unitvector(E-F) scaled breadth) rotated 90), F shifted ((unitvector(E-F) scaled breadth) rotated 90)];
p1 := A -- B -- B shifted (0, -breadth) -- A shifted (0, -breadth) -- cycle;
a1 := 0;
p2 := C -- E -- E' -- C' -- cycle;
a2 := 90;
p3 := E -- F -- F' -- E' -- cycle;
a3 := angle (E-F);
p4 := C -- F -- F' -- C' -- cycle;
a4 := 0;
for i := 1 step 1 until 4:
draw woodenThing(p[i], a[i]);
% draw p[i];
endfor;
dotlabel.top("A", A);
dotlabel.urt("B", B);
dotlabel.ulft("C", C);
dotlabel.lft("D", D);
dotlabel.ulft("E", E);


There are also some global variables which affect the texture to play with: https://github.com/jemmybutton/fiziko/blob/master/fiziko.mp#L1660

• Very nice package! – Aditya Aug 28 '18 at 1:50
• @AntonPetrunin the closest thing to documentation is fizikomp.pdf in releases. There are function descriptions and a few example. It lags behind, though, and doesn't contain everything. For example, this latest addition is not there yet and, as far as i remember, i didn't add anything on drawing knots there. – Sergey Slyusarev Aug 28 '18 at 7:57
• Cool that you added the possibility for an arbitray closed path! @Aditya I was so happy when I found the package that I played with it and finally managed to draw a cornu spiral with varying width of the curve. This has been "a dream" ever since I read Casselman's great book for the first time. :D – mickep Aug 28 '18 at 10:44
• @mickep The problem with this woodenThing thing is that it generates a texture every time and it's quite slow, whereas woodBlock predrawn once can be reused and cropped in many ways, which is much faster. On the other hand, reused textures are boring. – Sergey Slyusarev Aug 31 '18 at 21:20
• I used it here arxiv.org/pdf/1806.06942.pdf, (pages 17 and 51) --- thank you again. – Anton Petrunin Jan 2 at 4:29

I just learned about the fantastic MetaPost package fiziko created by @sergey-slyusarev.

The code (I use ConTeXt to generate this minimal example, it will be similar using LaTeX)

\startMPpage[offset=2bp]
input fiziko.mp
draw woodBlock(10cm,1cm);
\stopMPpage


generates the output

I have not looked into the code to see how easily one could change the form from a rectangle to an arbitrary closed path.

Here's the beginning of an answer. More work needed to make it robust and easily re-usable....

prologues := 3;
outputtemplate := "%j%c.eps";

vardef wavy expr pa =
point 0 of pa
for a = s step s until arclength(pa):
.. point arctime(a) of pa of pa
shifted (unitvector(direction arctime(a) of pa of pa)
rotated 90 scaled 1/8 normaldeviate)
endfor
enddef;

beginfig(1);
numeric s; s = 10;
path p, q;
p = (left--right) scaled 200;
for i=-10 upto 10:
draw wavy p shifted (2i*up) rotated -5
withpen pencircle xscaled 1/2 yscaled 1/8 rotated 15
withcolor 1/256(79,36,19);
endfor

q = unitsquare shifted -(1/2,1/2) xscaled 144 yscaled 21;
clip currentpicture to q; undraw q withpen pencircle scaled 1; draw q;

endfig;
end.

• Thank you (I was hoping that you will answer). The picture does not really look like a wood pattern. I wonder, is there a way to make a draw a level set $f(x,y)=c$ in MetaPost? If yes I would try to do it for sum of $a\cdot cos((1+c)\cdot x+b\cdoty)$ for random small values of – Anton Petrunin Apr 3 '18 at 20:50
• actually, it works quite well, but I miss oval shaped thing a bit. – Anton Petrunin Apr 19 '18 at 23:55