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

Netjava project 绘出最美丽的图案——分形

阅读更多

给我一个点,我能画出整个世界!这正是分形的魅力所在。
今天我们不说什么很枯燥的内容,我们先来看神奇的色子。
题目这样说:
1.平面上随机选A,B,C三个点。再随机选一个点,记为P。
2.有一个三面色子,每丢一次,则选中ABC三个中一点。
开始游戏:
1.重复丢色子,如果选中A,则取A和P的中点P1,画黑。
2.如果选中B,则取B和P1的中点P2,画黑。
3.如果选中A,则取A和P2的中点P3,画黑。
4.一直重复,如每点一下鼠标,丢100次色子。

这个游戏看似有点规律,但是当你画出图片时会发生非常奇妙的东西!



 

public class DrawDice extends JPanel {

	private Random r = new Random();// 创建随机数对象
	private int len = 5;// 设置点数为3
	private int x[] = new int[len];// 存x的数组
	private int y[] = new int[len];// 存y的数组
	private int tx = r.nextInt(600);// 随机获取第一个点的x坐标
	private int ty = r.nextInt(600);// 随机获取第一个点的y坐标

	public static void main(String[] args) {
		DrawDice dd = new DrawDice();
		dd.initUI();
	}

	public void initUI() {
		JFrame jf = new JFrame();// 创建窗体对象
		jf.setSize(new Dimension(600, 600));// 设置窗体大小
		jf.setDefaultCloseOperation(3);// 设置关闭按钮
		jf.setResizable(false);// 设置不可调节
		jf.setLocationRelativeTo(null);// 设置窗体局中
		jf.setVisible(true);// 设置窗体可见
		this.setBackground(Color.WHITE);// 设置背景颜色
		jf.add(this, BorderLayout.CENTER);// 将面板添加到窗体中部
		for (int i = 0; i < len; i++)// 随机获取坐标
		{
			x[i] = r.nextInt(600);
			y[i] = r.nextInt(600);
		}
	}

	/**
	 * 重写paint方法
	 */
	public void paint(Graphics g) {
		super.paint(g);// 调用父类方法
		drawpoint(g);// 重绘点
	}

	/**
	 * 画点的方法
	 * 
	 * @param g图形对象
	 */
	public void drawpoint(Graphics g) {
		int p = 100000;// 画10W个点
		while (p-- != 0) // 通过while进行循环
		{
			int t = r.nextInt(len);// 获取随机数
			g.drawLine((x[t] + tx) / 2, (y[t] + ty) / 2, (x[t] + tx) / 2,
					(y[t] + ty) / 2);// 连接画线
			tx = (x[t] + tx) / 2;// 得到新x坐标
			ty = (y[t] + ty) / 2;// 得到新y坐标
		}
	}
}

 

当我们选取5个点时,会发现更加奇妙的东西!



 

下面我们来介绍迭代实现分形。
所谓迭代,就是给你一个公式,然后反复把上一次的运算结果变成下一次自变量。
其实就是相当于一个数列,我们通过计算得到数据,然后将这些数据以点的形式画出来,
然后再通过放大移动将其移到屏幕中间,就可以画出非常美丽的图片啦~~

	/**
	 * 画第一个分形图形
	 * 
	 * @param g图像对象
	 */
	public void drawfractal1(Graphics g) {
		int large = 150;// 设置放大倍数
		int x0 = 350;// 设置初始x点
		int y0 = 330;// 设置初始y点
		double x = 0, y = 0, xt, yt;// 设置临时变量存储每一次计算出来的点
		double a = -2, b = -2, c = -1.2, d = 2;// 设置参数
		for (int i = 0; i < num; i++) // 循环画点
		{
			// g.setColor(new Color(0.1f, 0.2f, 0.3f,0.5f));
			g.setColor(Color.white);// 设置点为白色
			xt = (Math.sin(a * y) - Math.cos(b * x));// 计算下一个迭代点
			yt = (Math.sin(c * x) - Math.cos(d * y));// 计算下一个迭代点
			g.drawLine(x0 + (int) (large * xt), y0 + (int) (large * yt), x0
					+ (int) (large * xt), y0 + (int) (large * yt));// 画点
			x = xt;// 将新点存入
			y = yt;// 将新点存入
		}
	}

	/**
	 * 画第二个分形图形
	 * 
	 * @param g图像对象
	 */
	public void drawfractal2(Graphics g) {
		int large = 40;// 设置放大倍数
		int x0 = 350;// 设置初始x点
		int y0 = 300;// 设置初始y点
		double a = 1.40, b = 1.56, c = 1.40, d = -6.56;// 设置参数
		double x = 0, y = 0, xt, yt;// 设置临时变量存储每一次计算出来的点
		for (int i = 0; i < num; i++) // 循环画点
		{
			g.setColor(Color.white);// 设置点为白色
			xt = d * Math.sin(a * x) - Math.sin(b * y);// 计算下一个迭代点
			yt = c * Math.cos(a * x) + Math.cos(b * y);// 计算下一个迭代点
			g.drawLine(x0 + (int) (large * xt), y0 + (int) (large * yt), x0
					+ (int) (large * xt), y0 + (int) (large * yt));// 画点
			x = xt;// 将新点存入
			y = yt;// 将新点存入
		}
	}

	/**
	 * 画第三个分形图形
	 * 
	 * @param g图形对象
	 */
	public void drawfractal3(Graphics g) {
		int large = 75;// 设置放大倍数
		int x0 = 350;// 设置初始x点
		int y0 = 300;// 设置初始y点
		double a = 0.4, b = 1, c = 0;// 设置参数
		double x = 0, y = 0, xt, yt;// 设置临时变量存储每一次计算出来的点
		for (int i = 0; i < 10 * num; i++) // 循环画点
		{
			g.setColor(Color.blue);// 设置点为白色
			xt = y - Math.signum(x) * Math.sqrt(Math.abs(b * x - c));// 计算下一个迭代点
			yt = a - x;// 计算下一个迭代点
			g.drawLine(x0 + (int) (large * xt), y0 + (int) (large * yt), x0
					+ (int) (large * xt), y0 + (int) (large * yt));// 画点
			x = xt;// 将新点存入
			y = yt;// 将新点存入
		}
	}

	/**
	 * 画第四个分形图形
	 * 
	 * @param g图形对象
	 */
	public void drawfractal4(Graphics g) {
		double large = 1.5;// 设置放大倍数
		int x0 = 350;// 设置初始x点
		int y0 = 300;// 设置初始y点
		double a = 1, b = 4, c = 60;// 设置参数
		double x = 20, y = 20, xt, yt;// 设置临时变量存储每一次计算出来的点
		for (int i = 0; i < num; i++) // 循环画点
		{
			g.setColor(Color.white);// 设置点为白色
			xt = y - Math.signum(x) * Math.sqrt(Math.abs(b * x - c));// 计算下一个迭代点
			yt = a - x;// 计算下一个迭代点
			g.drawLine(x0 + (int) (large * xt), y0 + (int) (large * yt), x0
					+ (int) (large * xt), y0 + (int) (large * yt));// 画点
			x = xt;// 将新点存入
			y = yt;// 将新点存入
		}
	}

	private int num = 100000;

 

让我们来欣赏一下美丽的图片吧~



 

 

 

 

  • 大小: 45.5 KB
  • 大小: 84.9 KB
  • 大小: 181.6 KB
  • 大小: 87.8 KB
  • 大小: 62.9 KB
  • 大小: 133.6 KB
0
2
分享到:
评论
1 楼 zhangchunyu275 2013-08-07  
..学习了

相关推荐

Global site tag (gtag.js) - Google Analytics