?? fgrass.cpp
字號:
// FGrass.cpp: implementation of the CFGrass class.
//
//////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "Grass.h"
#include "FGrass.h"
#include "Rand.h"
#include <math.h>
#include <time.h>
#define pi 3.1415926
#define xs(x) ((int)(m_fFact*((x)-m_fXmin)))
#define ys(y) ((int)(m_fFact*((y)-m_fYmin)))
#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
CFGrass::CFGrass()
{
m_nTurDir=m_nTsSize=0;
m_fTurx=m_fTury=0;
m_fD=1;
m_bFf=false;
m_nJ=0;
m_nF=0;
m_fYmax=m_fYmin=m_fXmax=m_fXmin=0;
m_pTsDir=m_pSize=NULL;
m_pTsx=m_pTsy=m_pAngle=NULL;
m_pKar=NULL;
m_pAxiom=NULL;
m_pRule=NULL;
m_pRand=NULL;
}
CFGrass::~CFGrass()
{
delete m_pTsDir;
delete m_pSize;
delete m_pTsx;
delete m_pTsy;
delete m_pAngle;
delete m_pRule;
delete m_pRand;
}
void CFGrass::TurState(CDC *pDC,char com)
{
if(m_bFf){
m_fD=float(m_pRand->next())+1;
}
if(com=='F'||com=='f'){
m_fTurx+=float(m_fD*cos(m_nTurDir*m_pAngle[m_nF]*pi/180.0));
m_fTury+=float(m_fD*sin(m_nTurDir*m_pAngle[m_nF]*pi/180.0));
if(com=='F') pDC->LineTo(xs(m_fTurx),ys(m_fTury));
else pDC->MoveTo(xs(m_fTurx),ys(m_fTury));
}
else if(com=='+') m_nTurDir--;
else if(com=='-') m_nTurDir++;
else if(com=='['){
m_pTsx[m_nTsSize]=m_fTurx;
m_pTsy[m_nTsSize]=m_fTury;
m_pTsDir[m_nTsSize]=m_nTurDir;
m_nTsSize++;
}
else if(com==']'){
m_nTsSize--;
m_fTurx=m_pTsx[m_nTsSize];
m_fTury=m_pTsy[m_nTsSize];
m_nTurDir=m_pTsDir[m_nTsSize];
pDC->MoveTo(xs(m_fTurx),ys(m_fTury));
}
}
int CFGrass::Turs(char com)
{
if(m_bFf){
m_fD=float(m_pRand->next())+1;
}
if(com=='F'||com=='f')
{
m_fTurx+=float(m_fD*cos(m_nTurDir*m_pAngle[m_nF]*pi/180.0));
m_fTury+=float(m_fD*sin(m_nTurDir*m_pAngle[m_nF]*pi/180.0));
m_fXmax=max(m_fTurx,m_fXmax);
m_fYmax=max(m_fTury,m_fYmax);
m_fXmin=min(m_fTurx,m_fXmin);
m_fYmin=min(m_fTury,m_fYmin);
}
else if(com=='+') m_nTurDir--;
else if(com=='-') m_nTurDir++;
else if(com=='['){
if(m_nTsSize>=m_nMaxTs)
{
return -1;
}
m_pTsx[m_nTsSize]=m_fTurx;
m_pTsy[m_nTsSize]=m_fTury;
m_pTsDir[m_nTsSize]=m_nTurDir;
m_nTsSize++;
}
else if(com==']'){
if(m_nTsSize==0){
return 1;
}
m_nTsSize--;
m_fTurx=m_pTsx[m_nTsSize];
m_fTury=m_pTsy[m_nTsSize];
m_nTurDir=m_pTsDir[m_nTsSize];
}
return 0;
}
void CFGrass::Draw(char *str,int level)
{
int i,j,k,m;
k=0;
m_nF=UINT(m_pRand->next())%14;
while(str[k]!='\0')
{
i=0;
while(i<m_nKLen && str[k]!=m_pKar[i]) i++;
if(str[k]==m_pKar[i]){
level++;
if(level>m_nMaxLevel){
level--;
m=m_pSize[m_nF];
for(j=0;j<m;j++)
TurState(pDC,m_pRule[m_nF][j]);
goto loop;
}
Draw(m_pRule[m_nF],level);
}else{
TurState(pDC,str[k]);
goto loop;
}
level--;
loop: k++;
}
}
int CFGrass::Play(char *str,int level)
{
int i,j,k,m;
k=0;
m_nF=UINT(m_pRand->next())%14;
while(str[k]!='\0')
{
i=0;
while(i<m_nKLen && str[k]!=m_pKar[i]) i++;
if(str[k]==m_pKar[i]){
level++;
if(level>m_nMaxLevel){
level--;
m=m_pSize[m_nF];
for(j=0;j<m;j++){
if(Turs(m_pRule[m_nF][j])!=0)
return 0;
}
goto loop;
}
if(Play(m_pRule[m_nF],level)==0)
return 0;
}else{
if(Turs(str[k])!=0)
return 0;
goto loop;
}
level--;
loop: k++;
}
return 1;
}
int CFGrass::Create(int maxts,int maxlevel,int mx,int my)
{
m_nMaxTs=maxts;
m_nMaxLevel=maxlevel;
m_nMaxx=mx;
m_nMaxy=my;
m_pTsDir=new int[m_nMaxTs];
m_pTsx=new float[m_nMaxTs];
m_pTsy=new float[m_nMaxTs];
m_nKLen=1;
m_pKar="F";
m_pAxiom="+++++F";
m_nRLen=14;
m_pSize=new int[m_nRLen];
m_pAngle=new float[m_nRLen];
m_pRule=new char*[m_nRLen];
m_pAngle[0]=22.5;
m_pRule[0]="FF-[-F+F+F]+[+F-F-F]";
m_pSize[0]=strlen(m_pRule[0]);
m_pAngle[1]=11.25;
m_pRule[1]="FF-[F-[F-[F]+]+]+";
m_pSize[1]=strlen(m_pRule[1]);
m_pAngle[2]=22.5;
m_pRule[2]="FF[+F][-F]FFF[-FF]";
m_pSize[2]=strlen(m_pRule[2]);
m_pAngle[3]=22.5;
m_pRule[3]="F[+F][--FF]FF[+FF][-F]FF[+FF][-F]";
m_pSize[3]=strlen(m_pRule[3]);
m_pAngle[4]=30;
m_pRule[4]="F[+F]F[-F]F";
m_pSize[4]=strlen(m_pRule[4]);
m_pAngle[5]=20;
m_pRule[5]="F[+F]F[-F][F]";
m_pSize[5]=strlen(m_pRule[5]);
m_pAngle[6]=180.0/12.0;
m_pRule[6]="FF-[FF-[-[F]+]+]+";
m_pSize[6]=strlen(m_pRule[0]);
m_pAngle[7]=180.0/16.0;
m_pRule[7]="F-[F]+F-[-[F-[-[F]+]+F-[-[F]+]+]+]+";
m_pSize[7]=strlen(m_pRule[7]);
m_pAngle[8]=180.0/16.0;
m_pRule[8]="FF-[F-[-[F-[F-[-[F]+]+]+]+]+]+";
m_pSize[8]=strlen(m_pRule[8]);
m_pAngle[9]=180.0/8.0;
m_pRule[9]="FF[+F[+F-]-[F]]-[F-[F[+F-]]+]+";
m_pSize[9]=strlen(m_pRule[9]);
m_pAngle[10]=180.0/16.0;
m_pRule[10]="FF-[F-[-[F-[F-[-[F]+]+]+]+]+]+[+[+[+F[+F[+[+F-]-]-]-]-]-]";
m_pSize[10]=strlen(m_pRule[10]);
m_pAngle[11]=18;
m_pRule[11]="F[+[+FF-]-]-[-[FF]+]+F-[[+[+FF-]-]-[-[F]+]+F-[[+[+F-]-]-[-[F]+]+F]+]+";
m_pSize[11]=strlen(m_pRule[11]);
m_pAngle[12]=180.0/8.0;
m_pRule[12]="FF-[F[+F-]F]+[+FF-[F]+F+]";
m_pSize[12]=strlen(m_pRule[12]);
m_pAngle[13]=180.0f/7.0f;
m_pRule[13]="F[+F]F[-F]F";
m_pSize[13]=strlen(m_pRule[13]);
m_pRand=new CRandGauss(1,5);
// m_pRand=new CRandUniform(0,100);
return 1;
}
int CFGrass::ClacFact(int l)
{
m_nTurDir=m_nTsSize=0;
m_fTurx=m_fTury=0;
m_fYmax=m_fYmin=m_fXmax=m_fXmin=0;
if(Play(m_pAxiom,l)==0) return 0;
m_fFact=float(min((m_nMaxx/(m_nJ+1.0)-1.0)/(m_fXmax-m_fXmin),(m_nMaxy-1.0)/(m_fYmax-m_fYmin)));
m_nTurDir=m_nTsSize=0;
m_fTurx=m_fTury=0;
return 1;
}
int CFGrass::Draw(CDC *ipDC,char c)
{
int k;
switch(c){
case '1':
m_nJ=1;
m_bFf=true;
break;
case '2':
m_nJ=0;
m_bFf=true;
break;
case '3':
m_nJ=1;
m_bFf=false;
break;
case '4':
m_nJ=1;
m_bFf=false;
break;
default:
m_nJ=0;
m_bFf=false;
}
pDC=ipDC;
m_pRand->setCurSeed((unsigned)time( NULL ));
// srand( (unsigned)time( NULL ) );
k=int(m_pRand->next());//rand();
m_pRand->setCurSeed(k);
// srand(k);
if(ClacFact(1)==0) return 0;
pDC->MoveTo(xs(m_fTurx),ys(m_fTury));
m_pRand->setCurSeed(k);
// srand(k);
Draw(m_pAxiom,1);
if(m_nJ){
if(c!='4')
k=int(m_pRand->next());//k=rand();
else m_bFf=true;
if(ClacFact(1)==0) return 0;
m_fXmin=m_fXmin-m_nMaxx*1.0f/2.0f/m_fFact;
pDC->MoveTo(xs(m_fTurx),ys(m_fTury));
m_pRand->setCurSeed(k);
// srand(k);
Draw(m_pAxiom,1);
}
return 1;
}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -