19

I need to draw few diagrams like this with MetaPost.

enter image description here

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.

  • I am thinking this solution https://tex.stackexchange.com/a/43597/141947 may help, but I do not know how to create a custom tikz pattern from it. – BambOo Mar 26 '18 at 21:22
  • 1
    Maybe the mpattern package can be useful? I haven't tried it myself, though. https://www.tug.org/TUGboat/tb19-3/tb60bolek.pdf – Franck Pastor Mar 26 '18 at 21:33
  • What code have you got so far? Can you provide a minimal document for the drawing without the wood pattern? – cfr Mar 27 '18 at 10:44
  • @cfr I think to modify the second example here https://tex.stackexchange.com/questions/155152/metapost-how-to-fill-cycle-path-with-slanted-lines/155193#155193 – Anton Petrunin Mar 27 '18 at 17:39

3 Answers3

16

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

pic with wood pattern

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

mickep
  • 8,685
16

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;
breadth := 1/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);

enter image description here

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

  • Do you have a pack­age doc­u­men­ta­tion for fiziko? – Anton Petrunin Aug 28 '18 at 01:25
  • 4
    Very nice package! – Aditya Aug 28 '18 at 01:50
  • 1
    @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 07:57
  • 1
    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
  • @AntonPetrunin i've updated docs a little: https://github.com/jemmybutton/fiziko/releases/tag/v0.1.2-alpha , now there are some details on that woodenThing thing. – Sergey Slyusarev Aug 28 '18 at 17:27
  • 1
    @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
  • 2
    I used it here https://arxiv.org/pdf/1806.06942.pdf, (pages 17 and 51) --- thank you again. – Anton Petrunin Jan 02 '19 at 04:29
11

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

A Metapost plank

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.
Thruston
  • 42,268
  • 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 03 '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