6

in order to do some technical drawings, I intend to reproduced a (schematized) pebbled sea floor. I could manage to do a MWE, but this is as far as I can possibly get.

\documentclass{article}
\usepackage{tikz}
\usetikzlibrary{calc}
\usetikzlibrary{%
decorations.pathreplacing,%
decorations.pathmorphing%
}
\newcommand\irregularcircle[1]{% radius, irregularity
  let \n1 = {(#1)+rand*(0.1*#1)} in
  +(0:\n1)
  \foreach \a in {10,20,...,350}{
    let \n1 = {(#1)+rand*(0.2*#1)} in
    -- +(\a:\n1)
  } -- cycle
}

 \begin{document}
  \thispagestyle{empty}
  \begin{tikzpicture}[
                media/.style={font={\footnotesize\sffamily}},
                wave/.style={
                decorate,decoration={snake,post length=1.4mm,amplitude=2mm,
                segment length=2mm},thick},
                interface/.style={
                % The border decoration is a path replacing decorator. 
                % For the interface style we want to draw the original path.
                % The postaction option is therefore used to ensure that the
                % border decoration is drawn *after* the original path.
                    postaction={draw,decorate,decoration={border,angle=-135,
                    amplitude=0.3cm,segment length=2mm}}
                }
                ]
 \begin{scope}
  \draw [draw=none, fill=cyan!10, rounded corners=2mm] (-2,0) rectangle 
   (10,2);  
    \draw [interface, thick, black] (-2,0)--(10,0);
    \draw[draw=none, fill=brown!10, rounded corners=1mm, opacity=0.5] 
     (-2,0)rectangle (10,-1);
      \clip (-2,0) rectangle (10,-2);
      \foreach \a in {0,1,...,100}
       { 
          \draw[black!50,ultra thin,rounded corners=.5mm, fill=brown!20] 
              (8*rand, rand) \irregularcircle{0.21cm}; 

        } 
     \end{scope} 
     \end{tikzpicture}
   \end{document}

Now, i have following questions:

  1. any better way to draw stones (I used an available function on tikz to draw circle with addded noise)
  2. How could I (equally?) distribute the stones below the water? Ideally bounded between xmin,xmax AND ymin, ymax

Thank you! Marco

  • Alas, there are no built in patterns for this. I would use clip art and crop it to shape (tikz \clip, not \includgraphics [view=...]). – John Kormylo Oct 2 '18 at 14:50
  • OTOH, it might be less expensive to create your own clip art. FREE CLIP ART (only $12/image). – John Kormylo Oct 2 '18 at 15:27
8

Another two options, first using \pgfdeclarepatternformonly within tikzpicture environment to enable to use basic tikz code instructions like \draw instead \pgfpath..., the issue is that only accept paths, so filling with shades is not available; for this reason the second option is done using basic tikz code in drawing definitions to not repeat the code many times and creating another definition like a pattern helped with clip and foreach statement.

RESULT:

enter image description here

MWE:

\documentclass[tikz,border=5pt]{standalone}
\usetikzlibrary{calc}
\usetikzlibrary{patterns,shapes.geometric,decorations.pathmorphing,decorations.pathreplacing}

\begin{document}
    \begin{tikzpicture}[
    myshade/.style={
        black!50,
        draw,
        ultra thin,
        rounded corners=.5mm,
        top color=brown!20,
        bottom color=brown!20!gray
    },
    interface/.style={
                % The border decoration is a path replacing decorator. 
                % For the interface style we want to draw the original path.
                % The postaction option is therefore used to ensure that the
                % border decoration is drawn *after* the original path.
                    postaction={draw,decorate,decoration={border,angle=-135,
                    amplitude=0.3cm,segment length=2mm}}
       }
    ]
    \def\stone(#1)[#2][#3]{%Drawing manually some shape
        \begin{scope}[shift={(#1)},rotate=#2,scale=#3,transform shape]
            \draw[line width=0.25pt,rounded corners=1pt]
                (15:3pt) -- (45:4pt) -- (89:5pt)--(135:6pt) -- (150:3pt) -- (182:4pt)--(235:6pt) -- (280:3pt) -- (330:2pt) -- cycle;

        \end{scope}
    }
    %Declare a new pattern ¿form only?
    \pgfdeclarepatternformonly{pebless under sea floor}{\pgfqpoint{0pt}{0pt}}{\pgfqpoint{15pt}{15pt}}{\pgfqpoint{15pt}{15pt}}%
    {
         \stone(8pt,6pt)[-15][1]
         \stone(0pt,0pt)[45][0.7]
         \stone(15pt,15pt)[45][0.7]
         \stone(0pt,15pt)[45][0.7]
         \stone(15pt,0pt)[45][0.7]
         \stone(0pt,7.5pt)[180][0.7]
         \stone(15pt,7.5pt)[180][0.7]
         \stone(7.5pt,0pt)[90][0.7]
         \stone(7.5pt,15pt)[90][0.7]
         \draw[line width=0.25pt,rotate=-45] (5.5pt,10pt) ellipse (1pt and 2pt);
         \draw[line width=0.25pt] (12pt,10pt) circle (0.7pt);
    }
    %Create a second shape to create a brute force pattern...
    \def\stone2(#1)[#2][#3]{
        \begin{scope}[shift={(#1)},rotate=#2,scale=#3,transform shape]
            \draw[myshade]
                (15:3pt) -- (45:4pt) -- (89:5pt)--(135:6pt) -- (150:3pt) -- (182:4pt)--(235:6pt) -- (280:3pt) -- (330:2pt) -- cycle;
        \end{scope}
    }
    \def\stonepattern(#1){%Brute force pattern
        \begin{scope}[shift={(#1)}]
            \clip (0,0) rectangle ++(15pt,15pt);
            \stone2(8pt,6pt)[-15][1]
            \stone2(0pt,0pt)[45][0.7]
            \stone2(15pt,15pt)[45][0.7]
            \stone2(0pt,15pt)[45][0.7]
            \stone2(15pt,0pt)[45][0.7]
            \stone2(0pt,7.5pt)[180][0.7]
            \stone2(15pt,7.5pt)[180][0.7]
            \stone2(7.5pt,0pt)[90][0.7]
            \stone2(7.5pt,15pt)[90][0.7]
         \draw[line width=0.25pt,rotate=-45,myshade] (5.5pt,10pt) ellipse (1pt and 2pt);
         \draw[line width=0.25pt,myshade] (12pt,10pt) circle (0.7pt);
        \end{scope}
    }

    %Start drawing the thing
    \clip[rounded corners=0.2cm] (0,2) rectangle ++(12,-3);
    \fill [cyan!10] (0,0) rectangle ++(12,2);
    \fill[fill=brown!25, rounded corners=1mm, opacity=0.5] 
    (0,0) rectangle ++(12,-1);
    %Drawing sea floor using pattern
    \fill[pattern=pebless under sea floor] (0,0) rectangle ++(6,-1);
    %Dragind sea floor using brute force...
    \begin{scope}
        \clip(6,0) rectangle ++(6,-1);
        \foreach \x in {0,...,11}{
            \foreach \y in{0,...,2}{
                \stonepattern(6cm+\x*15pt,-1cm+\y*15pt)
            }
        }
    \end{scope}
    \draw [thick, black,interface] (0,0)--(13,0);

    \end{tikzpicture}
\end{document}
  • Many compliments for your work. Very nice and I have upvoted all users. – Sebastiano Oct 3 '18 at 8:35
  • J Leon V., this is very close to what I had in mind. Thank you. As a next step I want now to draw an up-sloping bed. I will try to do it and post it here to get some more feedback. – Marco Oct 3 '18 at 8:49
7

Conceptually the problem of drawing the stones is very similar to what has been done in this answer, which I am recycling here. This allows you to avoid overlaps.

\documentclass{article}
\usepackage{tikz}
\usetikzlibrary{calc}
\usetikzlibrary{%
decorations.pathreplacing,%
decorations.pathmorphing%
}
\newcommand\irregularcircle[1]{% radius, irregularity
  +(0:#1)
  \foreach \a in {30,60,...,330}{
    let \n1 = {(#1)+rand*(0.2*#1)} in
    -- +(\a:\n1)
  } -- cycle
}
%from https://tex.stackexchange.com/a/87518/121799
\def\xlist{4}
\def\ylist{4}
\newcommand{\fillrandomly}[7][]{
    \pgfmathsetmacro\diameter{#6*2}
    \foreach \i in {1,...,#7}{
        \pgfmathsetmacro\x{0.5*(#4+#2+(2*rnd-1)*(#4-#2))}
        \pgfmathsetmacro\y{0.5*(#5+#3+(2*rnd-1)*(#5-#3))}
        \xdef\collision{0}
        \foreach \element [count=\i] in \xlist{
            \pgfmathtruncatemacro\j{\i-1}
            \pgfmathsetmacro\checkdistance{ sqrt( ({\xlist}[\j]-(\x))^2 + ({\ylist}[\j]-(\y))^2 ) }
            \ifdim\checkdistance pt<\diameter pt
                \xdef\collision{1}
                \breakforeach
            \fi
        }
        \ifnum\collision=0
            \xdef\xlist{\xlist,\x}
            \xdef\ylist{\ylist,\y}
             \draw[black!50,ultra thin,rounded corners=.5mm, 
             top color=brown!20,bottom color=brown!20!gray,
             shading angle={(0.5+rand)*20}] 
              (\x,\y) \irregularcircle{0.21cm};
        \fi 

    }
}


 \begin{document}
  \thispagestyle{empty}
  \begin{tikzpicture}[
                media/.style={font={\footnotesize\sffamily}},
                wave/.style={
                decorate,decoration={snake,post length=1.4mm,amplitude=2mm,
                segment length=2mm},thick},
                interface/.style={
                % The border decoration is a path replacing decorator. 
                % For the interface style we want to draw the original path.
                % The postaction option is therefore used to ensure that the
                % border decoration is drawn *after* the original path.
                    postaction={draw,decorate,decoration={border,angle=-135,
                    amplitude=0.3cm,segment length=2mm}}
                }
                ]
 \begin{scope}
  \draw [draw=none, fill=cyan!10, rounded corners=2mm] (-2,0) rectangle 
   (10,2);  
    \draw [interface, thick, black] (-2,0)--(10,0);
    \draw[draw=none, fill=brown!10, rounded corners=1mm, opacity=0.5] 
     (-2,0)rectangle (10,-1);
      \clip (-2,0) rectangle (10,-2);
      \fillrandomly{-2+0.21}{-0.21}{10-0.21}{-1+0.21}{0.21}{37}
     \end{scope} 
\end{tikzpicture}
\end{document}

enter image description here

As for your second question: do you have a rough idea how the stones should look like? I made a proposal but it may be very different from what you're hoping to get.

It might be nicer to have the stones on the background.

\documentclass{article}
\usepackage{tikz}
\usetikzlibrary{calc}
\usetikzlibrary{%
decorations.pathreplacing,%
decorations.pathmorphing
}
\newcommand\irregularcircle[1]{% radius, irregularity
  +(0:#1)
  \foreach \a in {30,60,...,330}{
    let \n1 = {(#1)+rand*(0.2*#1)} in
    -- +(\a:\n1)
  } -- cycle
}
%from https://tex.stackexchange.com/a/87518/121799
\def\xlist{4}
\def\ylist{4}
\newcommand{\fillrandomly}[7][]{
    \pgfmathsetmacro\diameter{#6*2}
    \foreach \i in {1,...,#7}{
        \pgfmathsetmacro\x{0.5*(#4+#2+(2*rnd-1)*(#4-#2))}
        \pgfmathsetmacro\y{0.5*(#5+#3+(2*rnd-1)*(#5-#3))}
        \xdef\collision{0}
        \foreach \element [count=\i] in \xlist{
            \pgfmathtruncatemacro\j{\i-1}
            \pgfmathsetmacro\checkdistance{ sqrt( ({\xlist}[\j]-(\x))^2 + ({\ylist}[\j]-(\y))^2 ) }
            \ifdim\checkdistance pt<\diameter pt
                \xdef\collision{1}
                \breakforeach
            \fi
        }
        \ifnum\collision=0
            \xdef\xlist{\xlist,\x}
            \xdef\ylist{\ylist,\y}
             \draw[black!50,ultra thin,rounded corners=.5mm, 
             top color=brown!20,bottom color=brown!20!gray,
             shading angle={(0.5+rand)*20}] 
              (\x,\y) \irregularcircle{0.21cm};
        \fi 

    }
}


 \begin{document}
  \thispagestyle{empty}
  \begin{tikzpicture}[
                media/.style={font={\footnotesize\sffamily}},
                wave/.style={
                decorate,decoration={snake,post length=1.4mm,amplitude=2mm,
                segment length=2mm},thick},
                interface/.style={
                % The border decoration is a path replacing decorator. 
                % For the interface style we want to draw the original path.
                % The postaction option is therefore used to ensure that the
                % border decoration is drawn *after* the original path.
                    postaction={draw,decorate,decoration={border,angle=-135,
                    amplitude=0.3cm,segment length=2mm}}
                }
                ]
  \draw [draw=none, fill=cyan!10, rounded corners=2mm] (-2,0) rectangle 
   (10,2);  
  \begin{scope}
   \clip (-2,0) rectangle (10,-2);
   \draw[draw=none, fill=brown!10, rounded corners=1mm, opacity=0.5] 
     (-2,0)rectangle (10,-1);
   \fillrandomly{-2+0.21}{-0.21}{10-0.21}{-1+0.21}{0.21}{37}
   \draw [interface, thick, black] (-2,0)--(10,0);
  \end{scope} 
\end{tikzpicture}
\end{document}

enter image description here

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.