C++ 如何用代码控制L系统模式?
我正在做一个项目,以显示和动画的树木生长。我在这个项目中使用C++和OpenGL。树长到一定数量的树枝,停下来,然后树叶掉到地上。我决定使用Lidenmayer系统以图形化的方式来描述这一点,因为它似乎是创建结构和定义树的每个元素的一个更容易的替代方法。到目前为止,我可以展示树干和天空,但我不知道如何让树长出新的树枝。我考虑过也许做一个for循环来控制它,但我不确定如何完成它。处理这个问题的好方法是什么 我的L系统规则: 推导长度:10 公理:F F-->G[-F][+F]GF G-->GG 旋转角度=15.0度(.2618弧度) 更新:这是我到目前为止得到的C++ 如何用代码控制L系统模式?,c++,opengl,C++,Opengl,我正在做一个项目,以显示和动画的树木生长。我在这个项目中使用C++和OpenGL。树长到一定数量的树枝,停下来,然后树叶掉到地上。我决定使用Lidenmayer系统以图形化的方式来描述这一点,因为它似乎是创建结构和定义树的每个元素的一个更容易的替代方法。到目前为止,我可以展示树干和天空,但我不知道如何让树长出新的树枝。我考虑过也许做一个for循环来控制它,但我不确定如何完成它。处理这个问题的好方法是什么 我的L系统规则: 推导长度:10 公理:F F-->G[-F][+F]GF G-->GG 旋
#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();
}
#包括
#包括
#包括
#包括
int-treeSeed=0;
浮子枝=0.2618;
/*
控制树的生长。因素
生长的速度与收缩树的速度相反
方法
*/
//void GrowTree()
//{
/*树的生长方向取决于
关于L-系统规则*/
//
//int i;
//对于(i=0;i我认为你试图一次解决太多问题。你试图:
- 构建一种用于评估递归树结构的形式化语言
- 构建一个方法,用于指定在“age”上参数化的树规则
- 呈现给定的树规则
在你以最大程度的概括性解决这个问题之前,我先解决一个特例
使用硬编码组件渲染树
向树中添加参数以控制这些组件(分支长度、分支计数等)
编写一个由“age”参数化的函数,用于控制低级树组件
编写从L系统规则到低级树参数的转换函数
正如Jonathan所说,看起来你试图同时做的事情太多了。通常,对于L系统,树的生成与渲染是分开的
如果我正确理解您的规则:
Axiom: F
F --> G[-F][+F]GF
G --> GG
那么您的起始树是:
tree(0): F
i、 e树干。通过对树应用一次规则来生长树,在这种情况下,将产生以下结果:
tree(1): G[-F][+F]GF
另一次迭代将使其进一步增长并产生:
tree(2): GG[-G[-F][+F]GF][+G[-F][+F]GF]GGG[-F][+F]GF
等等
通常,您可以通过逐个字符迭代字符串来实现这一点,对于与规则匹配的每个字符,将规则rhs附加到目标字符串,否则只需附加字符
通过遍历树字符串再次渲染树,这一次将其解释为一组渲染指令,即F作为向前移动光标一个单位画一条线,+作为向左旋转光标等
如果通过一次迭代交替增长树,然后对其进行渲染,则该树将显示为增长
因此,从概念上讲,您可能希望从一个Tree
类开始,该类封装了公理、规则等和当前树字符串。该类将知道如何生长树,但不知道如何渲染树。因此,您还将有一个renderer类OpenGLRenderer
,该类将处理该问题。然后您将有一个如下循环:
while (someFlag)
{
tree->grow ();
renderer->render (tree.stringRep ());
}
其中大部分只是L-systems的基础,您可能已经知道,在这种情况下,我仍然不明白您到底在问什么。好的,我决定将GrowerShrink方法分为两个单独的方法,分别命名为Grow和Shrink。这是我的更新代码。/*控制树的生长*///void Grow()//{/*树的生长方向取决于L-系统规则*/int i;for(i=0;很抱歉这段代码很难理解,但我不确定如何编辑我当前的问题。如果不知道树是如何表示的,这是不可能回答的。我的L-系统规则:我的L-系统规则:派生长度:10公理:F-->G[-F][+F]GF G-->GG旋转角度=15.0度(.2618弧度)我猜这就是你的意思。如果你愿意,我也可以添加我的完整源代码。很高兴我找到了这篇文章!这对我用python完成我的l-systems项目非常有帮助。非常感谢!