【问题标题】:How to generate 3d trees in any given point and direction in space with C++ and L-Systems?如何使用 C++ 和 L-Systems 在空间中的任何给定点和方向生成 3d 树?
【发布时间】:2013-02-22 21:12:20
【问题描述】:

我正在用 C++ 编写一个 3d 场景,其中树木可以在任何点和任何方向“生长”。我发现 L-systems 树/行星看起来非常好,但我无法搜索一些函数或库,这些函数或库可以让我传递点坐标、方向向量和一些其他参数,并返回该“生长”树点集的数组。

我什至无法搜索到足够的信息来开始。因此,我可以参考或重复使用并进行一些调整以完成此任务的任何想法或链接。我找到了一些 L-sys 解析器,但它看起来只是在没有控制生长方向的情况下绘制到位,并且也未能给我整个点坐标。

【问题讨论】:

    标签: c++ 3d l-systems


    【解决方案1】:

    这可能是您自己从头开始实施的问题,而不是搜索和尝试集成一些 3rd 方库。

    实现 L 系统相当容易。您需要实现 2 个部分。

    第一部分是字符串重写系统。很简单。您只需要有一个重写规则字典(字符键、字符串值),然后将这些规则应用于初始字符串 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度

    以下代码 sn-ps 演示了使用四元数在 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-systems(即使是 3D),有一个不错的网站 http://malsys.cz 可以这样做(那些 C# sn-ps 来自它:)

    祝 L 系统好运!

    【讨论】:

      【解决方案2】:

      我不知道任何提供 3d L 系统算法的开源库,我怀疑你必须自己编写。

      从 2d 实现开始,它非常简单,wikipedia 页面是查看简单示例的好地方,一旦 2d 实现完成,接下来应该扩展到第三个。

      【讨论】:

        猜你喜欢
        • 2020-05-09
        • 2016-07-21
        • 2013-03-28
        • 1970-01-01
        • 2017-07-04
        • 1970-01-01
        • 2014-10-24
        • 1970-01-01
        • 2020-07-31
        相关资源
        最近更新 更多