分形之Julia集和Mandelbrot集及浅谈分形理论的应用

首先要show一把这俩个集合的图片


很漂亮是吧~不过很遗憾这不是我做的,但本人还是有画比较简单的两个集合的图形,有待指教改进。不过在此之前应该先简单介绍一下这两个集合,Mandelbrot集是通过迭代方程Zn+1=(Zn)^2+Zc,其中数Zc=0,Zn是一个复数。我们定义Mandelbrot集是所有复数Zc的集合,这样当n趋于无穷时Zn是有限的,如果超过2, Zn不会是有限的。例如我们想要的颜色像素(-1,0.5),以Zc = -1 +0.5i和Z0= 0开始,则有:
Z1 = Z0^2+Zc = -1+0.5i;
Z2 = Z1^2+Zc = -0.25-0.5i; 
Z3 = Z2^2+Zc = -1.1875+0.75i;
Z4 = Z3^2+Zc = -0.1529344-1.28125i;
Z5 = Z42+Zc = -2.61839+0.890381i;
``````
我们停在这里因为大小| Z5| = 2.76564> 2。我们得出这样的结论:这一点是无界的且迭代次数为5。然后我们再次重复整个过程的每个像素。而Julia集和Mandelbrot集是非常相似的因为所用的迭代方程为同一个Zn+1=(Zn)^2+Zc。然而,不同于上述的根据不同的Zc值绘制像素,我们假设Zc的所有像素是给定的常数,我们绘制不同的 。因此,这有无限的Julia集主要取决于你选择的Zc的取值。例如,我们想要的颜色像素(-1,0.5)的Julia集使用常数Zc = -1.125+0.25i,我们开始以Z0=-1+0.5i;
Z1 = Z02+Zc = -0.375-0.75i;
Z2 = Z12+Zc = -1.54688-0.8125i;
Z3 = Z22+Zc = -0.60767+2.26367i;
``````
我们停在这里,因为大小| Z3 | = 2.34381> 2。我们得出结论,这一点上是无限的和迭代n=3的基础上的像素.
以上的论断我们假设z=x+yi,可得两个集合均要求x^2+y^2<2^2,且对于Julia 集,固定Zc值,把复平面指定区域内的复数点作为初值Z0代入后,迭代过程Zn+1=Zn^2+Zc终止时的迭代次数;对于Mandelbrot 集,它表示固定Z0 值,把复平面指定区域内的复数点作为μ值代入后,迭代过程Zn+1=Zn^2+Zc终止时的迭代次数。写得比较简单,就一个JFrame界面和一个ActionListner监听器,界面部分就不拿出来了,下面是Julia集监听器部分代码
import java.awt.Color;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JFrame;
 
/**
 * 监听器
 * @author suer
 *
 */
public class CJuliadrawListener implements ActionListener {   
    double p, q;   //Zc=p+qi,p,q的值自己给定
    Graphics g;
    JFrame jf;
    private final int MAX=255;//颜色数值的最大值
	public CJuliadrawListener(Graphics g,JFrame jf){
		this.g=g;
		this.jf=jf;
	} 
	public void actionPerformed(ActionEvent e){
		String s=e.getActionCommand();
		if(s.equals("p=-0.65175;q=0.41850")){
			paint(g,-0.65175,0.41850);
		}else if(s.equals("p=-0.46;q=0.57")){
			paint(g,-0.46,0.57);
		}else if(s.equals("p=-0.8;q=0.156")){
			paint(g,-0.8,0.156);
		}else if(s.equals("p=-0.835;q=-0.2321")){
			paint(g,-0.835,-0.2321);
		}else if(s.equals("p=0.285;q=0.01")){
			paint(g,0.285,0.01);
		}else if(s.equals("p=-0.70176;q=-0.3842")){
			paint(g,-0.70176,-0.3842);
		}
    
	}
	/**
	 * julia集的实部和虚部值的范围
	 * @param x0:初始的实部值
	 * @param y0:初始的虚部值
	 * @return:循环的参数
	 */
    public int cjulia(double x0,double y0){   
        double xk,yk;   
        int i;   
        for (i=0;i<100;i++) {   
            xk=x0*x0-y0*y0+p;   
            yk=2*x0*y0+q; 
            if (xk*xk+yk*yk>4) return i;   
            x0=xk;   
            y0=yk;   
        }   
        return i;         
    }   
    /**
     * 由迭代产生的0.0到1.0的颜色值的方法
     * @param x0:初始的实部值
     * @param y0:初始的虚部值
     * @param p:Zc的实部值
     * @param q:Zc的虚部值
     * @return:颜色参数
     */
    private float punktfarbe(double x0, double y0,double p,double q){
       double xk=0, yk=0;
       int j = 0;
       while((j<MAX)&&(yk*yk+xk*xk< 4.0)){
        xk=x0*x0-y0*y0 + p;
        yk=2.0*x0*y0 + q;
        j++;
        x0=xk;
        y0=yk;
       }
      return (float)j/(float)MAX;
    }
   /**
    * 绘制julia集的方法
    * @param g:画布
    * @param p:Zc的实部值
    * @param q:Zc的虚部值
    */
    public void paint (Graphics g,double p,double q) { 
    	double reZ, imZ, ze0=0.0038; 
    	//double reZ, imZ, ze0=0.0055; 
        int x, y;   
        imZ=-1.5;   
        for (y=0;y<700;y++) {    
        	reZ=-1.5;  
            for (x=0;x<700;x++) {   
                if (cjulia(reZ,imZ)==100) {  
//                	float s=punktfarbe(reZ,imZ,p,q);
//                	float b=1.0f-s*s;
//                	g.setColor(Color.getHSBColor(1,s,b));
//                	float h=punktfarbe(reZ,imZ,p,q);
//                	float b=1.0f-h*h;
//                	g.setColor(Color.getHSBColor(h,1,b));  
//                	float b=punktfarbe(reZ,imZ,p,q);
//                	float h=1.0f-b*b;
//                	g.setColor(Color.getHSBColor(h,1,b));
                	float h=punktfarbe(reZ,imZ,p,q);
                	float s=1.0f-h*h;
                	g.setColor(Color.getHSBColor(h,s,1));  
                    g.drawLine(x+75,y,x+75,y);   
                }   
                reZ=reZ+ze0;    
            }   
            imZ=imZ+ze0;    
        }   
    }   
}

下面是Mandelbrot集的MouseListener监听器部分的代码
import java.awt.Color;
import java.awt.Graphics;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import javax.swing.JFrame;
public class MandelbrotListener implements MouseListener {  
	private static final double max=1.5;//最大值 
	private static final double min=-1.5; //最小值  
	private static final int Colors=25;  //颜色数 及增长数
	private Graphics g;
	private JFrame jf;
	public MandelbrotListener(Graphics 

g,JFrame jf){
		this.g=g;
		this.jf=jf;
	} 
	public void mouseClicked(MouseEvent e){}
    public void mousePressed(MouseEvent e){}
    public void mouseReleased(MouseEvent e){
    	drawMandel(g);
    }
    public void mouseEntered(MouseEvent e){}
    public void mouseExited(MouseEvent e){}
    public Color[] getColors(){return colors;}   
    /**
     * 颜色设置,rgb的值按colors的数值增长
     */
    private void makeColors(){   
        int maxRGB=255,r=0,g=0,b=0;   
        colors=new Color[Colors+1];   
        for(int i=0;i<Colors;i++){   
            colors[i]=new Color(r,g,b);   
            r+=Colors;   
            if(r>maxRGB){   
                r=0;g+=Colors;   
                if(g>maxRGB){   
                    g=0;   
                    b+=Colors;   
                }   
                if(b>maxRGB)   
                    b=0;   
            }   
        }   
        colors[Colors]=Color.white;   
    }   
    private static Color[] colors;   
   /**
    * 画mandelbrot集的方法,mandelbrot集要注意xstep,ystep,即发散的速度
    * @param g:画布
    */
    private void drawMandel(Graphics g){   
        double xstep,ystep,x,y;   //xstep,ystep是x,y值每次增加的大小
        int i,j,iteration,k=0;   
        double xk,yk,xh,yh,real,imag;;  
        xstep=0.0025;ystep=0.0035;
        for(y=min,j=0;y<=max;y+=ystep,j++){   
            for(x=min,i=0;x<=max;x+=xstep,i++){   
                xk=x;
                yk=y;   
                xh=yh=0.0;    
                for(iteration=0;iteration<Colors;iteration++){ 
                	real=xk+xh;
                	imag=yk+yh;
                	xh=real*real-imag*imag;
                	yh=2*real*imag;
                    if(xh*xh+yh*yh>4)   
                        break;   
                }    
                makeColors();
                g.setColor(colors[iteration]);   
                g.fillRect(i,j,1,1);   
                }   
        }
    }
}

最后要说的是,分形不是几个集合就能代表的,而是一门学问,分形理论的应用也不是局限在画出漂亮的图形而是囊括了很多方面,从大分子到宇宙星系,从自然科学到社会科学,凡是具有自相似性的现象就有分形存在。分形有在物理学中的应用,比如在准晶态的扩散、薄膜的研究、高能粒子碰撞中的阵发现象等,在化学中的应用,例如多相催化体系、宏观化学动力学等,又如植物中树、枝、叶、茎、花、草、蕨、花椰菜等是自然界中最先被认知具有分形维数的物体,材料制备和材料断裂行为等研究,以及用于解释和分析复杂的天文、水文、地质、地理等领域。此外在经济管理学、计算机图形学、复杂产品的分形设计、有限元网格划分的递推模型、制造决策映射建模等方面也有应用。

猜你喜欢

转载自931646813.iteye.com/blog/1870056