2009-12-11 24 views
-1

我正在开发一个项目来显示和生成一棵生长的树。我在这个项目上使用C++和OpenGL。树长到一定数量的树枝,停下来,然后树叶落到地上。我决定使用Lidenmayer系统以图形方式描述这一点,因为它似乎是创建结构和定义树的每个元素的更简单的替代方法。到目前为止,我可以展示树干和天空的树干,但是我失去了如何真正让树木生长新的树枝。我认为可能做一个for循环来控制这个,但我不知道如何完成它。什么是解决这个问题的好方法?如何用我的代码控制我的L系统模式?

我的L-系统规则:

推导长度:10 公理:F 的F - > G [-F] [+ F] GF ģ - 旋转> GG

角= 15.0度(.2618弧度)

更新:这是我到目前为止。

#include <math.h> 
#include <windows.h> 
#include <GL/gl.h> 
#include <glut.h> 

int treeSeed = 0; 
float branchAngle = .2618; 

/* 
    Controls the growth of the tree. Factor 
    of growth is inverse to that of the ShrinkTree 
    method 

*/ 

//void GrowTree() 
//{ 
    /*Tree grows in a direction depending 
    on the L-System rules */ 
// 
//  int i; 
//  for(i = 0; i <=10 ; i++) 
//  { 
//   
//   //grow tree 
// 
//  } 

//} 

/* 
Tree shrinks in a direction depending 
on the L-System rules. Factor of shrinkage is 
inverse to that of the GrowTree method.*/ 

void ShrinkTree() 
{ 
    /*int j; 
    for (j = -; j <=10 ; j++) 
    { 

    }*/ 

} 

//void treeAninmation() 
//{ 
// 
// glutPostRedisplay(); 
//} 


/* 
    Draws a leaf on the branch. 
    If the seed axiom is at zero, 
    a new leaf is drawn. Otherwise, 
    the branch shrinks to accomodate 
    existing leaves. 


*/ 

void DrawLeaf() 
{ 


    if(treeSeed==0) 
    { 
     glBegin(GL_QUADS); 
     glColor3f(0.0f,1.0f,0.0f); 

     glVertex2f(-0.05, -40.5); 
     glVertex2f(-0.05, -20.5); 
     glVertex2f(-0.02, -40.5); 
     glVertex2f(-0.02,-20.5); 

     glEnd(); 

    } 
    /*else 
    { 

     GrowTree(); 
     DrawTwig(treeSeed-1); 
     glPushMatrix(); 
       glRotate(branchAngle,1.0f,0.0f,0.0f); 
       DrawLeaf(treeSeed-1); 
     glPopMatrix(); 
     glPushMatrix(); 
       glRotate(branchAngle,); 
       DrawLeaf(treeSeed-1); 
     glPopMatrix(); 
    }*/ 

} 


void DrawTwig() 
{ 

    /* 

     Draws trunk of tree 
     Represents base scenario of 
     recursion 

    */ 
    if(treeSeed==0) 
    { 

     glLineWidth(5.0); 

     glBegin(GL_LINE_STRIP); 

     glColor3f(0.60f,0.40f,0.12f); 

     glVertex2f(-0.10, -80.5); 
     glVertex2f(-0.10, -100.5); 

     glEnd(); 

    } 

    /*else 
    { 
     ShrinkTree(); 
     DrawTwig(treeSeed-1); 

    }*/ 
} 



/* Draws the tree with leaves * 
    Uses recursion to draw tree structure 
    Relies on L-System formula in order 
    to produce a tree 

*/ 

void DrawTree() 
{ 

    DrawTwig(treeSeed); 
    //DrawLeaf(treeSeed); 


} 




/* Draws the horizon, the sky, and the ground*/ 

void RenderScene(void) 
{ 
    // clears color buffer 
    glClear(GL_COLOR_BUFFER_BIT); 

    /* 
    //GLfloat y; 
    GLfloat fSizes[2]; // Store supported line width range 
    GLfloat size; // Store supported line width increments 
    */ 

    //The horizon lies in the xy plane 

    glBegin(GL_LINE_STRIP); 

    glColor3f(0.0f,0.0f,0.0f); //sets color of horizon to black 
    glVertex2f(-135.0,0.0); 
    glVertex2f(135.0,0.0); 

    glEnd(); 

    //The sky lies in the xy plane 
    //Starts at horizon line, 
    //goes upwards to height edge of screen, 
    //and goes rightwards to width edge of screen. 


    glBegin(GL_QUADS); 

    glColor3f(0.0f,0.0f,1.0f); 

    glVertex2f(135.0, 0.0); 
    glVertex2f(-135.0, 0.0); 
    glVertex2f(-135.0, 100.0); 
    glVertex2f(135.0,100.0); 


    glEnd(); 

    DrawTree(); 

    glFlush(); 

} 


void SetupRC(void) 
{ 

    glClearColor(1.0f,1.0f,1.0f,1.0f); 

} 


void ChangeSize(GLsizei w, GLsizei h) 
{ 
    GLfloat aspectRatio; 

    //prevents divison by zero 
    if(h ==0) 
     h = 1; 

    //set Viewport to window dimensions 
    glViewport(0,0,w,h); 

    // Reset coordinate system 
    glMatrixMode(GL_PROJECTION); 
    glLoadIdentity(); 

    // Establish clipping volume (left, right,bottom,top,near,far 

    aspectRatio = (GLfloat)w/(GLfloat)h; 

    if (w <= h) 
     glOrtho (-100.0, 100.0, -100/aspectRatio, 100/aspectRatio,1.0,-1.0); 
    else 
     glOrtho (-100.0 * aspectRatio, 100.0 * aspectRatio, -100.0, 100.0, 1.0, -1.0); 
    glMatrixMode(GL_MODELVIEW); 
    glLoadIdentity(); 
} 

void main(int argc, char **argv) 
{ 
    glutInit(&argc, argv); 

/* Testing basic display functions for now */ 

    glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB); 
    glutInitWindowSize(1000, 1000); 
    glutCreateWindow("falling leaves"); 
    glutReshapeFunc(ChangeSize); 
    glutDisplayFunc(RenderScene); 
    //glutIdleFunc(treeAnimation); 
    //glutDisplayFunc(DrawTree); 
    SetupRC(); 
    glutMainLoop(); 
} 
+0

好的,我决定将GroworShrink方法分成两个独立的方法,名为Grow和Shrink。这是我更新的代码。 /* \t Controls the growth of the tree */ //void Grow() //{ \t /*Tree grows in a direction depending \t on the L-System rules */ \t \t int i; \t \t for(i = 0; i <=10 ; i++) \t \t { \t \t \t \t \t \t //grow tree \t \t } \t \t } void Shrink() { \t int j; \t for (j = -; j <=10 ; j++) \t { \t } } user230013 2009-12-11 23:58:27

+0

对不起,难以阅读的片段,但我不知道如何编辑我目前的问题。 – user230013 2009-12-11 23:59:47

+0

如果不知道树如何表示,这是不可能回答的。 – 2009-12-13 10:32:03

回答

1

我想你试图一次解决太多的事情。您正试图:

  • 构建评估递归树结构的正式语言。
  • 构建一个用于指定在“年龄”上参数化的树规则的方法。
  • 渲染给定的树规则。

在最大程度上解决这个问题之前,我会解决一个特例。

  1. 渲染与硬编码的组件树
  2. 添加参数,以你的树,以控制这些部件(枝长,枝数等)
  3. 写由控制低“时代”参数化的功能高级树组件。
  4. 写的信用证系统规则转换函数为低电平树参数
1

乔纳森指出,它看起来像你试图在同一时间做太多的事情。通常对于L系统,树生成与渲染是分开的。

如果我正确理解您的规则:

Axiom: F 
F --> G[-F][+F]GF 
G --> GG 

然后你的出发树:

tree(0): F 

即树干。

tree(1): G[-F][+F]GF 

另一次迭代将进一步扩大它和产量:

tree(2): GG[-G[-F][+F]GF][+G[-F][+F]GF]GGG[-F][+F]GF 

等您可以通过制作一个规则应用到你的树,在这种情况下会产生以下,苹果树在成长。

通常情况下,您将通过逐字符遍历字符串来实现此操作,并且对于匹配规则的每个字符都将规则rhs附加到目标字符串,否则只是追加字符。

渲染树再次通过树串迭代完成,此时它解释一组渲染指令表示为F作为移动光标一个单元向前画一条线,+作为旋转光标左等

如果通过一次迭代交替增长树,然后再进行渲染,树会显得增长。

所以从概念上讲,你可能想从一个Tree类开始,它封装了公理,规则等和当前的树字符串。这个类将知道如何增长树,但不知道如何渲染它。所以你也会有一个渲染器类OpenGLRenderer来处理这个问题。然后,您有一个循环像这样:

while (someFlag) 
{ 
    tree->grow(); 
    renderer->render (tree.stringRep()); 
} 

其中大部分是L-系统,你可能已经知道的只是基础知识,在这种情况下,我还是不明白它到底是什么你问。

+0

很高兴我发现这篇文章!这是非常有帮助的,因为我一直在使用python中的l系统项目。谢谢一堆! – mdegges 2011-09-25 00:29:06

相关问题