如何生成三维树在任何给定的点和方向的空间与c++和l系统

How to generate 3d trees in any given point and direction in space with C++ and L-Systems?

本文关键字:空间 方向 c++ 系统 何生成 任何 三维      更新时间:2023-10-16

我正在用c++编程一个3d场景,其中树木可以在任何点和任何方向"生长"。我发现l系统的树/行星看起来非常好,但我不能谷歌一些函数或库,可以让我传递一个点坐标,一个方向矢量和一些其他参数,并返回一个数组的"生长"的树点集。

我甚至不能谷歌足够的信息来开始。所以任何想法或链接,我可以参考,或重用,并作出一些调整,以完成这项任务。我找到了一些L-sys解析器,但它看起来只是在原地绘图,而没有控制生长方向,也无法给出整个点的坐标。

这可能是你自己从头开始实现比搜索和尝试集成一些第三方库更快的问题。

实现l -系统相当容易。你需要实现两个部分。

第一部分是字符串重写系统。这很简单。你只需要有一个重写规则的字典(char键,字符串值),然后将这些规则应用于初始字符串i次(其中i是迭代次数)。

伪代码:

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
        }
    }
}

第二个比较困难的部分是符号结果字符串的解释。最简单的方法是使用四元数来解释3D中类似乌龟的图形——将它们组合起来很简单。

上面重写的规则是描述龙曲线,符号的语义含义为:

  • L, R:向前划线
  • +:左转90度
  • -:右转90度

下面的代码片段演示了使用四元数在3D中移动和旋转的实现。这是我用c#写的l系统解释器(我希望你能原谅我:)。

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);
}

所以要解释字符串,你只需要遍历字符串并解释每个符号。最简单的方法是:

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
    }
}

如果你想尝试l系统(即使在3D)有一个很好的网站http://malsys.cz在那里你可以这样做(那些c#片段来自它:)

祝你L-systems好运!

我不知道有任何提供3d L-system算法的开源库,我想你必须自己编写。

从2d实现开始,这非常简单,维基百科页面是查看简单示例的好地方,一旦2d实现完成,扩展到第三个应该遵循。