分形(二)

在代码运行起来是各种诡秘的结果的时候,真是强烈觉得分形是一个奇妙的东西,虽然无比希望可以意外画出特好看的图形,可惜貌似运气不怎么样,或者在改了代码之后才反应过来没有保存。。。

谢宾斯基三角形,运行结果如下:

 

 

显然,是用一个循环或者递归来实现的,每次都在一个大的三角形里取中点,再将三点连起来,又会形成三个小号的顶点向上的三角形,然后继续连接其三边的中点,以此类推。

首先,肯定得先把那个最大的三角形单独给画出来了。接下来计算中点是必须的,然后直接把三个点连起来就可以了,由于三角形已经被划分成了四个部分,而我们又要继续在其中三个三角形中再画,所以之后必定得要根据情况传入不同参数,三次调用它本身,于是就可以一直画相同的图形了。

 

代码如下:

 

public class TriangleFrame extends  JFrame{
	public static void main(String [] args){
		TriangleFrame Tri=new TriangleFrame();
		Tri.showGUI();
}
	
Graphics g;

public void showGUI(){
			this.setSize(600, 600);
			this.setTitle("三角形");
			this.setDefaultCloseOperation(3);
			this.setVisible(true);
			//获取画布
			g=this.getGraphics();
			paint(g);
	}

public void pa(int x1,int x2,int x3,int y1,int y2,int y3,int i){
		if(i>0){
		i--;
	    int px1=(x1+x2)/2;
	    int px2=(x1+x3)/2;
	    int px3=(x2+x3)/2;
	    int py1=(y1+y2)/2;
	    int py2=(y1+y3)/2;
	    int py3=(y2+y3)/2;
	    
	    g.drawLine(px1, py1,px2, py2);   
            g.drawLine(px1, py1, px3,py3);   
	    g.drawLine(px2, py2, px3, py3);  
		 try{
				 Thread.sleep(1);
			 }catch(Exception ef){}
		pa(x1,px2,px1,y1,py2,py1,i);
		pa(px1,x2,px3,py1,y2,py3,i);
		pa(px3,px2,x3,py3,py2,y3,i);
		}
}

public void paint(Graphics g){
	super.paint(g) ;
	int x1,x2,x3;
	int y1,y2,y3;
	int i=8;
	x1=250;x2=0;x3=500;y1=100;y2=400;y3=400;

	g.drawLine(x1, y1, x2, y2);   
        g.drawLine(x2, y2, x3, y3);   
        g.drawLine(x1, y1, x3, y3);   
  
        Color co = new Color(116,116,116);
        g.setColor(co);
        pa(x1,x2,x3,y1,y2,y3,i);
    }
}

 

 

科赫曲线,好吧,这个是貌似是变种的,不知为何每条线都只画出来一半,话说其实我觉得这个比较好看,如图:

 

 

首先得搜那个计算三分点的公式,然后就是分情况讨论了,它有三种画法,一种是底是平的,另两种分别是向左倾斜和向右倾斜。画一次就是四个三角形,两条边上和距离三分之一个边长的地方各一个,也就是四个递归了。然后是连线,重点就是必须只画一次,到最后找到所有点了再画。开始很奇怪原本自己就是斜的的三角形再在两边上画三角形要不要多分几种情况,莫名其妙画出来了,觉得古怪又改回每次画线,再去掉那些线的时候就出现了上图的状况,好吧,代码是个神奇的东西。。。          

 

代码如下:

public class ExamFrame extends JFrame{

	public static void main(String[] args) {
		ExamFrame df = new ExamFrame();
		df.initGUI();
	}
	
	private int count=4;  
	Graphics g;

	public void initGUI() {
		// 窗体的属性
		this.setTitle(" ");
		this.setSize(900,600);
		this.setLocation(100, 100);
		this.setDefaultCloseOperation(3);
		this.setVisible(true);
	
		//获取事件源上的画布对象
		g = this.getGraphics();
		
	}
	//重绘的方法 
    public void paint(Graphics g) {  
        // TODO Auto-generated method stub  
        super.paint(g);  
        int x1=100,x2=400,y1=600,y2=400;
       // g.drawLine(x1,y1,x2,y2);  
        draw(100,400,600,400,count);  
    }  
  
   
    public void draw(int x1,int y1,int x2,int y2,int count){  
    
    	if(count>0){
            //三分点

            double x3=(2*x1+x2)/3;  
            double y3=(2*y1+y2)/3;  
              
            double x4=(x1+2*x2)/3;  
            double y4=(y1+2*y2)/3;  
            
            double x5=0;
            double y5=0;   
            //System.out.println("yes");
            
            double k=(y4-y3)/(x4-x3);   
         
            if(k==0){  
                x5=(x3+x4)/2;  
                y5=y3-(x4-x3)*Math.sqrt(3)/2;  
            }else if(k>0){  
                y5=y3;  
                x5=2*x4-x3;  
            }else if(k<0){
                y5=y4;  
                x5=2*x3-x4;  
           }
   
            int tx1=(int)x1;  
            int tx2=(int)x2; 
            int ty1=(int)y1; 
            int ty2=(int)y2; 
            int tx3=(int)x3;  
            int tx4=(int)x4; 
            int ty3=(int)y3; 
            int ty4=(int)y4; 
            int tx5=(int)x5;  
            int ty5=(int)y5; 

          
            draw(tx1,ty1,tx3,ty3,count-1);
            draw(tx3,ty3,tx5,ty5,count-1);
            draw(tx5,ty5,tx4,ty4,count-1);
            draw(tx4,ty4,tx2,ty2,count-1);  
          
      	  //递归调用;  
        	if(count==1)
        		g.drawLine(tx1,ty1,tx3,ty3);
    		}
        }  
    }