分形画板

本文介绍了分形的概念,强调其自相似和迭代生成的特性,并探讨了分形在现实世界的美学应用。通过代码实现分形,揭示了如何使用迭代函数绘制美丽的分形图像,如IFS树。分形的美妙之处在于它能用简单的数学原理模拟复杂自然景象,为电脑艺术创作提供了无限可能。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

分形是什么

分形之美

如何实现分形

分形举例

分形是什么

部分与整体以某种方式相似的形体称为分形。分形最基本特点是用分数维度的视角和数学方法描述和研究客观事物,也就是用分形分维的数学工具来描述研究客观事物。它跳出了一维的线、二维的面、三维的立体乃至四维时空的传统藩篱,更加趋近复杂系统的真实属性与状态的描述,更加符合客观事物的多样性与复杂性。

分形有两个重要的原则:即自相似原则和迭代生成原则。其表征分形在通常的几何变换下具有不变性,即标度无关性。由于自相似性是从不同尺度的对称出发,也就意味着递归。分形形体中的自相似性可以是完全相同,也可以是统计意义上的相似。
在这里插入图片描述

分形之美

我们现实生活当中很多事物具有不规则性,但是仔细联系一下,却发现它们却有着共同的规律,它们都与分形几何有关,因此分形理论的数学基础就是分形几何,掌握了分形几何我们就可以成为电脑艺术家,利用电脑画出漂亮的艺术图,画出现实生活中的任何事物。
分形其实是一种艺术,根据迭代分形可以画出许多美的图片,比如说谢宾斯基三角形,地毯海绵等等。
在这里插入图片描述
用代码就可以画出以上如此美丽的图片:

public void coordinateCar(double x, double y, double width, double height,int con) {
		if (con < 1) {
			return;
		}
		this.x = (int) x;
		this.y = (int) y;
		this.width = (int) width;
		this.height = (int) height;
		g.setColor(new Color(con*10%255,con*40%255,con*20%255));
		g.fillRect(this.x, this.y, this.width, this.height);
//这里计算下次传入的参数值 ,这个可以另写一个方法
		double x1 = x - width * 2 / 3;
		double y1 = y - height * 2 / 3;
		double width1 = width / 3;
		double height1 = height / 3;
		double x2 = x + width / 3;
		double y2 = y - height * 2 / 3;
		double x3 = x + width * 4 / 3;
		double y3 = y - height * 2 / 3;

		double x4 = x + width * 4 / 3;
		double y4 = y + height / 3;
		double x5 = x + width * 4 / 3;
		double y5 = y + height * 4 / 3;
		double x6 = x + width / 3;
		double y6 = y + height * 4 / 3;
		double x7 = x - width * 2 / 3;
		double y7 = y + height * 4 / 3;
		double x8 = x - width * 2 / 3;
		double y8 = y + height / 3;
		con--;
//调用这个方法 超过了一次, 那么传入的参数一定不能是,this.x等等
		coordinateCar(x1, y1, width1, height1, con);
		coordinateCar(x2, y2, width1, height1, con);
		coordinateCar(x3, y3, width1, height1, con);
		coordinateCar(x4, y4, width1, height1, con);
		coordinateCar(x5, y5, width1, height1, con);
		coordinateCar(x6, y6, width1, height1, con);
		coordinateCar(x7, y7, width1, height1, con);
		coordinateCar(x8, y8, width1, height1, con

如何实现分形

实现分形肯定得需要一个画板,因此我们首先就应该写出一个画板界面,然后加入按钮,事件监听器等等。

public void showUI(){
		JFrame jfr = new JFrame();                 //创建一个界面对象
		jfr.setSize(1000, 1000);                       //设置界面大小
		jfr.setTitle("分形画板");                        //设置界面名称
		jfr.setLocationRelativeTo(null);          
		jfr.setDefaultCloseOperation(3);
		jfr.setLayout(new FlowLayout());            //设置流式布局
		DrawListener drawl = new DrawListener();       //定义一个事件监听器
		ImageIcon icon =new ImageIcon("C://Users/23521/Desktop/1.jpg");   
		JLabel jla = new JLabel(icon);
		
		JButton jbt1 = new JButton("IFS树");
		jfr.add(jbt1);
		jbt1.addActionListener(drawl);
		JButton jbt2 = new JButton("IFS大树");
		jfr.add(jbt2);
		jbt2.addActionListener(drawl);
		jfr.add(jla);
		JButton jbt3 = new JButton("蕨类植物");
		jfr.add(jbt3);
		jbt3.addActionListener(drawl);              //把事件监听器放入到按钮当中
		jfr.setVisible(true);                         //设置界面可见
		Graphics g =jfr.getGraphics();      //画图板
		drawl.g= g;
	}

设置完界面只是第一步,其中分形最核心的一步就是找出迭代函数并且运用迭代函数,至于迭代式网上有许多资源,我们可以直接拿来用,比如说树的迭代式就是:xn+1=a xn+byn+e
yn+1=c xn+dn+f;
在这里插入图片描述
如此美的一棵树居然可以用一个小小的迭代函数表示出来,神奇吧。我虽说手画只会画一个火柴人,但是如果我能够好好运用分形,那我们我就是小小艺术家了。讲到这我还是回来吧。迭代函数最需要注意的就是代入参数这一步,参数有很多组,所有我们就要设置随机数组来表示参数出现的可能性,每一组参数代入的可能性可能一样,也可能不一样。这时我们可以这样来写:

Random r = new Random();
				int z =r.nextInt(5);
				if(z==0){
					a=0.1950;
			        b=-0.4880;
			        c=0.3440;
			        d=0.4430;
			        e1=0.4431;
			        f=0.2452;
				}
				else if(z==1){
					a=0.4620;
			        b=0.4140;
			        c=-0.2520;
			        d=0.3610;
			        e1=0.2511;
			        f=0.5692;
				}
				else if(z==2){
					a=-0.6370;
			        b=0.0000;
			        c=0.0000;
			        d= 0.5010;
			        e1=0.8562;
			        f=0.2512;
				}
				else if(z==3){
					a=-0.0350;
			        b=0.0700;
			        c=-0.4690;
			        d= 0.0220;
			        e1= 0.4884;
			        f=0.5069;
				}
				else{
					a=-0.0580;
			        b=-0.0700;
			        c=0.4530;
			        d= -0.1110;
			        e1= 0.5976;
			        f=0.0969;
				}

利用random对象的函数制造一个随机数组,然后用数出现的可能性代替每组参数组代入的可能性。
由于画图时drawLine(x1,y1,x1,y1)函数当中的x1,y1只能够是int 型,所有我们后面需要用到强制转换。

.......
double x1=0,y1=0;
.......
double x2=a*x1+b*y1+e1;
				double y2=c*x1+d*y1+f;
				
				int x3=(int)(-x2*(400)+m);
				int y3=(int)(-y2*(400)+n+200);
				g.setColor(Color.BLACK);
				g.drawLine(x3,y3,x3,y3);
				//System.out.println(x3+" ...."+y3);
				x1=x2;
				y1=y2;

分形举例

  1. IFS树
    在这里插入图片描述

IFS方程如下

xn+1=r cos(θ)xn-Ssin(Phi)yn+e yn+1=r sin(θ)xn+s cos(Phi)yn+f

参数表:
set 1 set 2 set 3 set 4 set 5 set 6
r 0.0500 0.0500 0.6000 0.5000 0.5000 0.5500
s 0.6000 -0.5000 0.5000 0.4500 0.5500 0.4000
theta 0.0000 0.0000 0.6980 0.3490 -0.5240 -0.6980
phi 0.0000 0.0000 0.6980 0.3492 -0.5240 -0.6980
e 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000
f 0.0000 1.0000 0.6000 1.1000 1.0000 0.7000

然后代入迭代式和参数即可:

.......
         double x1=0,y1=0;
			
			for(int j=0;j<5;j++){
				Random r1 = new Random();
			int m=r1.nextInt(500)+300;
			int n=r1.nextInt(500)+300;
			for(int i=0;i<=100000;i++){
				double r,s,theta,phi,e1,f;
				Random r2 = new Random();
				int z =r2.nextInt(6);
				if(z==0){
					r=0.05;
			        s=0.6;
			        theta=0;
			        phi=0;
			        e1=0;
			        f=0;
				}
				else if(z==1){
					r=0.05;
			        s=-0.5;
			        theta=0;
			        phi=0;
			        e1=0;
			        f=1;
				}
				else if(z==2){
					r=0.6;
			        s=0.5;
			        theta=0.698;
			        phi=0.698;
			        e1=0;
			        f=0.6;
				}
				else if(z==3){
					r=0.5;
			        s=0.45;
			        theta=0.349;
			        phi=0.3492;
			        e1=0;
			        f=1.1;
				}
				else if(z==4){
					r=0.5;
			        s=0.55;
			        theta=-0.524;
			        phi=-0.524;
			        e1=0;
			        f=1;
				}
				else{
					r=0.55;
			        s=0.4;
			        theta=-0.698;
			        phi=-0.698;
			        e1=0;
			        f=0.7;
				}
				double x2=r*Math.cos(theta)*x1-s*Math.sin(phi)*y1+e1;
				double y2=r*Math.sin(theta)*x1+s*Math.cos(phi)*y1+f;
				
				int x3=(int)(-x2*(200)+100+m);
				int y3=(int)(-y2*(200)+100+n);
				g.setColor(Color.DARK_GRAY);
				g.drawLine(x3,y3,x3,y3);
				//System.out.println(x3+" ...."+y3);
				x1=x2;
				y1=y2;
				....................

分形十分让我触动,因为我感叹于电脑的艺术,代码的艺术,利用分形,可以画出十分有艺术感的画,水墨画,山水画等等,都可以。期待自己掌握分形后走上艺术家的道路。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值