5

I'm trying to draw a classical Koch-Curve using the lindenmayersystem, but everytime a line segment is transformed there should be a 50/50 chance of it to be flipped left or right. The goal is to generate a realistic looking coastline made out of the directions for Koch-Curve-constructions. I'm really not familiar with the random function of tikz, so my attempt doesn't work at all:

\documentclass[border=9,tikz]{standalone}
\usetikzlibrary{lindenmayersystems}
\begin{document}
\pgfdeclarelindenmayersystem{Koch curve}{
  \symbol{A}{\pgflsystemdrawforward}
  \symbol{B}{\pgflsystemdrawforward}
  \rule{A -> A+A--A+A}
  \rule{B -> B-B++B-B}
  \rule{S -> (random(A,B))}
  }

  \tikz\draw[lindenmayer system={Koch curve,angle=60,axiom=S,order=4}]lindenmayer system;

\end{document}

enter image description here

Edit: I almost got it now, the only remaining problem is that after each sequence (four lines with a pike) the angles stay randomized. That causes the overall segments of the curve to not follow the initial construction rule for the Koch-Curve (A+A--A+A):

\documentclass[border=9,tikz]{standalone}
\usetikzlibrary{lindenmayersystems}
\begin{document}
\pgfdeclarelindenmayersystem{Koch curve}{
  \symbol{A}{\pgflsystemdrawforward}

  \symbol{a}{\pgfmathrandom{0}{1}\ifnum\pgfmathresult=0%
\def\pgflsystemrightangle{120}\def\pgflsystemleftangle{60}%
\else\def\pgflsystemrightangle{-120}\def\pgflsystemleftangle{-60}\fi}

  \symbol{+}{\pgflsystemturnleft}
  \symbol{-}{\pgflsystemturnright}

  \rule{A -> Aa+A-A+A}
  }

  \tikz\draw[lindenmayer system={Koch curve,axiom=A,order=2}]lindenmayer system;

\end{document}

enter image description here

The last segment that goes to the top left should lust go straight to the right just like the first segment. Does anybody know how to fix that?

5
  • 2
    Yes, this is built-in. There are some keys that start with randomize. At the lower-level, the commands start with \pgflsystemrandomize… which are already used by \pgflsystemdrawforward and for example \pgflsystemturnleft. Commented Dec 8, 2022 at 14:29
  • @Qrrbrbirlbel ok thank you very much! Do you by any chance know where I can find information on how to use those commands correctly?
    – Stroebel
    Commented Dec 12, 2022 at 9:42
  • The manual itself explains them pretty good. That said, I've digged around a bit and there is no built-in way to randomnize between A and B inside a rule. I've also tried making a symbol that calls another symbol based on a random number but that's not that easy because we would need to mess with the parser. But it wouldn't be hard to do random stuff inside a symbol. \pgfmathrandom{0}{1}\ifnum\pgfmathresult=0 \pgflsystemdrawforward\else\pgftransformrotate{180}\pgflsystemdrawforward\fi. Commented Dec 12, 2022 at 10:04
  • @Qrrbrbirlbel thanks again! I'll try to implement that later, hopefully It'll work!
    – Stroebel
    Commented Dec 12, 2022 at 12:43
  • Ok 7 hours in and I still can't do it. I tried to change around the angles but that doesn't seem to be the solution.
    – Stroebel
    Commented Dec 12, 2022 at 20:14

1 Answer 1

0

Since this old Q is still waiting for a TikZ answer, here is a comparison in Metapost, the graphics language that is available to lualatex with the luamplib package.

a simulated coast line

\documentclass[border=5mm]{standalone}
\usepackage{luamplib}
\begin{document}
\begin{mplibcode}
vardef complicate(expr a, b) = 
    save c, d, m; pair c, d, m;
    c = 1/3[a, b];
    d = 2/3[a, b];
    m = d rotatedabout(c, 60 normaldeviate);
    if abs(b-a) > 2:
        complicate(a, c) &
        complicate(c, m) &
        complicate(m, d) &
        complicate(d, b) 
    else:
        a--c--m--d--b
    fi
enddef;
input colorbrewer-rgb
beginfig(1);
    path coast; 
    coast = complicate(origin, 400 right) -- (400, -100) -- (0, -100) -- cycle;

    color water, land;
    water = Blues 9 2; land = Oranges 9 2;

    fill bbox coast withcolor water;
    fill coast withcolor land;
    draw coast withpen pencircle scaled 1/4;

endfig;
\end{mplibcode}
\end{document}

You need to compile this with lualatex.

Notes

I do not know of any formal L-system for MP, but it is not too hard to write your own recursive function as I have done here. The recursive function complicate(a, b) takes the two end points, and works out three intermediate points. If the distance between a and b is more than 2pt (0.7mm), it calls itself again four times, otherwise it just returns the path through the five points. The results from the recursive calls are spliced together with & so that the top level call returns a <path> value.

Some of the results look better than others. I ran it a few times before I got the picture of Brittany above.

If you were to remove the random part, and just put this:

m = d rotatedabout(c, 60); 

in line 4 of the function, then you would get the regular Koch snowflake curve:

enter image description here

1
  • All you had to do was draw the coastline of French Bretagne. :-)
    – projetmbc
    Commented Jul 10 at 8:20

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .