首页
会员中心
到顶部
到尾部
VC毕业设计

用LS文法编程实现分形图实验源码

时间:2020/10/13 21:16:48  作者:  来源:  查看:1  评论:0
内容摘要: 一、 实验目的1、 通过编程实现分形图 ,更深入的了解分形图和LS文法的思想2、 了解分形图的LS文法实现。 二、 实验环境说明开发工具:Microsoft Visual C++ 6.0用其中...
一、 实验目的
1、 通过编程实现分形图 ,更深入的了解分形图和LS文法的思想
2、 了解分形图的LS文法实现。
 
二、 实验环境说明
开发工具:Microsoft Visual C++ 6.0
用其中的MFC AppWizard(exe)-Single documents.
操作环境:Microsoft Windows XP SP1
三、 实现功能说明(包括操作说明)
点击菜单栏->“画图”,可以画特定的分形图包括:
1. 分形树(5种)
2. 手帕曲线(2种)
3. Sierpinski三角形
4. Peano曲线
5. Koch反雪花曲线
6. Koch雪花曲线
7. 柳条
8. 多规则分形树
9. “止”字曲线
10. 环形肠
点击菜单栏->“设置”,可以设置递归深度  看随着递归深度的增加,图形的变化。
点击菜单栏->“作者”,有作者信息。
四、 算法与数据结构(程序设计)
  主要数据结构(主要是一些变量和数组):
int i,j,k;/*辅助变量*/
double pi;/*圆周率*/
int seta;//偏转角
struct point//结点
{
double x;/*x坐标*/
double y;/*y坐标*/
double angle;/*前进角度*/
}point1,point2;
string tree,temptree,unit,unit1,unit2;/*实现ls的辅助字符串*/
int length;/*字符长度*/
int step,setstep;/*步长*/
int deep,setdeep,depth,/*递归深度*/message;/*表示画某种图*/
• 程序请参考源代码
Ls文法的主要思想是:
仿照语言学中的语法生成方法来构造图形的一种算法
递归生成语法
一个或者几个初始字母
一组生成规则
将生成规则反复作用到初始字母和新生成的字母上
Ls文法的实现分形图绘制的主要过程就是:
一类独特的迭代过程
核心概念是重写
公理
用字母表和符号串来表达生成对象的初始形式
一组产生式重写规则
将初始形式的每个字符依次替换成为新的字符形式
反复替换重写,生成终极图形
二维LS文法字母表的绘图规则如下:
 
F:以当前方向前进一步,并画线
f:以当前方向前进一步,不画线
+:逆时针旋转dº
-:顺时针旋转dº
[:将当前信息压栈
]:将“[”时刻的信息出栈
算法的设计主要包括三各部分:
1.初始化( 公理  规则 偏转角)
if(message==0){MemDC.TextOut(100,150,"因为有的图形递归深度过高不好看,被置为为小的",44);
               MemDC.TextOut(100,170,"有的图形步长太小不好看,所以被置为适当大小",42);}
else if(message==1)//分形树1
{
tree="F";
    unit="F[+F]F[-F][F]";
    seta=25;
     point1.x=300;point1.y=400;
     point1.angle=90;
}
else if(message==2)//分形树2
{
tree="F";
unit="F[+F]F[-F+F]";
     seta=30;
 step--;
     point1.x=300;point1.y=400;
     point1.angle=90;
}
else if(message==3)//分形树3
{
tree="F";
   unit="FF+[+F-F-F]-[-F+F+F]";
    seta=25;
if(step>3){step=3;}
     point1.x=300;point1.y=400;
     point1.angle=90;
}
else if(message==4)//分形树4
{
tree="F";
   unit="F[-F][+F]F";
    seta=25;
point1.x=300;point1.y=400;
     point1.angle=90;
}
else if(message==5)//分形树5
{
tree="F";
   unit="F[-F][+F][--F]F[++F]F";
    seta=25;
     point1.x=300;point1.y=400;
     point1.angle=90;
}
else if(message==6)//柳条
{
if(deep>3){deep=3;}
 tree="F";
 unit="F[+F]F[-F]+F";
     seta=20;
 step*=4;
 point1.x=100;point1.y=300;
     point1.angle=90;
  }
else if(message==7){//手帕曲线1
tree="F+F+F+F";
unit="FF[+F+F+F]F";
     seta=90;
 step=4;
     point1.x=100;point1.y=10;
     point1.angle=0;
}
else if(message==8){//手帕曲线2
tree="F+F+F+F";
unit="F[F]+F-F[++F]-F+F";
     seta=90;
 step=4;
     point1.x=30;point1.y=10;
     point1.angle=0;
}
else if(message==9){//“止”字曲线
if(deep>3){deep=3;}
tree="F+F+F+F";
unit="F+F-F-FFF+F+F-F";
     seta=90;
 step=3;
  point1.x=200;point1.y=200;
     point1.angle=0;
}
else if(message==10){//环形肠
if(deep>4){  deep=4;}
tree="F+F+F+F";
unit="FF-F-F-F-F-F+F";
     seta=90;
 step/=2;
      point1.x=300;point1.y=300;
     point1.angle=0;
}
else if(message==11)//koch雪花
{
tree="F++F++F";
unit="F-F++F-F";
     seta=60;
 step=1;
   point1.x=250;point1.y=150;
     point1.angle=0;
}
else if(message==12)//koch反雪花
{
tree="F++F++F";
unit="F+F--F+F";
     seta=60;
 step=1;
     point1.x=250;point1.y=150;
     point1.angle=0;
}
else if(message==13)//多规则分形树
{
  tree="X";
      unit="F-[[X]+X]+F[+FX]-X";
         seta=22.5;
     step*=3;
 point1.x=250;point1.y=350;
     point1.angle=90;
}
else if(message==14)//peano曲线
{
tree="X";
unit1="-YF+XFX+FY-";
    unit2="+XF-YFY-FX+";
     seta=90;
 step-=2;
     point1.x=250;point1.y=400;
     point1.angle=0;
}
else if(message==15){//Sierpinski垫片
      tree="L";
unit1="+R-L-R+";
    unit2="-L+R+L-";
     seta=60;
 step=3;
     point1.x=250;point1.y=400;
     point1.angle=60;
}
 length=tree.size();
2.替换
depth=deep;
while(depth--)
{
length=tree.size();
temptree=tree;
tree="";
j=0;
while(j<length)
{
if(temptree[j]=='X'&&message>12)
{
if(message==13)
  tree+=unit;
else
        tree+=unit1;
}
 else if(temptree[j]=='Y'&&message>12)
{
  tree+=unit2;
}
else if(temptree[j]=='F'&&message<13)
{
  tree+=unit;
}
else if(temptree[j]=='L')
{
  tree+=unit1;
}
else if(temptree[j]=='R')
{
  tree+=unit2;
}
else tree+=temptree[j];
j++;
}
}
length=tree.size();
3.画图
int i=0;
 MemDC.MoveTo(point1.x,point1.y);
    while(i<length)
{
switch(tree[i++])
{
case 'F':
          point1.angle=point1.angle;
      point1.x=point1.x+step*cos(point1.angle*pi/180);
  point1.y=point1.y-step*sin(point1.angle*pi/180);
          MemDC.LineTo(point1.x,point1.y);
  break;
case 'f':
          point1.angle=point1.angle;
      point1.x=point1.x+step*cos(point1.angle*pi/180);
  point1.y=point1.y-step*sin(point1.angle*pi/180);
          MemDC.MoveTo(point1.x,point1.y);
  break;
case '-':
          point1.angle=point1.angle+seta; 
          break;
case '+':
          point1.angle=point1.angle-seta;
              break;
    case '[':
              stack1.push(point1);
  break;
    case ']':
          point1=stack1.top();stack1.pop();
  MemDC.MoveTo(point1.x,point1.y);
          break;
case 'L':{
          point1.angle=point1.angle;
      point1.x=point1.x+step*cos(point1.angle*pi/180);
  point1.y=point1.y-step*sin(point1.angle*pi/180);
          MemDC.LineTo(point1.x,point1.y);
  break;}
case 'R':{
          point1.angle=point1.angle;
      point1.x=point1.x+step*cos(point1.angle*pi/180);
  point1.y=point1.y-step*sin(point1.angle*pi/180);
          MemDC.LineTo(point1.x,point1.y);
  break;}
case 'X':if(message==13){
          point1.angle=point1.angle;
      point1.x=point1.x+step*cos(point1.angle*pi/180);
  point1.y=point1.y-step*sin(point1.angle*pi/180);
          MemDC.LineTo(point1.x,point1.y);
  break;}
  }
    }
五、 部分实验截图  。
  通过点击菜单栏->“设置”,可以设置递归深度  看随着递归深度的增加,图形的变化。
     下面截取一部分实验效果图:
用LS文法编程实现分形图实验源码
柳条
用LS文法编程实现分形图实验源码
多规则生成树
用LS文法编程实现分形图实验源码
Peano曲线
用LS文法编程实现分形图实验源码
Sierpinski三角形垫片
六、实验小结
通过这个实验,我对ls文法有了更深的理解,体会到了分形图的魅力。用LS文法实现分形图比用递归实现更加有效率,更美观,程序的可读性也提高了很多,通过这次实验,觉得要有好的理论是很重要的。
  


相关评论
广告联系QQ:45157718 点击这里给我发消息 电话:13516821613 杭州余杭东港路118号雷恩国际科技创新园  网站技术支持:黄菊华互联网工作室 浙ICP备06056032号