`
xiaozhouzhou
  • 浏览: 13357 次
  • 性别: Icon_minigender_1
社区版块
存档分类
最新评论

分形浅谈——科赫曲线和L-System

阅读更多
分形浅谈
开始接触到分行图时,感觉很难,无法下手,只能做出第一层或第二层,后续的就做不下去了。但是当你找出里面的规律之后就不一样了。分形,其本质可以说是迭代递归的一种运用。以下是我找出的一个分形制作的一个步骤:
一、观察分形图的结构,找出它的特点,也就是它的共同点,他可以有什么构成得到。
二、观察分形图的角度的变化。也就是说后面的一层是前面一层经过多少度的转角得到。
三、归纳出一个可行的递归方法体。
下面以科赫曲线来进行阐述。
我们先观察它的图形:

可以发现它是由下面这个简单的图形变化而来:

所以第一步先写出这个图形来。然后找出他接下来演变的规律。一般都是观察前后角度的变化规律。如下:

前后两个图形的变化可以看作是前面一个图形中间线段顺时针或逆时针旋转递归画图得到。接着,我们可以找出它的迭代递归的代码体:
public void draw(int x1,int y1,int x2,int y2,int deepth,Graphics g,double angle){
		if(deepth<=0){
			g.drawLine( x1,y1,x2,y2);
			
		}
		else{
		int x3=x1+(x2-x1)/3;
		int y3=y1+(y2-y1)/3;
		int x4=x1+2*(x2-x1)/3;
		int y4=y1+2*(y2-y1)/3;
		int l=(int) Math.sqrt((x4-x3)*(x4-x3)+(y4-y3)*(y4-y3));
		int x5=(int) (l*Math.cos(angle)+x3);
		int y5=(int) (y3- l*Math.sin(angle));
		draw(x1,y1,x3,y3,deepth-1, g,angle);
		draw(x3,y3,x5,y5,deepth-1,g,angle+Math.PI/3);
		draw(x4,y4,x5,y5,deepth-1, g,angle);
		draw(x4,y4,x2,y2,deepth-1, g,angle);

		}
		}
	}

这样就完成了对科赫曲线的大概制作过程。
下面给出完整的科赫曲线代码:
public class DrawKoch extends JFrame{
	double angle=Math.PI/3;
	Graphics g;
	public static void main(String args []){
		DrawKoch dk= new DrawKoch();
		dk.init();		
	}
	public void init(){
		setSize(800,800);
		setLayout(new FlowLayout());
		setDefaultCloseOperation(3);
		setVisible(true);
	}
	
	public void paint(Graphics g){
		super.paint(g);
		draw(20,600,600,600,5,g,Math.PI/3);
	}
	public void draw(int x1,int y1,int x2,int y2,int deepth,Graphics g,double angle){
		if(deepth<=0){
			g.drawLine( x1,y1,x2,y2);
			
		}
		else{
		int x3=x1+(x2-x1)/3;
		int y3=y1+(y2-y1)/3;
		int x4=x1+2*(x2-x1)/3;
		int y4=y1+2*(y2-y1)/3;
		int l=(int) Math.sqrt((x4-x3)*(x4-x3)+(y4-y3)*(y4-y3));
		int x5=(int) (l*Math.cos(angle)+x3);
		int y5=(int) (y3- l*Math.sin(angle));
		draw(x1,y1,x3,y3,deepth-1, g,angle);
		draw(x3,y3,x5,y5,deepth-1,g,angle+Math.PI/3);
		draw(x4,y4,x5,y5,deepth-1, g,angle);
		draw(x4,y4,x2,y2,deepth-1, g,angle);

		}
		}
	}

科赫曲线,已经完成,接下来就讲讲L-System的原理及写法。
L-System对于我们来说可能会觉得很陌生或是感觉做出这个很困难,但只要你找出他的规律以及F,+,-是如何定义和表示的就能迎刃而解了。
我用L-System原理来来描述上面的科赫曲线规律:
对于一个L-System来说,我们首先需要一个字符串。比如对于科赫曲线,就用字符串:F+F--F+F(其中定义"F"为画一条直线,定义"+","-"分别为逆时针旋60度,顺时针旋转60度。)来表示科赫曲线的一层,以F->F+F--F+F作为科赫曲线的演变规则,这样就可以简单的画出科赫曲线了。如果你改变F的演变规则,或是"+","-"的定义,可以得到意想不到的图形。
下面是一段关于F字符串的遍历递归:
public void production(){
                  //母串的获取
		str=jt1.getText();
                  //字串的获取
		str1=jt2.getText();
                  //递归层数的获取
		count=Integer.parseInt(jt5.getText());
		for(int j=0;j<count-1;j++){
			char[] ch=str.toCharArray();
			String str2="";
			for(int i=0;i<ch.length;i++){
				if(ch[i]=='F'){
					str2+=str1;
				}else {
					str2=str2+ch[i];
				}
			
			}
			str=str2;
		}
                  //画图方法的调用
		print(str,center.getWidth(),center.getHeight());
	} 
F字符串的定义:
for(int i=0;i<ch.length;i++){
                  //F的定义
		if(ch[i]=='F'){
			double x2=x1+len*x;
			double y2=y1+len*y;
			Line l=new Line(x1,y1,x2,y2);
			x1=x2;
			y1=y2;
			list.add(l);
				}
                           //-的定义
			if(ch[i]=='-'){
				double x_=x*Math.cos(rx)-y*Math.sin(rx);
				double y_=x*Math.sin(rx)+y*Math.cos(rx);
				x=x_;
				y=y_;
			}
                           //+的定义
			if(ch[i]=='+'){
				double x_=x*Math.cos(-ry)-y*Math.sin(-ry);
				double y_=x*Math.sin(-ry)+y*Math.cos(-ry);
				x=x_;
				y=y_;
			}
		}
		
	}  

这两段代码为主要代码,搞清楚思路之后就没问题了,不一定要照着这个方式写。
下面给出一些其他分形图:



  • 大小: 3.2 KB
  • 大小: 2.2 KB
  • 大小: 2.1 KB
  • 大小: 23.1 KB
  • 大小: 30.1 KB
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics