首页 > 开发 > Java > 正文

Java Chaos Game噪声游戏实例代码

2024-07-13 10:15:08
字体:
来源:转载
供稿:网友

[简介]

最近一直在读《深奥的简洁》,里面有一章介绍了几种使用噪声产生分形图的方法,感觉很有意思,于是尝试使用计算机模拟了一下,效果还不错(噪声法比传统迭代法在编程上好实现一些,后来发现这类算法还不少,搜索chaosgame可以找到更多)。

[Sierpinski三角形的噪声产生法]

chaos,game,java,噪声游戏

在这些噪声游戏中,Sierpinski(谢尔宾斯基)三角形的生成规则可谓是最简单的:

1.在平面上选取三个点,标记为1、2、3,作为大三角形的顶点。

2.选择其中一点,作为“当前点”(比如选择1号)。

3.产生1~3的随机数,在该数表达的顶点与“当前点”的中点绘制一个新点,并将新点作为“当前点”。

4.重复步骤3,即可逼近图案。

*.注意随机数最好不要使用以时间作为种子的产生方式。

[模拟程序]

package com.geiv.chaos;import java.awt.event.KeyEvent;import com.thrblock.util.RandomSet;import geivcore.DefaultFactor;import geivcore.KeyFactor;import geivcore.KeyListener;import geivcore.R;import geivcore.UESI;import geivcore.enginedata.obj.Obj;public class Sierpinski extends DefaultFactor implements KeyListener{	UESI UES;	Obj[] basePoint;	Obj crtPoint;	public Sierpinski(UESI UES,int times){		this.UES = UES;		basePoint = new Obj[3];		//创建三个基准点 		for (int i = 0;i < 3;i++){			basePoint[i] = UES.creatObj(UESI.BGIndex);			basePoint[i].addGLPoint("70DBDB",0,0);			basePoint[i].show();		}		basePoint[0].setCentralX(400);		//设置三点位置 		basePoint[0].setCentralY(60);		basePoint[1].setCentralX(60);		basePoint[1].setCentralY(550);		basePoint[2].setCentralX(740);		basePoint[2].setCentralY(550);		crtPoint = basePoint[0];		//将0号点作为当前点 		this.setKeyListener(this);		UES.pushKeyBoardIO(this);		for (int i = 0;i < times;i++){			generateNew();		}	}	@Override 	  public void doKeyBord(KeyFactor whom, int keyCode, Boolean ispressed) {		//挂载回调 		if(ispressed){			if(keyCode == KeyEvent.VK_SPACE){				//空格对应创建一个新点 				generateNew();			} else if(keyCode == KeyEvent.VK_A){				//A对应创建100个新点 				for (int i = 0;i < 100;i++){					generateNew();				}			} else if(keyCode == KeyEvent.VK_B){				//B对应创建1000个新点 				for (int i = 0;i < 1000;i++){					generateNew();				}			}		}	}	public void generateNew(){		Obj flagPoint = basePoint[RandomSet.getRandomNum(0, 2)];		//随机选择基准点之一 		float nx = (flagPoint.getCentralX() + crtPoint.getCentralX())/2f;		//计算中点 		float ny = (flagPoint.getCentralY() + crtPoint.getCentralY())/2f;		Obj newPoint = UES.creatObj(UESI.BGIndex);		//创建新点 		newPoint.addGLPoint("70DBDB",0,0);		newPoint.setColor(RandomSet.getRandomColdColor());		newPoint.setCentralX(nx);		//设置坐标 		newPoint.setCentralY(ny);		newPoint.show();		crtPoint = newPoint;		//置为当前点	}	public static void main(String[] args) {		UESI ues = new R();		new Sierpinski(ues,0);		//后面的构造参数可以设置初始点数。	}}

[模拟结果]

在B键按下时

chaos,game,java,噪声游戏

chaos,game,java,噪声游戏

chaos,game,java,噪声游戏

[Barnsleyfern的噪声产生法]

chaos,game,java,噪声游戏

相比于Sierpinski三角的简单规则性,Barnsleyfern(分形羊齿草)给人以更加复杂的印象,出于它的复杂性,混沌学科经常拿出它来证明“简单规则也可产生复杂对象”的结论。

它的产生规则也不是很复杂:

1.首先给定”当前点”(0,0),我们用ox,oy表示横纵坐标。

2.计算下一点(nx,ny)需要以一定随机规则选择下列四种迭代公式之一:

1)以%1的概率选择此迭代公式:

nx=0;

ny=0.16f*oy;

2)以%85的概率选择此迭代公式:

nx=0.85*ox+0.04*oy;

ny=-0.04*ox+0.85*oy+1.6;

3)以%7的概率选择此迭代公式:

nx=0.2*ox-0.26*oy;

ny=0.23*ox+0.22*oy+1.6;

4)以%7的概率选择此迭代公式:

nx=-0.15*ox+0.28*oy;

ny=0.26*ox+0.24*oy+0.44;

3.绘制(nx,ny),并将其设为当前点,重复2,即可无限逼近结果。

↑以上公式摘自Wiki:http://en.wikipedia.org/wiki/Barnsley_fern。在编程时,我发现一个问题,Wiki并未指明这个坐标的决对值与屏幕大小的关系,也并未说明x、y轴的方向,在我自己定义的坐标系下绘制总是不成功,后来我按照公式搜索,找到了这个面:http://people.sc.fsu.edu/~jburkardt/cpp_src/fern_opengl/fern.cpp。这是一个C++下的OPENGL程序,而里面用了与Wiki相同的公式,也就是说,这组公式是以Opengl的坐标系为基准的,在做了对应变换后终于成功绘制。

[模拟程序]

package com.geiv.chaos;import geivcore.DefaultFactor;import geivcore.KeyFactor;import geivcore.KeyListener;import geivcore.R;import geivcore.UESI;import geivcore.enginedata.obj.Obj;import java.awt.Color;import java.awt.event.KeyEvent;import com.thrblock.util.RandomSet;public class Barnsleyfern extends DefaultFactor implements KeyListener{	UESI UES;	Obj crtPoint;	public Barnsleyfern(UESI UES,int times){		this.UES = UES;		crtPoint = UES.creatObj(UESI.BGIndex);		crtPoint.addGLPoint("70DBDB",0,0);		crtPoint.show();		crtPoint.setCentralX(0);		crtPoint.setCentralY(0);		UES.setViewOffsetX(90);		this.setKeyListener(this);		UES.pushKeyBoardIO(this);		for (int i = 0;i < times;i++){			generateNew();		}	}	@Override 	  public void doKeyBord(KeyFactor whom, int keyCode, Boolean ispressed) {		//键盘IO的方式同上例 		if(ispressed){			if(keyCode == KeyEvent.VK_SPACE){				generateNew();			} else if(keyCode == KeyEvent.VK_A){				for (int i = 0;i < 100;i++){					generateNew();				}			} else if(keyCode == KeyEvent.VK_B){				for (int i = 0;i < 1000;i++){					generateNew();				}			}		}	}	public void generateNew(){		float nx,ny;		float ox = crtPoint.getCentralX()/150f,oy = (600 - crtPoint.getCentralY())/60f;		//这里做了OPENGL坐标转换,在设置新点位置时对应反转。 		double code = 100.0 * RandomSet.getRandomFloatIn_1();		//随机浮点数数0~100 		if(code >= 0&&code <= 1){			nx = 0;			ny = 0.00f * ox + 0.16f * oy;		} else if(code > 1&& code <= 86){			nx = 0.85f*ox + 0.04f*oy;			ny = -0.04f*ox + 0.85f*oy + 1.6f;		} else if(code > 86&& code <= 93){			nx = 0.2f*ox - 0.26f*oy;			ny = 0.23f*ox + 0.22f*oy + 1.6f;		} else{			nx = -0.15f*ox + 0.28f*oy;			ny = 0.26f*ox + 0.24f*oy + 0.44f;		}		Obj newPoint = UES.creatObj(UESI.BGIndex);		newPoint.addGLPoint("70DBDB",0,0);		newPoint.setColor(Color.GREEN);		newPoint.setCentralX(nx*150f);		//将之前的坐标变换抵消 		newPoint.setCentralY(600 - ny*60f);		newPoint.show();		crtPoint = newPoint;		//设置新点为当前点。	}	public static void main(String[] args) {		UESI ues = new R();		new Barnsleyfern(ues,0);	}}

[模拟结果]

chaos,game,java,噪声游戏

chaos,game,java,噪声游戏

chaos,game,java,噪声游戏

总结

以上就是本文关于Java Chaos Game噪声游戏实例代码的全部内容,希望对大家有所帮助。感兴趣的朋友可以继续参阅本站其他相关专题,如有不足之处,欢迎留言指出。感谢朋友们对本站的支持!


注:相关教程知识阅读请移步到JAVA教程频道。
发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表