Tree.cpp
上传用户:yunyi28
上传日期:2021-04-25
资源大小:6978k
文件大小:8k
源码类别:

分形几何

开发平台:

Visual C++

  1. #include "Tree.h"
  2. #include <math.h>
  3. #include <windows.h>
  4. #include <gl/gl.h>
  5. #include <time.h>
  6. #include "Data.h"
  7. #define  PI 3.14159
  8. Tree::Tree(void)
  9. {
  10. bCount = 0;
  11. }
  12. Tree::~Tree(void)
  13. {
  14. // if(branch) delete[] branch;
  15. }
  16. void Tree::InitTree(TreeInfo *i)
  17. {
  18. info = i;
  19. }
  20. void Tree::InitTreeInfo()
  21. {
  22. int i;
  23. string formtree;
  24. // srand(time(0));
  25. //info->base[]为字符串数组(生成规则集),numbase为规则个数此处随机选择初始图
  26. formtree  = info->base[rand() % info->numBase] ;
  27. info->tree.clear ();
  28. //////////////////////////////////////////////////////////////
  29. //循环depth次
  30. for ( i = 0 ; i < info->depth ; ++i)
  31. {
  32. int curlen = formtree.length();
  33. int j = 0 ;
  34. while (j < curlen)
  35. {
  36. /*扫描初始字符串(初始图),遇到'F'将在base中随机选择字符串(生成元)替代
  37. 遇到'['']''-''+'将有初始字符串替代*/
  38. if(formtree[j] == 'F')
  39. info->tree += info->base[rand()%info->numBase];
  40. else
  41. info->tree += formtree[j] ;
  42. ++j;
  43. }
  44.  
  45. formtree = info->tree ;//生成表达式
  46.  
  47. info->tree.clear ();
  48. }
  49. info->tree = formtree ;
  50. }
  51. void Tree::BuildTree()
  52. {
  53. //如果tree为空,返回
  54. if(info->tree.empty())
  55. return ;
  56. else 
  57. {
  58. TreeNode stack[STACK_SIZE];
  59. TreeNode curNode,nextNode;
  60. int stackpushpos = 0;
  61. int i;
  62. for(i=0;i<MAX_BRANCH;branch[i++].leaf = false);
  63. //设置curNode
  64. curNode.position.x = curNode.position.y = curNode.position.z = 0;
  65. curNode.alpha = curNode.beta = 0;
  66. curNode.r = info->r;
  67. curNode.length = info->l;
  68. int treelength = info->tree.length();
  69. i = -1;
  70. while (i++<treelength)
  71. {
  72. switch(info->tree[i])
  73. {
  74. case 'F'://向前绘制树干或树枝
  75. nextNode.position.x = 
  76. curNode.position.x + 
  77. curNode.length*sin(curNode.alpha* PI /180)*cos(curNode.beta* PI /180);
  78. nextNode.position.z = 
  79. curNode.position.z + 
  80. curNode.length*sin(curNode.alpha* PI /180)*sin(curNode.beta* PI /180);
  81. nextNode.position.y = 
  82. curNode.position.y + 
  83. curNode.length*cos(curNode.alpha* PI /180);
  84. nextNode.alpha = curNode.alpha;//与y轴的夹角
  85. nextNode.beta = curNode.beta;//与x轴的夹角
  86. nextNode.r = curNode.r * info->rfade;//树枝半径的衰减率
  87. nextNode.length = curNode.length * info->lfade;//树枝长度的衰减率
  88. branch[bCount].begin = curNode;
  89. branch[bCount].end  = nextNode;
  90. bCount++;
  91. curNode = nextNode;
  92. break ;
  93. case '[':
  94. stack[stackpushpos] = curNode ;//压入当前点的状态,此处是赋值,而不是存储节点指针
  95. curNode.r *= info->bfade;//分支半径的衰减
  96. stackpushpos ++;//当前压入栈中点的数目
  97. break;
  98. case ']':
  99. branch[bCount-1].leaf = true;//即到达树枝尽头,绘制叶子
  100. curNode = stack[stackpushpos-1]; //恢复上一点的状态
  101. stackpushpos -- ;
  102. break;
  103. case '+':
  104. curNode.alpha += info->minAlpha + 
  105. rand()%(info->maxAlpha-info->minAlpha);//增加与y轴的夹角 40 , 50 
  106. curNode.beta = 90+info->minBeta+ 
  107. rand()%(info->maxBeta-info->minBeta);//增加与x轴的夹角 0 , 350
  108. break;
  109. case '-':
  110. curNode.alpha -= info->minAlpha + 
  111. rand()%(info->maxAlpha-info->minAlpha);//减少与y轴的夹角
  112. curNode.beta = 180+ info->minBeta+ 
  113. rand()%(info->maxBeta-info->minBeta);//减少与x轴的夹角
  114. break;
  115. default:
  116. ;
  117. }
  118. }
  119. branch[bCount-1].leaf = true;
  120. }
  121. for(int i=0;i<bCount;++i)
  122. ComputeBranchInfo(&branch[i]);
  123. }
  124. int Tree::RenderBranch(Branch *b)
  125. {
  126. glColor3f(1.0f,1.0f,0.0f);
  127. glBegin(GL_QUAD_STRIP);
  128. for(int i=0;i<=8;++i)
  129. {
  130. glTexCoord2f(0,i/8.0);
  131. glVertex3f(b->beginv[i].x,b->beginv[i].y,b->beginv[i].z);
  132. glTexCoord2f(1,i/8.0);
  133. glVertex3f(b->endv[i].x,b->endv[i].y,b->endv[i].z);
  134. }
  135. glEnd();
  136. return 16;
  137. }
  138. int Tree::RenderLeaves(Branch* b)
  139. {
  140. if(!b->leaf) return 0;
  141. glColor3f(1.0f,1.0f,1.0f);
  142. glBegin(GL_QUADS);
  143. glTexCoord2f(1,0);
  144. glVertex3f(b->pt[0].x,b->pt[0].y,b->pt[0].z);
  145. glTexCoord2f(1,1);
  146. glVertex3f(b->pt[1].x,b->pt[1].y,b->pt[1].z);
  147. glTexCoord2f(0,1);
  148. glVertex3f(b->pt[2].x,b->pt[2].y,b->pt[2].z);
  149. glTexCoord2f(0,0);
  150. glVertex3f(b->pt[3].x,b->pt[3].y,b->pt[3].z);
  151. glEnd();
  152. return 2;
  153. }
  154. int Tree::RenderTree()
  155. {
  156. if(bCount <= 0) return 0;
  157. int NumTrisRendered = 0;
  158. glPushMatrix();
  159. glTranslatef(center.x,center.y,center.z);
  160. glDisable(GL_BLEND);
  161. glAlphaFunc(GL_GREATER,0.0f);
  162. glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
  163. // glBlendFunc(GL_ONE_MINUS_DST_ALPHA,GL_DST_ALPHA);
  164. glDisable(GL_DEPTH_TEST);
  165. glEnable(GL_BLEND);
  166. glEnable(GL_ALPHA_TEST);
  167. // glEnable(GL_ALPHA_TEST);
  168. // glDisable(GL_SCISSOR_TEST);
  169. glBindTexture(GL_TEXTURE_2D, bmptexture[0]);
  170. for(int i=0; i<bCount; ++i)
  171. NumTrisRendered += RenderBranch(&branch[i]);
  172. glBindTexture(GL_TEXTURE_2D, bmptexture[3]); // Select The Mask Texture
  173. for(int i=0; i<bCount; ++i)
  174. NumTrisRendered += RenderLeaves(&branch[i]);// Done Drawing The Quad
  175. glEnable(GL_DEPTH_TEST);
  176. glDisable(GL_BLEND); 
  177. glDisable(GL_ALPHA_TEST);
  178. glPopMatrix();
  179. return NumTrisRendered;
  180. }
  181. void Tree::CallRenderList()
  182. {
  183. glCallList(list);
  184. }
  185. void Tree::ComputeBranchInfo(Branch* b)
  186. {
  187. //计算模拟树干的八边形的顶点
  188. float sqrtbr = sqrt(2.0)*b->begin.r/2; //树枝起始半径开方
  189. float sqrter = sqrt(2.0)*b->end.r/2; //树枝终止半径开方
  190. Vertex bp = b->begin.position; //起始位置
  191. Vertex ep = b->end.position; //终止位置
  192. float br = b->begin.r; //起始节点半径
  193. float er = b->end.r; //终止节点半径
  194. //用八边形模拟圆形
  195. b->beginv[0].x = bp.x;
  196. b->beginv[0].z = bp.z + br;
  197. b->beginv[0].y = bp.y;
  198. b->beginv[1].x = bp.x + sqrtbr;
  199. b->beginv[1].z = bp.z + sqrtbr;
  200. b->beginv[1].y = bp.y;
  201. b->beginv[2].x = bp.x + br;
  202. b->beginv[2].z = bp.z;
  203. b->beginv[2].y = bp.y;
  204. b->beginv[3].x = bp.x + sqrtbr;
  205. b->beginv[3].z = bp.z - sqrtbr;
  206. b->beginv[3].y = bp.y;
  207. b->beginv[4].x = bp.x;
  208. b->beginv[4].z = bp.z - br;
  209. b->beginv[4].y = bp.y;
  210. b->beginv[5].x = bp.x - sqrtbr;
  211. b->beginv[5].z = bp.z - sqrtbr;
  212. b->beginv[5].y = bp.y;
  213. b->beginv[6].x = bp.x- br;
  214. b->beginv[6].z = bp.z;
  215. b->beginv[6].y = bp.y;
  216. b->beginv[7].x = bp.x - sqrtbr;
  217. b->beginv[7].z = bp.z + sqrtbr;
  218. b->beginv[7].y = bp.y;
  219. b->beginv[8].x = bp.x;
  220. b->beginv[8].z = bp.z + br;
  221. b->beginv[8].y = bp.y;
  222. b->endv[0].x = ep.x;
  223. b->endv[0].z = ep.z + er;
  224. b->endv[0].y = ep.y;
  225. b->endv[1].x = ep.x + sqrter;
  226. b->endv[1].z = ep.z + sqrter;
  227. b->endv[1].y = ep.y;
  228. b->endv[2].x = ep.x + er;
  229. b->endv[2].z = ep.z;
  230. b->endv[2].y = ep.y;
  231. b->endv[3].x = ep.x + sqrter;
  232. b->endv[3].z = ep.z - sqrter;
  233. b->endv[3].y = ep.y;
  234. b->endv[4].x = ep.x;
  235. b->endv[4].z = ep.z - er;
  236. b->endv[4].y = ep.y;
  237. b->endv[5].x = ep.x - sqrter;
  238. b->endv[5].z = ep.z - sqrter;
  239. b->endv[5].y = ep.y;
  240. b->endv[6].x = ep.x- er;
  241. b->endv[6].z = ep.z;
  242. b->endv[6].y = ep.y;
  243. b->endv[7].x = ep.x - sqrter;
  244. b->endv[7].z = ep.z + sqrter;
  245. b->endv[7].y = ep.y;
  246. b->endv[8].x = ep.x;
  247. b->endv[8].z = ep.z + er;
  248. b->endv[8].y = ep.y;
  249. //计算树叶所对应的四边形顶点
  250. if(!b->leaf) return ;
  251. float x=b->end.position.x;
  252. float y=b->end.position.y;
  253. float z=b->end.position.z;
  254. float size = info->sizeleaf;
  255. float sqrt2 = sqrt(2.0)/2;
  256. float sqrt2s = sqrt(2.0)*size;
  257. float salpha = sin(b->end.alpha*PI/180);
  258. float calpha = cos(b->end.alpha*PI/180);
  259. float sbeta = sin(b->end.beta*PI/180);
  260. float cbeta = cos(b->end.beta*PI/180);
  261. //四个顶点坐标
  262. b->pt[0].x = x;
  263. b->pt[0].y = y;
  264. b->pt[0].z = z;
  265. b->pt[2].x = x+sqrt2s*salpha*cbeta;
  266. b->pt[2].y = y+sqrt2s*calpha;
  267. b->pt[2].z = z+sqrt2s*salpha*sbeta;
  268. b->pt[1].x = x+sqrt2s*salpha*cos((b->end.beta-45)* PI /180)/2;//(cbeta*sqrt2+sbeta*sqrt2)/2;
  269. b->pt[1].y = y/2+b->pt[2].y/2;
  270. b->pt[1].z = z+sqrt2s*salpha*sin((b->end.beta-45)* PI /180)/2;//(sbeta*sqrt2-cbeta*sqrt2)/2;
  271. b->pt[3].x = x+sqrt2s*salpha*cos((b->end.beta+45)* PI /180)/2;//(cbeta*sqrt2-sbeta*sqrt2)/2;
  272. b->pt[3].y = b->pt[1].y;
  273. b->pt[3].z = z+sqrt2s*salpha*sin((b->end.beta+45)* PI /180)/2;//(sbeta*sqrt2+cbeta*sqrt2)/2;
  274. }