计算机图形学01—分形树(OpenGL)(C++语言)
本篇用来展示使用OpenGL做的分形树。编程语言使用的是C++语言。
程序运行结果如下所示:
在程序中还设置了场景漫游,可以使用键盘来控制前进、后退、向左转以及向右转。
程序代码:
由于程序较多,这里展示画分形树的重要函数代码,完整代码资源可见计算机图形学—分形树(OpenGL)
void LSystemRule1()
{
//初始化
//std::cout << "进入LSystemRule()" << endl;
way = "FA[+X][-&X]-%XB";
//std::cout << "进入LSystemRule() 定义了三条规则" << endl;
len = 30.0f;//长度
Alphaz = 40;
Alphay = 60;
n = 8;
k = 0;
stackpointer = 0;//栈顶指针
for (int i = 0; i < 150; i++)
{
stack[i].point.x = 0.0;
stack[i].point.y = 0.0;
stack[i].point.z = 0.0;
stack[i].directionz = NULL;
stack[i].directiony = NULL;
}
temprule = way;
for (int i = 1; i <= n; i++)
{
int curlen = temprule.length();
int pos = 0, j = 0;
while (j < curlen)
{
if (temprule[j] == 'X')//迭代,将其中的F替换成文法模型
{
rule += way;
j++;
pos = rule.length() - 1;
}
else//保留转角
{
rule += temprule[j];
pos++;
j++;
}
}
temprule = rule;
rule.clear();
}
rule = temprule;//迭代好之后的文法规则
}
void LSystemRule2()
{
//初始化
std::cout << "进入LSystemRule()" << endl;
/*grassway[0] = "FFF[+&FF]F[-%%%%%&F]F";
grassway[1] = "FFF[+%FF]F[-F&[+%F]]";
grassway[2] = "FF-[&&--F+F+F]+[%+F+F-F]";
grassway[3] = "FF[+F+F-[++F-F++F]]F[--F-F+[F-F++F]]";
grassway[4] = "FF[&F&F%[F%F&&F]]F[%F%F&[F%F&&F]]";*/
gr = "FF[+%%F+F-[%F-F++F]]F[%-F-F+[F-F++F]]";
std::cout << "进入LSystemRule() 定义了三条规则" << endl;
lenline = 0.1f;//长度
Alpha = 35;
num = 2;
stackpointer1 = 0;
for (int i = 0; i < 150; i++)
{
stack1[i].point.x = 0.0;
stack1[i].point.y = 0.0;
stack1[i].point.z = 0.0;
stack1[i].directiony = NULL;
stack1[i].directionz = NULL;
}
//rule = way[0];
//rule1 = grassway[rand() % 5];
rule1 = gr;
for (int i = 1; i <= num; i++)
{
int curlen = temprule1.length();
//cout << curlen << endl;
int pos = 0, j = 0;
while (j < curlen)
{
if (temprule1[j] == 'F')
{
//rule1 += grassway[rand() % 5];
rule1 += gr;
//rule = way[0];
j++;
pos = rule1.length() - 1;
}
else
{
rule1 += temprule1[j];
pos++;
j++;
}
}
temprule1 = rule1;
//rule1.empty();
rule1.clear();
}
rule1 = temprule1;
std::cout << "出LSystemRule()" << endl;
}
void drawGrass(CVector3D p,float R,float G,float B)
{
Node Nextnode, Curnode;
Curnode.point.x = p.x;
Curnode.point.y = p.y;
Curnode.point.z = p.z;
Curnode.directionz = -85;
Curnode.directiony = 0;
int length = rule1.length();
//std::cout << "长度 = " << length << endl;
int i = 0;
//cout << rule << endl;
glRotatef(180, 1.0, 0.0, 0.0);
glTranslatef(0.0, 30.0, 0.0);
glPushMatrix();
while (i < length)
{
//std::cout << "rule[i] = " << rule[i] << endl;
switch (rule1[i])
{
case 'F':
Nextnode.point.x = Curnode.point.x + lenline * cos(Curnode.directionz * PI / 180) * cos(Curnode.directiony * PI / 180);
Nextnode.point.y = Curnode.point.y + lenline * sin(Curnode.directionz * PI / 180);
Nextnode.point.z = Curnode.point.z - lenline * cos(Curnode.directionz * PI / 180) * sin(Curnode.directiony * PI / 180);
Nextnode.directiony = Curnode.directiony;
Nextnode.directionz = Curnode.directionz;
/*std::cout << "Nextnode.point.x= " << Nextnode.point.x << endl;
std::cout << "Nextnode.point.y= " << Nextnode.point.y << endl;
std::cout << "Nextnode.point.z= " << Nextnode.point.z << endl;*/
glBegin(GL_LINES);
glColor3f(R,G,B);
glVertex3f(Curnode.point.x, Curnode.point.y, Curnode.point.z);
glVertex3f(Nextnode.point.x, Nextnode.point.y, Nextnode.point.z);
glEnd();
Curnode = Nextnode;
break;
case '[':
stack1[stackpointer1] = Curnode;
stackpointer1++;
break;
case ']':
Curnode = stack1[stackpointer1 - 1];
stackpointer1--;
break;
case '+':
Curnode.directionz = Curnode.directionz + Alpha;
break;
case '-':
Curnode.directionz = Curnode.directionz - Alpha;
break;
case '&':
Curnode.directiony = Curnode.directiony + Alpha;
break;
case '%':
Curnode.directiony = Curnode.directiony - Alpha;
break;
default:
;
}
i++;
}
glPopMatrix();
//std::cout << "完成!" << endl;
}
有其他问题欢迎私信,一起讨论学习!