Tree.cpp
资源名称:XLT.rar [点击查看]
上传用户:yunyi28
上传日期:2021-04-25
资源大小:6978k
文件大小:8k
源码类别:
分形几何
开发平台:
Visual C++
- #include "Tree.h"
- #include <math.h>
- #include <windows.h>
- #include <gl/gl.h>
- #include <time.h>
- #include "Data.h"
- #define PI 3.14159
- Tree::Tree(void)
- {
- bCount = 0;
- }
- Tree::~Tree(void)
- {
- // if(branch) delete[] branch;
- }
- void Tree::InitTree(TreeInfo *i)
- {
- info = i;
- }
- void Tree::InitTreeInfo()
- {
- int i;
- string formtree;
- // srand(time(0));
- //info->base[]为字符串数组(生成规则集),numbase为规则个数此处随机选择初始图
- formtree = info->base[rand() % info->numBase] ;
- info->tree.clear ();
- //////////////////////////////////////////////////////////////
- //循环depth次
- for ( i = 0 ; i < info->depth ; ++i)
- {
- int curlen = formtree.length();
- int j = 0 ;
- while (j < curlen)
- {
- /*扫描初始字符串(初始图),遇到'F'将在base中随机选择字符串(生成元)替代
- 遇到'['']''-''+'将有初始字符串替代*/
- if(formtree[j] == 'F')
- info->tree += info->base[rand()%info->numBase];
- else
- info->tree += formtree[j] ;
- ++j;
- }
- formtree = info->tree ;//生成表达式
- info->tree.clear ();
- }
- info->tree = formtree ;
- }
- void Tree::BuildTree()
- {
- //如果tree为空,返回
- if(info->tree.empty())
- return ;
- else
- {
- TreeNode stack[STACK_SIZE];
- TreeNode curNode,nextNode;
- int stackpushpos = 0;
- int i;
- for(i=0;i<MAX_BRANCH;branch[i++].leaf = false);
- //设置curNode
- curNode.position.x = curNode.position.y = curNode.position.z = 0;
- curNode.alpha = curNode.beta = 0;
- curNode.r = info->r;
- curNode.length = info->l;
- int treelength = info->tree.length();
- i = -1;
- while (i++<treelength)
- {
- switch(info->tree[i])
- {
- case 'F'://向前绘制树干或树枝
- nextNode.position.x =
- curNode.position.x +
- curNode.length*sin(curNode.alpha* PI /180)*cos(curNode.beta* PI /180);
- nextNode.position.z =
- curNode.position.z +
- curNode.length*sin(curNode.alpha* PI /180)*sin(curNode.beta* PI /180);
- nextNode.position.y =
- curNode.position.y +
- curNode.length*cos(curNode.alpha* PI /180);
- nextNode.alpha = curNode.alpha;//与y轴的夹角
- nextNode.beta = curNode.beta;//与x轴的夹角
- nextNode.r = curNode.r * info->rfade;//树枝半径的衰减率
- nextNode.length = curNode.length * info->lfade;//树枝长度的衰减率
- branch[bCount].begin = curNode;
- branch[bCount].end = nextNode;
- bCount++;
- curNode = nextNode;
- break ;
- case '[':
- stack[stackpushpos] = curNode ;//压入当前点的状态,此处是赋值,而不是存储节点指针
- curNode.r *= info->bfade;//分支半径的衰减
- stackpushpos ++;//当前压入栈中点的数目
- break;
- case ']':
- branch[bCount-1].leaf = true;//即到达树枝尽头,绘制叶子
- curNode = stack[stackpushpos-1]; //恢复上一点的状态
- stackpushpos -- ;
- break;
- case '+':
- curNode.alpha += info->minAlpha +
- rand()%(info->maxAlpha-info->minAlpha);//增加与y轴的夹角 40 , 50
- curNode.beta = 90+info->minBeta+
- rand()%(info->maxBeta-info->minBeta);//增加与x轴的夹角 0 , 350
- break;
- case '-':
- curNode.alpha -= info->minAlpha +
- rand()%(info->maxAlpha-info->minAlpha);//减少与y轴的夹角
- curNode.beta = 180+ info->minBeta+
- rand()%(info->maxBeta-info->minBeta);//减少与x轴的夹角
- break;
- default:
- ;
- }
- }
- branch[bCount-1].leaf = true;
- }
- for(int i=0;i<bCount;++i)
- ComputeBranchInfo(&branch[i]);
- }
- int Tree::RenderBranch(Branch *b)
- {
- glColor3f(1.0f,1.0f,0.0f);
- glBegin(GL_QUAD_STRIP);
- for(int i=0;i<=8;++i)
- {
- glTexCoord2f(0,i/8.0);
- glVertex3f(b->beginv[i].x,b->beginv[i].y,b->beginv[i].z);
- glTexCoord2f(1,i/8.0);
- glVertex3f(b->endv[i].x,b->endv[i].y,b->endv[i].z);
- }
- glEnd();
- return 16;
- }
- int Tree::RenderLeaves(Branch* b)
- {
- if(!b->leaf) return 0;
- glColor3f(1.0f,1.0f,1.0f);
- glBegin(GL_QUADS);
- glTexCoord2f(1,0);
- glVertex3f(b->pt[0].x,b->pt[0].y,b->pt[0].z);
- glTexCoord2f(1,1);
- glVertex3f(b->pt[1].x,b->pt[1].y,b->pt[1].z);
- glTexCoord2f(0,1);
- glVertex3f(b->pt[2].x,b->pt[2].y,b->pt[2].z);
- glTexCoord2f(0,0);
- glVertex3f(b->pt[3].x,b->pt[3].y,b->pt[3].z);
- glEnd();
- return 2;
- }
- int Tree::RenderTree()
- {
- if(bCount <= 0) return 0;
- int NumTrisRendered = 0;
- glPushMatrix();
- glTranslatef(center.x,center.y,center.z);
- glDisable(GL_BLEND);
- glAlphaFunc(GL_GREATER,0.0f);
- glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
- // glBlendFunc(GL_ONE_MINUS_DST_ALPHA,GL_DST_ALPHA);
- glDisable(GL_DEPTH_TEST);
- glEnable(GL_BLEND);
- glEnable(GL_ALPHA_TEST);
- // glEnable(GL_ALPHA_TEST);
- // glDisable(GL_SCISSOR_TEST);
- glBindTexture(GL_TEXTURE_2D, bmptexture[0]);
- for(int i=0; i<bCount; ++i)
- NumTrisRendered += RenderBranch(&branch[i]);
- glBindTexture(GL_TEXTURE_2D, bmptexture[3]); // Select The Mask Texture
- for(int i=0; i<bCount; ++i)
- NumTrisRendered += RenderLeaves(&branch[i]);// Done Drawing The Quad
- glEnable(GL_DEPTH_TEST);
- glDisable(GL_BLEND);
- glDisable(GL_ALPHA_TEST);
- glPopMatrix();
- return NumTrisRendered;
- }
- void Tree::CallRenderList()
- {
- glCallList(list);
- }
- void Tree::ComputeBranchInfo(Branch* b)
- {
- //计算模拟树干的八边形的顶点
- float sqrtbr = sqrt(2.0)*b->begin.r/2; //树枝起始半径开方
- float sqrter = sqrt(2.0)*b->end.r/2; //树枝终止半径开方
- Vertex bp = b->begin.position; //起始位置
- Vertex ep = b->end.position; //终止位置
- float br = b->begin.r; //起始节点半径
- float er = b->end.r; //终止节点半径
- //用八边形模拟圆形
- b->beginv[0].x = bp.x;
- b->beginv[0].z = bp.z + br;
- b->beginv[0].y = bp.y;
- b->beginv[1].x = bp.x + sqrtbr;
- b->beginv[1].z = bp.z + sqrtbr;
- b->beginv[1].y = bp.y;
- b->beginv[2].x = bp.x + br;
- b->beginv[2].z = bp.z;
- b->beginv[2].y = bp.y;
- b->beginv[3].x = bp.x + sqrtbr;
- b->beginv[3].z = bp.z - sqrtbr;
- b->beginv[3].y = bp.y;
- b->beginv[4].x = bp.x;
- b->beginv[4].z = bp.z - br;
- b->beginv[4].y = bp.y;
- b->beginv[5].x = bp.x - sqrtbr;
- b->beginv[5].z = bp.z - sqrtbr;
- b->beginv[5].y = bp.y;
- b->beginv[6].x = bp.x- br;
- b->beginv[6].z = bp.z;
- b->beginv[6].y = bp.y;
- b->beginv[7].x = bp.x - sqrtbr;
- b->beginv[7].z = bp.z + sqrtbr;
- b->beginv[7].y = bp.y;
- b->beginv[8].x = bp.x;
- b->beginv[8].z = bp.z + br;
- b->beginv[8].y = bp.y;
- b->endv[0].x = ep.x;
- b->endv[0].z = ep.z + er;
- b->endv[0].y = ep.y;
- b->endv[1].x = ep.x + sqrter;
- b->endv[1].z = ep.z + sqrter;
- b->endv[1].y = ep.y;
- b->endv[2].x = ep.x + er;
- b->endv[2].z = ep.z;
- b->endv[2].y = ep.y;
- b->endv[3].x = ep.x + sqrter;
- b->endv[3].z = ep.z - sqrter;
- b->endv[3].y = ep.y;
- b->endv[4].x = ep.x;
- b->endv[4].z = ep.z - er;
- b->endv[4].y = ep.y;
- b->endv[5].x = ep.x - sqrter;
- b->endv[5].z = ep.z - sqrter;
- b->endv[5].y = ep.y;
- b->endv[6].x = ep.x- er;
- b->endv[6].z = ep.z;
- b->endv[6].y = ep.y;
- b->endv[7].x = ep.x - sqrter;
- b->endv[7].z = ep.z + sqrter;
- b->endv[7].y = ep.y;
- b->endv[8].x = ep.x;
- b->endv[8].z = ep.z + er;
- b->endv[8].y = ep.y;
- //计算树叶所对应的四边形顶点
- if(!b->leaf) return ;
- float x=b->end.position.x;
- float y=b->end.position.y;
- float z=b->end.position.z;
- float size = info->sizeleaf;
- float sqrt2 = sqrt(2.0)/2;
- float sqrt2s = sqrt(2.0)*size;
- float salpha = sin(b->end.alpha*PI/180);
- float calpha = cos(b->end.alpha*PI/180);
- float sbeta = sin(b->end.beta*PI/180);
- float cbeta = cos(b->end.beta*PI/180);
- //四个顶点坐标
- b->pt[0].x = x;
- b->pt[0].y = y;
- b->pt[0].z = z;
- b->pt[2].x = x+sqrt2s*salpha*cbeta;
- b->pt[2].y = y+sqrt2s*calpha;
- b->pt[2].z = z+sqrt2s*salpha*sbeta;
- b->pt[1].x = x+sqrt2s*salpha*cos((b->end.beta-45)* PI /180)/2;//(cbeta*sqrt2+sbeta*sqrt2)/2;
- b->pt[1].y = y/2+b->pt[2].y/2;
- b->pt[1].z = z+sqrt2s*salpha*sin((b->end.beta-45)* PI /180)/2;//(sbeta*sqrt2-cbeta*sqrt2)/2;
- b->pt[3].x = x+sqrt2s*salpha*cos((b->end.beta+45)* PI /180)/2;//(cbeta*sqrt2-sbeta*sqrt2)/2;
- b->pt[3].y = b->pt[1].y;
- b->pt[3].z = z+sqrt2s*salpha*sin((b->end.beta+45)* PI /180)/2;//(sbeta*sqrt2+cbeta*sqrt2)/2;
- }