`
剑晨java
  • 浏览: 23554 次
  • 性别: Icon_minigender_1
文章分类
社区版块
存档分类
最新评论

分形之科赫曲线

阅读更多
  真是不好意思,一直在补以前的内容,好像显得博客特别的乱,并且以后还会有几篇也是补写的博客。
  科赫曲线,我想讲当时我写的两个方法,当时也想了好久,其实究其原因还是自己的畏难情绪和缺乏耐心。
  科赫曲线就是通过递归来出其曲线,关键是找到规律。
  第一个方法,我只想给出源代码,因为这是我糊里糊涂写出来的,我也不知道从何说起。
/**
 * 科赫曲线
 * @author 剑晨
 *
 */
public class DrawKoch extends JFrame{
	double angle=Math.PI/3;//角度60
	Graphics g;//画布
	public static void main(String args []){//程序入口
		DrawKoch dk= new DrawKoch();
		dk.init();		
	}
	public void init(){
		setSize(800,800);
		setDefaultCloseOperation(3);
		setVisible(true);
	}
	
	public void paint(Graphics g){
		super.paint(g);
		draw(100,400,700,400,4,g,Math.PI/3);
	}
	/**
	 * 画曲线方法
	 * @param x1 y1 x2 y2坐标
	 * @param deepth 递归深度
	 * @param g 画布
	 * @param angle 角度
	 */
	public void draw(int x1,int y1,int x2,int y2,int deepth,Graphics g,double angle){
		if(deepth<=0){//递归深度为0时画线
			g.drawLine( x1,y1,x2,y2);
			
		}
		else{
			//第1个三分点的坐标
			int x3=x1+(x2-x1)/3;
			int y3=y1+(y2-y1)/3;
			//第2个三分点的坐标
			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) (x3+l*Math.cos(angle));
			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(x5,y5,x4,y4,deepth-1, g,angle-Math.PI/3);
			draw(x4,y4,x2,y2,deepth-1, g,angle);

			}
		}

	}
	
效果图如下:

  第二个方法,这是我讲一下我写的过程的方法。同样是递归,中间点的计算也是通过线长和角度计算。不过我事先并没有考虑别的,只是按照找到的规律递归,如下代码那样,并没考虑这样是否有角度的错误,只是先画出来再说,然后再不断改正。
/**
	 * 画科赫的方法
	 * @param x1 y1 x2 y2  坐标
	 * @param deepth 递归深度
	 */
	public void draw(double x1,double y1,double x2,double y2,int deepth){
		if(deepth<=1){//深度为1,画线
			g.drawLine((int)x1,(int)y1,(int)x2,(int)y2);
		}else{
			//第一个三分点
			double x3=x1+(x2-x1)/3;
			double y3=y1+(y2-y1)/3;
			//第二个三分点
			double x4=x1+2*(x2-x1)/3;
			double y4=y1+2*(y2-y1)/3;
			//顶点
			double l=Math.sqrt((x4-x3)*(x4-x3)+(y4-y3)*(y4-y3));
			double angle=Math.atan((y4-y3)/(x4-x3));
			double x5=x3+Math.cos(angle-Math.PI/3)*l;
			double y5=y3+Math.sin(angle-Math.PI/3)*l;
			//递归
			draw(x1,y1,x3,y3,deepth-1);
			draw(x3,y3,x5,y5,deepth-1);
			draw(x5,y5,x4,y4,deepth-1);
			draw(x4,y4,x2,y2,deepth-1);
		}
	}
果然,成功永远不可能那么简单。他出现了错误,如下图。

然后我就通过改变递归深度来观察出现错误点的规律,然后发现了规律,就加了一段代码。只是一句,却改变了结果。
/**
	 * 画科赫的方法
	 * @param x1 y1 x2 y2  坐标
	 * @param deepth 递归深度
	 */
	public void draw(double x1,double y1,double x2,double y2,int deepth){
		if(deepth<=1){//深度为1,画线
			g.drawLine((int)x1,(int)y1,(int)x2,(int)y2);
		}else{
			//第一个三分点
			double x3=x1+(x2-x1)/3;
			double y3=y1+(y2-y1)/3;
			//第二个三分点
			double x4=x1+2*(x2-x1)/3;
			double y4=y1+2*(y2-y1)/3;
			//顶点
			double l=Math.sqrt((x4-x3)*(x4-x3)+(y4-y3)*(y4-y3));
			double angle=Math.atan((y4-y3)/(x4-x3));
			//特别点的处理(新加的一句代码!!!!!!!!!!!!!!!!!!!!)
			if(x4<x3&&y4<=y3||x4<x3&&y4>=y3){
				angle=angle+Math.PI;
			}
			double x5=x3+Math.cos(angle-Math.PI/3)*l;
			double y5=y3+Math.sin(angle-Math.PI/3)*l;
			//递归
			draw(x1,y1,x3,y3,deepth-1);
			draw(x3,y3,x5,y5,deepth-1);
			draw(x5,y5,x4,y4,deepth-1);
			draw(x4,y4,x2,y2,deepth-1);
		}
	}
效果图如下。



 
  • 大小: 3.9 KB
  • 大小: 2.5 KB
  • 大小: 2.4 KB
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics