⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 tree.cpp

📁 关于分形L系统的应用
💻 CPP
字号:
// Tree.cpp: implementation of the Tree class.
//
//////////////////////////////////////////////////////////////////////

#include "stdafx.h"
#include "fxs.h"
#include "Tree.h"
#include "Set.h"

#include <stack>
//using   namespace   std;

#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif

//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////

Tree::Tree()
{
	m_count = 2;
	m_suofang = 1;
	m_yd = 0;
	m_fenjiao = 6;//分支倾斜度.调试完要改成6°
	m_suanfa = 0;
//	m_lastl = l*pow(m_jiedian,m_count-1);
	m_LStr = "F";
	m_rule = "F[+F][++F][-F]F[--F]F";
	m_bili = 1.0/3;//分支比例
	m_jiedian = 1.0/3;//节点比例; 
	m_l=l; //初始主干长.调试完要改成符合要求
	m_qingxie=90*DU; //主干倾斜度

}

Tree::~Tree()
{

}

void Tree::Draw (CPaintDC* pdc,int px,int py)
{
	py -= m_yd;
	m_l = l * m_suofang;
	if(m_suanfa==0){
	NoLSdraw(pdc,px,py,m_qingxie,m_l,m_count);//开始普通迭代
	} 
	else 
	{
		//单一LS文法
		///******************************************
		//避免多余的重复生成LS字符串和重复计算最后长度
		if(m_lsuofang != m_suofang || m_lc != m_count){
			m_lastl=m_l*pow(m_jiedian,m_count);
		
		}
		if(m_lrule != m_rule || m_lc != m_count){
			CString str =  "F";
			LSToStr(str,m_count);
		}
		m_lc = m_count;
		m_lsuofang = m_suofang;
		m_lrule = m_rule;
		LSdraw(pdc,m_LStr,px,py,m_qingxie,m_lastl);
		///******************************************
	}
}
///******************************************
//普通迭代
void Tree::NoLSdraw(CPaintDC* pdc,int px,int py,double qingxie,double l,int count) 
{   
    
 	int x=px+l*cos(qingxie);//终点
	int y=py-l*sin(qingxie);
	DrawLine(pdc,px,py,x,y);
	if(count--<=0)
		 return;
	int x1=px+l*cos(qingxie)*m_jiedian;//第1个分叉点
	int y1=py-l*sin(qingxie)*m_jiedian;
	int x2=px+l*cos(qingxie)*2*m_jiedian;//第2个分叉点
	int y2=py-l*sin(qingxie)*2*m_jiedian;
	NoLSdraw(pdc,x1,y1,qingxie+m_fenjiao*DU,l*m_bili,count);
	NoLSdraw(pdc,x1,y1,qingxie+2*m_fenjiao*DU,l*m_bili,count);	   
	NoLSdraw(pdc,x1,y1,qingxie-m_fenjiao*DU,l*m_bili,count);
	NoLSdraw(pdc,x2,y2,qingxie-2*m_fenjiao*DU,l*m_bili,count);	
	   
  
}



///******************************************
//单一LS文法
void Tree::LSdraw(CPaintDC* pdc,CString lstr,int px,int py,double qingxie,double l)
{
	
	 /*vector<int> i;
	 i.push_back();*/
	std::stack<int> sx,sy;
	std::stack<double> alpha;
	int count = 0;
	pdc->TextOut(0,50,"所用LS规则:"+m_rule);

	int x,y;
    for(int i=0;i<lstr.GetLength();i++)
	{

		switch (lstr.GetAt(i)) {
			case 'F':
				x=px+l*cos(qingxie)*pow(m_bili/m_jiedian,count);//新终点
				y=py-l*sin(qingxie)*pow(m_bili/m_jiedian,count);
				DrawLine(pdc,px,py,x,y);
				px = x;
				py = y;
				break;
			case '+':
				qingxie += m_fenjiao*DU;
				break;
			case '-':
				qingxie -= m_fenjiao*DU;
				break;
			case '[':
				sx.push(px);
				sy.push(py);
				alpha.push(qingxie);
				count++;
				break;
			case ']':
				px = sx.top();
				sx.pop();
				py = sy.top();
				sy.pop();
				qingxie = alpha.top();
				alpha.pop();
				count--;
				break;
			default:
				break;
		}
	}
 }

 void Tree::LSToStr(CString lstr,int count)
 {

	 if(--count < 0) {
		m_LStr = lstr;
		 return;
	 }
	 CString strtmp;
	 for(int i=0;i<lstr.GetLength();i++)
	 {		 
		 switch (lstr.GetAt(i)) {
		 case 'F':
			 strtmp += m_rule;
			 break;
		 case '+':
			 strtmp += '+';
			 break;
		 case '-':
			 strtmp += '-';
			 break;
		 case '[':
			 strtmp += '[';
			 break;
		 case ']':
			 strtmp += ']';
			 break;
		 default:
			 break;
		 }
	 }
	 LSToStr(strtmp,count);
 }

void Tree::DrawLine(CPaintDC* pdc,int px,int py,int x,int y)
{

	pdc->MoveTo(px,py); //画线
	pdc->LineTo(x,y);
}

void Tree::Set()
{
	CSet set;
	set.Set(m_suanfa,m_fenjiao,m_yd,m_suofang,m_count,m_bili,m_rule);
	if(IDOK==set.DoModal())
	{
		m_count = set.m_count;
		m_fenjiao =	set.m_fenjiao;
		m_suofang = set.m_suofang;
		m_yd = set.m_yd;
		m_suanfa = set.m_suanfa;
		m_bili = set.m_bili;
		m_rule = set.m_rule;
		AfxGetMainWnd()->Invalidate();		
	}

		
}

void Tree::ZoneOut()
{
	m_suofang *= 1.5;
}

void Tree::ZoneIn()
{
	m_suofang /= 1.5;
}

void Tree::Up()
{
	m_yd -= 100;
}

void Tree::Down()
{
	m_yd += 100;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -