Java学习日记:UI篇(6)--谢尔宾斯基地毯图

本文介绍如何使用Java编程语言绘制谢尔宾斯基地毯,一种基于正方形的分形图形。通过迭代和递归方法,逐步构建出复杂的自相似图案。

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

Java学习日记:UI篇(6)–谢尔宾斯基地毯图

引言:谢尔宾斯基地毯是数学家谢尔宾斯基提出的一个分形图形,谢尔宾斯基地毯和谢尔宾斯基三角形基本类似,不同之处在于谢尔宾斯基地毯采用的是正方形进行分形构造,而谢尔宾斯基三角形采用的等边三角形进行分形构造。谢尔宾斯基地毯和它本身的一部分完全相似,减掉一块会破坏自相似性。(来自百度百科

是不是还不知道它是啥东西?没事,来张图看看:(有密集恐惧症者慎入)
在这里插入图片描述
在这里插入图片描述

思路:

方法1:

        ~~~~~~~        一个实心正方形划分为9个小正方形,为中间的小正方形涂上颜色(使得可见,所以你觉得什么颜色会让它最好看?),再对余下的小正方形重复这一操作便能得到谢尔宾斯基地毯。
        ~~~~~~~        显而易见,这是一个迭代的过程,我们不断的重复之前的动作,多次以后,我们就可以得到谢尔宾斯基地毯图了。
看到这里你有想法了吗?
        ~~~~~~~        
        ~~~~~~~        
我们来试一下在正中心画一个正方形:

int x0=100,y0=50,width=300,height=300;
g.drawRect(x0, y0, width, height);//最外面的方框
g.fillRect(x0+width/3,y0+ height/3, width/3, height/3);//中心的正方形

        ~~~~~~~        
        ~~~~~~~        x0、y0为方框左上角坐标,width、height分别为方框宽度和高度。根据思路里面说到的,将大的方框分为9个小正方形,所以中心正方形为方框的1/3。
        ~~~~~~~        
现在我们已经做完了第一次操作了,接下来就是将它周围的八个正方形做同样的处理。我们可以一个个画,如下:

g.fillRect(x0+0*width/3+width/9,y0+0*height/3+height/9, width/9, height/9);//0,0
g.fillRect(x0+1*width/3+width/9,y0+0*height/3+height/9, width/9, height/9);//1,0
g.fillRect(x0+2*width/3+width/9,y0+0*height/3+height/9, width/9, height/9);//2,0
g.fillRect(x0+0*width/3+width/9,y0+1*height/3+height/9, width/9, height/9);//0,1
g.fillRect(x0+2*width/3+width/9,y0+1*height/3+height/9, width/9, height/9);//2,1
g.fillRect(x0+0*width/3+width/9,y0+2*height/3+height/9, width/9, height/9);//0,2
g.fillRect(x0+1*width/3+width/9,y0+2*height/3+height/9, width/9, height/9);//1,2
g.fillRect(x0+2*width/3+width/9,y0+2*height/3+height/9, width/9, height/9);//2,2

看到这里发现什么规律了吗?我们画正方形的方法为:g.fillRect(x, y, width, height);,所以仔细看上面的代码,是不是每一次的x、y都在变化,而且是有规律的变化,增加width/3,height/3。参考下图,可以让你更容易理解为什么是增加width/3,height/3。
在这里插入图片描述
所以我们可以采取如下的方法来代替这一串代码:

for(int k=0;k<=2;k++) {	//改变纵坐标
			
	for(int j=0;j<=2;j++) {//改变横坐标
	
		g.fillRect(x0+j*width/3+width/9,y0+k*height/3+height/9, width/9, height/9);//绘画正方形	
	
	}

试试看交换两个for循环,是不是绘制顺序发生了改变?
        ~~~~~~~        
        ~~~~~~~        
接下来,我们进行层数嵌套:

int x0=100,y0=50,width=300,height=300;
g.drawRect(x0, y0, width, height);//最外面的方框
g.fillRect(x0+width/3,y0+ height/3, width/3, height/3);//中心的正方形
//开始切分
int n;//定义切分层数
for(int i=2;i<=n;i++){
	int a=(int) Math.pow(3, i);//这里用调整正方形宽度比例(1/9,1/27...)
	int b=(int) Math.pow(3, i-1);//间隔比例
	
	for(int k=0;k<=Math.pow(3, i-1)-1;k++) {	//改变纵坐标
		for(int j=0;j<=Math.pow(3, i-1)-1;j++) {//改变横坐标
		
			g.fillRect(x0+j*width/b+width/a,y0+k*height/b+height/a, width/a, height/a);//绘画
		}
	}
}

到此,我们便画出了如篇首的图像。为了让我们的过程更好,我们可以加入如下语句:

//加入判断语句,来跳过每一区域中心部分(已被上一级的正方形所覆盖,所以不需要再画了)
if(k==Math.pow(3,i-1)-2&&j==Math.pow(3,i-1)-2) {
	continue;//跳过中间的不画
	}
else{
	g.fillRect(x0+j*width/b+width/a,y0+k*height/b+height/a, width/a, height/a);//绘画
	//这里是让我们画图延迟一定时间,这样我们就可以清楚的看到画图的过程,1000 = 1s
	try {
		Thread.sleep(200);
	} catch (InterruptedException e) {
		// TODO Auto-generated catch block
		e.printStackTrace();
	}
}

        ~~~~~~~        
方法2
上面我们采用的是循环来绘制图形,接下面我们使用迭代来完成它。
思路
构建一个绘制方法,然后用这个方法对自己进行调用,达到迭代的目的,绘出整个图形。

public void drawMySher1(Graphics g,int x,int y,int width,int height,int n) {    	
		if(n<=0) { 
    		return;//当n<=0,结束此次调用,运行后面的代码
		}
    		g.fillRect(x+width/3, y+height/3, width/3, height/3);//绘制
    		n--;    		    		
    		drawMySher1(g,x,y,width/3,height/3,n);//0,0
    		drawMySher1(g,x+width/3,y,width/3,height/3,n);//1,0
	   		drawMySher1(g,x+2*width/3,y,width/3,height/3,n);//2,0		
	   		/。。。
    }

这里只是给出部分代码以作示例,重要的是思路。如果大家有什么想法的,欢迎一起讨论。
        ~~~~~~~        
        ~~~~~~~                 ~~~~~~~        
        ~~~~~~~        
画图需要在界面上实现,如果有不清楚的可前往UI篇(1)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值