`
felixour
  • 浏览: 31660 次
  • 性别: Icon_minigender_1
  • 来自: 湖南
社区版块
存档分类
最新评论

Netjava project 寻找自然界的规律——递归分形

阅读更多

上一次我们用了简单的直线和迭代法画点的形式画出了美丽的图形,但是自然界除了有其神奇的特性,更多地是有规律可寻的。
今天我们就要用递归来画出可以自己控制的图片!

 

我们先来介绍一下递归,所谓递归,就是自己的方法中还在调用自己的方法。但是实际上我们可以不用这样来考虑,我们就可以认为在方法中又调用了一个方法,
这个方法和自己的方法的用途一样,只是带入的参数不同。
在递归中我们要注意几点:
1、注意退出条件的控制,递归是个死循环,没有退出条件就会一直递归下去,直至栈溢出,然后报错。
2、递归时注意变量的传递和值的变化。
3、我们还要关注进入时的参数值变化和返回时返回值的变化。

 

首先我们来画一个递归画直线的:

	 /**
	 * 递归画直线的方法
	 * @param g图形对象
	 * @param x1第一个点横坐标
	 * @param y1第一个点纵坐标
	 * @param x2第二个点横坐标
	 * @param y2第二个点纵坐标
	 * @param count递归次数
	 */
	public void drawline(Graphics g, int x1, int y1, int x2, int y2, int count) {
		count--;
		//如果count等于0就返回
		if (count < 1) {
			return;
		}
		g.drawLine(x1, y1, x2, y2);//画线
		drawline(g, x1, y1 + 50, (int) (2.0 / 3 * x1 + 1.0 / 3 * x2), y2 + 50,
				count);//递归画左边直线
		drawline(g, x2, y2 + 50, (int) (2.0 / 3 * x2 + 1.0 / 3 * x1), y1 + 50,
				count);//递归画右边直线
	}

  

正方形:



 
 

	/**
	 * 画正方形的方法
	 * @param g图形对象
	 * @param x正方形中心横坐标
	 * @param y正方形中心纵坐标
	 * @param r正方形边长的一半
	 * @param count迭代次数
	 */
	public void drawsquare(Graphics g, int x, int y, int r, int count) {
		count--;
		//如果count为0,返回
		if (count < 1) {
			return;
		}
		g.fillRect(x - r, y - r, 2 * r, 2 * r);//画正方形
		//迭代画周围的8个小正方形
		drawsquare(g, x - (int) (r * 2.5), y - (int) (r * 2.5), r / 3, count);
		drawsquare(g, x, y - (int) (r * 2.5), r / 3, count);
		drawsquare(g, x + (int) (r * 2.5), y - (int) (r * 2.5), r / 3, count);
		drawsquare(g, x - (int) (r * 2.5), y, r / 3, count);
		drawsquare(g, x + (int) (r * 2.5), y, r / 3, count);
		drawsquare(g, x - (int) (r * 2.5), y + (int) (r * 2.5), r / 3, count);
		drawsquare(g, x, y + (int) (r * 2.5), r / 3, count);
		drawsquare(g, x + (int) (r * 2.5), y + (int) (r * 2.5), r / 3, count);
	}

 

三角形:



 

	/**
	 * 画三角形
	 * @param g图形对象
	 * @param x1上边的横坐标
	 * @param y1上边的纵坐标
	 * @param x2左边的横坐标
	 * @param y2左边的纵坐标
	 * @param x3右边的横坐标
	 * @param y3右边的纵坐标
	 * @param count画三角形的迭代次数
	 */
	public void drawtriangle(Graphics g, int x1, int y1, int x2, int y2,
			int x3, int y3, int count) {
		count--;//count减一
		if (count < 1)//如果count小于1,返回
		{
			return;
		}
		//画线
		g.drawLine(x1, y1, x2, y2);
		g.drawLine(x1, y1, x3, y3);
		g.drawLine(x3, y3, x2, y2);
		//画中间的线
		drawtriangle(g, (x1 + x2) / 2, (y1 + y2) / 2, x2, y2, (x2 + x3) / 2,
				(y2 + y3) / 2, count);
		drawtriangle(g, x1, y1, (x1 + x2) / 2, (y1 + y2) / 2, (x1 + x3) / 2,
				(y1 + y3) / 2, count);
		drawtriangle(g, (x1 + x3) / 2, (y1 + y3) / 2, x3, y3, (x2 + x3) / 2,
				(y2 + y3) / 2, count);
	}

 

Koch雪花:



 

 

	/**
	 * 画雪花的方法
	 * 
	 * @param g图形对象
	 * @param x1左边点的横坐标
	 * @param y1左边点的纵坐标
	 * @param x2右边点的横坐标
	 * @param y2右边点的纵坐标
	 * @param count画线的次数
	 */
	public void drawkoch(Graphics g, double x1, double y1, double x2,
			double y2, int count) {
		if (count <= 1) {
			g.drawLine((int) x1, (int) y1, (int) x2, (int) y2);// 画线
		} else {
			double x3 = (2 * x1 + x2) / 3;// 第一个三等份点的x坐标
			double y3 = (2 * y1 + y2) / 3;// 第一个三等份点的y坐标
			double x4 = (x1 + 2 * x2) / 3;// 第二个三等份点的x坐标
			double y4 = (y1 + 2 * y2) / 3;// 第二个三等份点的y坐标
			double k = (x1 - x2) * (y1 - y2);// 线的斜率
			double x5 = x1, y5 = y1;// 第一个三等份点的x坐标
			if (y3 == y4)// 直线
			{
				x5 = (x3 + x4) / 2;
				y5 = y3 - (x4 - x3) * Math.sqrt(3) / 2;
			} else if (k < 0)// 左斜线
			{
				x5 = x1;
				y5 = y4;
			} else if (k > 0)// 右斜线
			{
				x5 = x2;
				y5 = y3;
			}
			if (x3 == x4) // 如果斜线为竖线
			{
				x5 = x3;
				y5 = y3;
			}
			// 画尖端的左面那条线
			drawkoch(g, x3, y3, x5, y5, count - 1);
			// 画尖端的右面那条线
			drawkoch(g, x5, y5, x4, y4, count - 1);
			// 画左边那条直线
			drawkoch(g, x1, y1, x3, y3, count - 1);
			// 画右边那条直线
			drawkoch(g, x4, y4, x2, y2, count - 1);
		}
	}

 

 

  • 大小: 14.3 KB
  • 大小: 55.2 KB
  • 大小: 22.3 KB
  • 大小: 70.4 KB
1
1
分享到:
评论
2 楼 felixour 2013-08-14  
kingsfighter 写道
楼主的这一系列的东西很不错,有点数学模型的概念

你竟然能看出来我做数模?~
1 楼 kingsfighter 2013-08-12  
楼主的这一系列的东西很不错,有点数学模型的概念

相关推荐

Global site tag (gtag.js) - Google Analytics