`
xuluan
  • 浏览: 11229 次
  • 性别: Icon_minigender_1
社区版块
存档分类
最新评论
阅读更多

    

     前言: 

 

     首先先简单介绍一下Mandelbrot集,该集被曼德布罗特教授称之为“魔鬼的聚合物”,也被大家称之为“上帝的指纹”。之所以这么称呼,我想是该集合本身的自相似性及其图像复杂度。然而,如此复杂的图像也只不过是通过一个简单的公式(Z^2 = Z^2 + c)来完成的,当然当年曼德布罗特教授发现这个公式是不容易的。我刚开始接触Mandelbrot集的时候并没有注意到其简单性,只是觉得图像蛮漂亮的,就开始着手了。当时也没有注意到其子集Julia集,最后才发现Julia集与Mandelbrot集是一个公式来的,只是它们的初始条件不同而已。Julia集中,复数c是固定,确切的说是它不随复平面上的坐标变化而变化。而Mandelbrot集中的c是随坐标值改变而改变的。 

     MandelBrot vs Julia: 

     下面就切入正题了,刚在前言里也说过Julia集是Mandelbrot集的子集,这也就是说如果把Madelbrot集画出来,再画Julia集就简单多了。Mandelbrot集的图像是一个3:2(这个可以研究一下公式)的图,为了使图像好看些可以按这个比例把它放大,比如说把这个它画在一个600x400的框架中,缩放比例也就是1/200。下面主要是初始化Z^2 = Z^2 + c,c = new Complex((double)x * rate - 2.0,(double)y * rate - 1.0);z = c;然后就是进行公式转化了,即Z^2 = Z^2 + c,直达达到迭代次数或者复数z的模长大于2采跳出循环。迭代次数其实就是放大比例,次数越多放大效果越好,看的也越精细,也会体现出它的自相似。之所以要以模长为2为界限,这个就需要自己研究一下公式了。跳出循环时,如果达到迭代次数就是Mandelbrot集里的,不然就不是了。这样我们就可也找出框架里的点那些是Mandelbrot集里的,那些不是了,说到这里Mandelbrot集也就差不多出来了。下面给出一小段关于画Mandelbrot的代码:

for (int x = 0; x < 600; x++) {
	for (int y = 0; y < 400; y++) {
				
		interation = 0;
		c = new Complex((double)x * rate - 2.0,(double)y * rate - 1.0);
		z = c.add(new Complex(0.0,0.0));
		//计算模长
		length = Math.sqrt(z.re * z.re + z.im * z.im);
				
		//判断是否在set内
		while (length <= 2 && interation < maxInteration) {
					
			//Mandelbrot集
			z = z.multiply(z);
			z = z.add(c);
					
			//计算模长
			length = Math.sqrt(z.re * z.re + z.im * z.im);
					
			interation++;
		}
					
		//如果在set内
		if (interation == maxInteration) {
			g.setColor(Color.BLACK);
			g.drawLine(x, y + 5, x, y + 5);
		}else {//如果不在set内
			g.setColor(advocate(interation));
			g.drawLine(x, y + 5, x, y + 5);
		}
				
	}
}

     相信画Mandelbrot集已经很简单了,下面开始画Julia集了。

    

      刚才也说过如果已经画出Mandelbrot集,那么Julia集就不用费吹灰之力了。给窗体添加一个鼠标监听器,获取坐标,然后根据坐标就可以得到c了,即c = new Complex((double)x * rate - 2.0,(double)y * rate - 1.0);,然后就是跟画Mandelbrot集相同的步骤了,这里就不多说了,只给出相应的代码了。

 

public void mouseMoved(MouseEvent e){
        x1 = e.getX();
	y1 = e.getY();
	//System.out.println("x1的值:" + x1 + "y1的值:" + y1);
	c1 = new Complex((double)x1 * rate - 2.0,(double)y1 * rate - 1.04);
	for (int x = 0; x < 600; x++) {
		for (int y = 0; y < heigth; y++) {
						
		        interation = 0;
		        z1 = new Complex((double)x * rate - 1.5,(double)y 
                                                             * rate - 1.05);
			//计算模长
		         length = Math.sqrt(z1.re * z1.re + z1.im * z1.im);
						
			//判断是否在set内
			while (length <= 2 && interation < maxInteration) {
							
				//Mandelbrot集
				z1 = z1.multiply(z1);
				z1 = z1.add(c1);
							
				//计算模长
				length = Math.sqrt(z1.re * z1.re + z1.im 
                                                                      * z1.im);
							
			        interation++;
			}
							
			//如果在set内
			if (interation == maxInteration) {
				g.setColor(Color.BLACK);
				g.drawLine(x + 605, y, x + 605, y);
			}else {//如果不在set内
			         g.setColor(advocate(interation));
	                        g.drawLine(x + 605, y, x + 605, y);
			}
						
	       }
	}
}

 

下面给张图片:



 

 

其实Mandelbrot集可以进行无限放大,放大思想:①选中的区域调整比例为3:2,上下左右缩放一下就可以;

                                                                             ②然后就是把坐标轴改变位置,即把原点移到选中区域中的分叉点上;

                                                                             ③接下来当然是调整缩放比例了,如果不调整的话,也就不是放大了,其实根本也放不大。原先的1/200(3.0/640.0)也就变成(tox - fromx)/ 640.0。tox是选中区域右边横坐标,fromx也就是选中区域左边坐标了。

 

PS:附件中有.jar文件,可以看看效果,只是Julia集的色彩配的不怎么好

 

  • 大小: 184.6 KB
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics