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