一些有趣的分形

一些有趣的分形

DrawUI

首先还是创建一个界面,这里我们都很熟悉,创建一个界面类

在这里插入图片描述

public class DrawUI(){
public void showUI(){
//创建窗体
		JFrame drawFrame = new JFrame("画板");
		drawFrame.setSize(1000,1000);
		drawFrame.setLocationRelativeTo(null);
		drawFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE );
		
		//设置布局
		JPanel north = new JPanel();
		north.setPreferredSize(new Dimension(0,30));
		drawFrame.add(north,BorderLayout.NORTH);
		
		JPanel center = new JPanel();
		drawFrame.add(center,BorderLayout.CENTER);
		center.setBackground(Color.WHITE);
		//设置窗体可见
        drawFrame.setVisible(true);
}
public static void main (String[] args){
 DrawUI ui = new DrawUI();
 ui.showUI();
}

界面完成以后,我们在上面添加一些按钮,当然这里的按钮的名字我们可以随意,我随便设置了几个名字

        //north是我们的北部边界,上面设置了的,把按钮放在上面比较美观,
        //不设置北部边界直接界面的流式布局也可以,
       // 这里主要是为了熟练JPanel的应用
        JButton btn1 = new JButton("蛋");
        north.add(btn1);
        
        JButton btn2 = new JButton("乱");
        north.add(btn2);
        
        JButton btn3 = new JButton("心");
        north.add(btn3);
        
        JButton btn4 = new JButton("树");
        north.add(btn4);
		
        JButton btn5 = new JButton("三角");
        north.add(btn5);

然后运行,我们就可以得到这样一个界面了
在这里插入图片描述

IFS

建一个IFS类来写我们的分形的方法
所谓的分形,就是通过数学公式计算出点的坐标,然后再用计算机画出来
例如这个
在这里插入图片描述
公式代入计算很简单,只有一个地方要注意到就是我们会用到一个缓存画布,因为我们经过了几万次的画点,如果一个一个点画,会很难看,所以我们用到缓存画布

public class IFS {
	
//A按钮定义
	public void drawA(Graphics g) {
		double x = 0f;
		double y = 0f;
		double a = -1.8, b = -2.8, c = -0.5, d = -0.9;

		// 缓存画布
		BufferedImage ig = new BufferedImage(1000, 600, BufferedImage.TYPE_INT_ARGB);
		Graphics nb = ig.getGraphics();
		g.setColor(Color.BLACK);

		for (; a < 1; a -= 0.001) {
			nb.setColor(Color.BLACK);
			nb.fillRect(0, 0, 1000, 600);

			nb.setColor(new Color(Color.HSBtoRGB((float) (a + 1), (float) (a + 2), 3)));

			for (int i = 0; i < 20000; i++) {
				double temx = Math.sin(a * y) + c * Math.cos(a * x);
				double temy = Math.sin(b * x) + d * Math.cos(b * y);
				int x1 = (int) (temx * 100 + 300);
				int y1 = (int) (temy * 100 + 300);
				nb.drawLine(x1, y1, x1, y1);
				x = temx;
				y = temy;
				
			}
			g.drawImage(ig,0,0,null);
		}
	}
	
	
//B按钮定义
	public void drawB(Graphics g) {
		double x = 0f;
		double y = 0f;
		double a;
		double b ;
		double c ; 
		double d  ;
		
		if (Math.random()<0.5 ){
			a = 1.641;
			b = 1.902;
			c = 0.316;
			d = 1.525;
		} else {
			a = 0.970;
			b = -1.899;
			c = 1.381;
			d = -1.506;
		}

		// 缓存画布
		BufferedImage ig = new BufferedImage(1000, 600, BufferedImage.TYPE_INT_ARGB);
		Graphics nb = ig.getGraphics();
		g.setColor(Color.BLACK);

		for (; a > 1; a += 0.001) {
			nb.setColor(Color.BLACK);
			nb.fillRect(0, 0, 1000, 600);

			nb.setColor(new Color(Color.HSBtoRGB((float) (a + 2), (float) (a + 3), 1)));

			for (int i = 0; i < 10000; i++) {
				double temx = Math.sin(a * y) -  Math.cos(b * x);
				double temy = Math.sin(c * x) -  Math.cos(d * y);
				int x1 = (int) (temx * 100 + 300);
				int y1 = (int) (temy * 100 + 300);
				nb.drawLine(x1, y1, x1, y1);
				x = temx;
				y = temy;
			}
			g.drawImage(ig, 0, 0, null);
		}
	}
	
//C按钮定义
	public void drawC(Graphics g){
		

                g.setColor(Color.BLACK);
				g.fillRect(0, 0, 1000, 600);
		for(int i=0;i<=180;i++){     
			for(int j=0;j<=180;j++){   
				
				double r=Math.PI/45*i*(1-Math.sin(Math.PI/45*j))*20;   
				double x=r*Math.cos(Math.PI/45*j)*Math.sin(Math.PI/45*i)+300;   
				double y=-r*Math.sin(Math.PI/45*j)+200;    
				Color c=Color.getHSBColor(i*j/8100.0f, 0.9999f,0.9999f);   
				g.setColor(c);      
				g.drawOval((int)x, (int)y, 1,1);   
				try{    
					Thread.sleep(1);    
					}
				catch(Exception e){}        
				}      
			}   
		} 
	
	
//D按钮定义
	public void drawD(Graphics g) {

		double x=200,y=200;
		double[][] array={
				{0.05,0.0,0.0,0.4,-0.06,-0.47},
				{-0.05,0.0,0.0,-0.4,-0.06,-0.47},
				{0.03,-0.14,0.0,0.26,-0.16,-0.01},
				{-0.03,0.14,0.0,-0.26,-0.16,-0.01},
				{0.56,0.44,-0.37,0.51,0.3,0.15},
				{0.19,0.07,-0.1,0.15,-0.2,0.28},
				{-0.33,-0.34,-0.33,0.34,-0.54,0.39}
				};
		//随机数
				Random r=new Random(0);
	//			Random k=new Random(0);
				g.setColor(Color.BLACK);
				g.fillRect(0, 0, 1000, 400);
				Color headColor = new Color(89,139,137);
				g.setColor(headColor);
                g.fillRect(0, 400, 1000, 600);
				for(int i=0;i<25500;i++){
					int j=r.nextInt(7);
					double a=array[j][0],b=array[j][1],c=array[j][2],
							d=array[j][3],e=array[j][4],f=array[j][5];
					double tempx=a*x+b*y+e;
					double tempy=c*x+d*y+f;
					int showx=(int)(tempx*200+400);
					int showy=(int)(tempy*200+550);
					//倒影
					g.setColor(new Color(20,21,25));
					if(i%2==0)g.drawLine(showx,showy,showx+4,showy);
					else g.drawLine(showx-4, showy, showx, showy);
					//正向树
					int changey=790-showy;
					g.setColor(new Color(i/100,138,207));
					g.drawLine(showx,changey,showx,changey);
					//迭代
					x=tempx;
					y=tempy;
				}
				g.setColor(new Color(95,129,19));
				g.drawOval(60, 400, 500, 5);

				try{    
					Thread.sleep(100);    
					}
				catch(Exception e){}      
		
	}
	
	//E按钮定义
	//这里是我后来加的,画的递归的三角形,也还挺好看,就放上去了
	
	public void drawE(Graphics g,int n,int d,int x0,int y0) {
    
	if(n==0) {
		
	}
	else {
    //画出一个大三角形
	double x1=x0+d;
	double y1=y0+Math.sqrt(3)*d;
	double x2=x0-d;
	double y2=y0+Math.sqrt(3)*d;
	g.drawLine(x0,y0,(int)x1,(int)y1 );
	g.drawLine((int)x1, (int)y1,(int)x2 ,(int)y2 );
	g.drawLine((int)x2,(int)y2,x0 ,y0 );
	//取三边中点
	double x3=(x0+x1)/2;
	double y3=(y0+y1)/2;
	double x4=(x1+x2)/2;
	double y4=(y1+y2)/2;
	double x5=(x0+x2)/2;
	double y5=(y0+y2)/2;
	
	//中点再连线
	g.drawLine((int)x3,(int)y3,(int)x4,(int)y4);
	g.drawLine((int)x3,(int)y3,(int)x5 ,(int)y5);
	g.drawLine((int)x4,(int)y4,(int)x5 ,(int)y5);
	//再取中点连线
	double x6=(x3+x5)/2;
	double y6=(y3+y5)/2;
	double x7=(x3+x4)/2;
	double y7=(y3+y4)/2;
	double x8=(x4+x5)/2;
	double y8=(y4+y5)/2;
	g.drawLine((int)x6,(int)y6,(int)x7 ,(int)y7);
	g.drawLine((int)x6,(int)y6,(int)x8 ,(int)y8);
	g.drawLine((int)x7,(int)y7,(int)x8 ,(int)y8);
	
	//递归
	drawE(g,n-1,d/2,x0,y0);
	drawE(g,n-1,d/2,(int)x3,(int)y3);
	drawE(g,n-1,d/2,(int)x5,(int)y5);
	
	}
		
	}

	}

DrawListener

接下来写我们的监听器类

public class DrawListener implements ActionListener{
	
    String cmd="0";
	Graphics g;
	
	    	cmd = e.getActionCommand();//获得按钮上的内容然后调用IFS类里的方法
	    	if(cmd.equals("蛋")) {
				IFS ifs= new IFS();
				ifs.drawA(g);
			}
			if(cmd.equals("乱")) {
				IFS ifs= new IFS();
				ifs.drawB(g);
			}
			
			if(cmd.equals("心")) {
				IFS ifs= new IFS();
				ifs.drawC(g);
			}
			
			if(cmd.equals("树")) {
				IFS ifs= new IFS();
				ifs.drawD(g);
			}
			
			if(cmd.equals("三角")) {
				IFS ifs= new IFS();
				ifs.drawE(g,5,400,400,200);
	    }
		
	}
	}

然后就可以了,最后一步在界面里加上我们的监听器

 //创建监听器
        DrawListener drawL = new DrawListener();
        //获取窗体的画布
        drawL.g= center.getGraphics();
        
		//创建Button监听器
		btn1.addActionListener(drawL);
		btn2.addActionListener(drawL);
		btn3.addActionListener(drawL);
		btn4.addActionListener(drawL);
		btn5.addActionListener(drawL);

结束!看看效果
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
over~

发布了13 篇原创文章 · 获赞 1 · 访问量 304

猜你喜欢

转载自blog.csdn.net/Alagagaga/article/details/103430573
今日推荐