1

I am programming in C++ a 3d scene in which trees can be "grown" in any point and in any direction. I find the L-systems trees/planets look very nice but I cannot google some function or library that can let me pass a point coordinate, a direction vector and some other parameters, and return an array of that "grown" tree point set.

I cannot even google out enough information to start. So any idea or link I can refer to, or re-use and make some adjustment to get this task done. I found some L-sys parsers, but it looked like just drawing in place without controlling growing directions and also failed giving me whole point coordinates.

Gagiel
  • 45
  • 5

2 Answers2

4

This is probably problem which is faster to implement from scratch on your own rather for searching and trying to integrate some 3rd party libraries.

Implementing L-systems is fairly easy. You need to implement 2 parts.

The first part is string-rewriting system. It is simple. You just need to have a dictionary of rewrite rules (char key, string value) and then apply those rules for initial string i-times (where i is number of iterations).

Pseudo-code:

map<char, string> rewriteRules = {{'L', "L+R+"}, {'R',"-L+R"}};

string rewrite(string str) {
    string result = "";
    for each (char c in str) {
        if (rewriteRules contains key c) {
            result += rewriteRules[c];
        }
        else {
            result += c; // identity
        }
    }
}

The second, harder part is interpretation of result string of symbols. The easiest way how to interpret turtle-like graphics in 3D is to use quaternions - it is simple to combine them.

Rewrite rules above are describing Dragon Curve and semantic meaning of symbols is:

  • L, R: Draw line forward
  • +: turn left 90 degrees
  • -: turn right 90 degrees

Following code snippets are demonsttrating implementation of moving and rotating in 3D using quaternions. It is from my L-system interpreter written in C# (I hope you will forgive me :).

Quaternion rotationQuat = Quaternion.Indentity;
Vector3D position;

Vector3D forwardVector = new Vector3D(1, 0, 0);
Vector3D upVector = new Vector3D(0, 1, 0);
Vector3D rightVector = forwardVector.Cross(upVector);

public void Forward(double distance, bool draw) {
    Vector3D moveVector = rotationQuat.Transform(forwardVector * distance);
    Vector3D oldPosition = position;
    position += moveVector;

    if (draw) {
        // draw cylinder/box from oldPosition to (new) position
    }
}

public void Yaw(double angle) {
    rotationQuat *= new Quaternion(upVector, angle);
}

public void Pitch(double angle) {
    rotationQuat *= new Quaternion(rightVector, angle);
}

public void Roll(double angle) {
    rotationQuat *= new Quaternion(forwardVector, angle);
}

So to interpret the string you just need to go through string and interpret each symbol. The simplest way is just switch:

for each (char c in string) {
    switch(c) {
    case 'L':
    case 'R':
        Forward(10, true);
        break;
    case '+':
        Yaw(90);
        break;
    case '-':
        Yaw(-90);
        break;
    default:
        break; // do nothing
    }
}

If you want to experiment with L-systems (even in 3D) there is nice web site http://malsys.cz where you can do so (Those C# snippets are from it :)

Good luck with L-systems!

NightElfik
  • 4,328
  • 5
  • 27
  • 34
0

I do not know of any open source library which provides 3d L-system algorithms, I suspect you'll have to write your own.

Start off with a 2d implementation, it's pretty straightforward, the wikipedia page is a good place to see simple examples, once the 2d implementation is complete, extending to a third should follow from that.

Gearoid Murphy
  • 11,834
  • 17
  • 68
  • 86