Lindenmayer brush for Krita

This term i had a course about fractals on the university. We also had to write code for a submission and the lecturer made the technique and topic free to choose. So I chose to make a lindenmayer brush for krita, because I planed to do so since the first university year, where I heard of lindenmayer systems the first time.

I quickly coded something together, so that I was able to prove, that my idea would work.

Lindenmayer systems are some kind of a grammar, they work like this: You have an alphabet of letters, in this case these letters are simple short lines, then you have productions and a rule: Always produce all letters. These productions eat one letter and produce ether no, one or several new letters. There are several classes of such productions, one of the simplest would be “A -> AA”. More sophisticated productions, like in the brush, can contain parameters, if clauses, calculations, random values etc. Basically it would be possible to have several different productions, but I chose to have only one and in turn make it more powerful.

Here is an example of a production, it is used in one of the brushes:

if{letter[branched] == false} {
newLetter = newLetter();
newLetter[position] = variant(letter[endPosition]);
newLetter[angle] = variant(newLetter[angleToSun]);
newLetter[length] = 5;
letter[branched] = bool(true);
}

if{letter[age] > 1} {
letter.delete();
}

It actually creates just a line.

At first the productions were plain C++ code, but that is very cumbersome, as you have to build, install and start krita for testing. The next thing I tried, was to use QtScript and write the productions in ECMAScript (also called JavaScript). It took about 5 to 7 hours until I proved, that it was way to slow.

So I decided to implement my own little scripting language. The interpreter is about 700 lines of code, including some tests. It’s certainly not as powerful, as ECMAScript, but it’s fast and okayish for this use case.

There is an if clause, which supports &&, there is a rand() function, a function for mixing angles, some very basic math, bool and float data types, you can create new letters and delete old ones. It’s possible to write new parameters (“branched” in the code above), edit some default ones (position, angle, length..), which will be used for drawing and access some computed ones (endPosition, angleToSun, distanceToSun, age..).

I have to write some documentation, expand the possibilities of the language and work on the configuration interface. But for now you can already test the current code, it’s in the krita-lbrush-adamc branch in the calligra repository.

Here is a final picture..

The presets for this brushes are included in the repository :)

Tags: , , ,

7 Responses to “Lindenmayer brush for Krita”

  1. Great job! The result is very pretty and I can’t wait to use the new brushes!

  2. maninalift says:

    doubleawesome

  3. Bugsbane says:

    So, will this be in the 2.4 release?

  4. Adam Celarek says:

    No. The feature freeze for 2.4 was some time ago and the brush is far from finished..

  5. Bugsbane says:

    Ah well. It’ll be cool in 2.5, just please, please, please use a name for this that will actually help new users to understand what it’s supposed to do. “Lindenmayer brush” would mean nothing to the uninitiated. Something like “fractal brush”, almost anyone could guess roughly what it might do, before they even use it.

    Anyway, great work. It looks fantastic, and the possibilities of it combined with GHNS are huge!

  6. Adam Celarek says:

    I will think of a better name. Maybe Scripted Brush or something like that, because fractal brush also doesn’t really resemble it’s style. I hope, that it’s not too technical..

    For now I will stick to the working title Lindenmayer brush though :)

    Yeah, GHNS will be awesome with it :)