1. 牛顿分形(Newton Fractal)
在复数域上使用牛顿迭代生成分形图像,函数公式F(z) = z^3 – 1在复数域上面有
三个根,一个是1,另外两个分别是复数-0.5+0.87i 与 -0.5 – 0.87i根据计算出来根
的值不同转换为RGB三种不同的颜色,根据迭代次数的多少设置颜色值的大小,

即颜色强度。

二叉树递归分形,牛顿分形图案_jcomponent

2. 曼德布罗特集合分形(Mandelbort Set Fractal) 使用复数函数公式F(z) = z^2 + c其中

c是一个复数

二叉树递归分形,牛顿分形图案_jcomponent_02

3. 递归分形树 (recursion tree)– 类似二叉树的递归生成树干,同时不断的缩小树干长
度,根据递归次数不同与角度不同可以得到不同的递归分形树,注意Java最大栈
深度是64,过度的归次数可能导致java栈溢出错误。递归次数建议不要超过32.

二叉树递归分形,牛顿分形图案_recursion_03

根据角度不同,可以生成不同的二叉递归树。

牛顿迭代与曼德尔波特分形算法需要复数范围内的加减乘除计算,请先google一下

然后就知道啦。本人实现的复数计算的类如下:

package com.gloomyfish.fractal;  public class Complex {   private float real;   private float imaginary;    public Complex(float paramFloat1, float paramFloat2)   {     this.real = paramFloat1;     this.imaginary = paramFloat2;   }    public float real()   {     return this.real;   }    public float imaginary()   {     return this.imaginary;   }    public float modulus()   {     return (float)Math.sqrt(this.real * this.real + this.imaginary * this.imaginary);   }    public boolean equal(Complex paramComplex)   {     return ((this.real == paramComplex.real()) && (this.imaginary == paramComplex.imaginary()));   }    public Complex add(Complex paramComplex)   {     return new Complex(this.real + paramComplex.real(), this.imaginary + paramComplex.imaginary());   }    public Complex subtract(Complex paramComplex)   {     return new Complex(this.real - paramComplex.real(), this.imaginary - paramComplex.imaginary());   }    public Complex multiply(Complex paramComplex)   {     return new Complex(this.real * paramComplex.real() - (this.imaginary * paramComplex.imaginary()), this.real * paramComplex.imaginary() + this.imaginary * paramComplex.real());   }    public Complex divide(Complex paramComplex)   {     float f1 = paramComplex.real() * paramComplex.real() + paramComplex.imaginary() * paramComplex.imaginary();     float f2 = (this.real * paramComplex.real() + this.imaginary * paramComplex.imaginary()) / f1;     float f3 = (this.imaginary * paramComplex.real() - (this.real * paramComplex.imaginary())) / f1;      return new Complex(f2, f3);   }    public String toString()   {     String str = (this.imaginary >= 0.0F) ? "+" : "-";     return this.real + str + Math.abs(this.imaginary) + "i";   } }
牛顿分形的算法代码如下:

package com.gloomyfish.fractal;  public class NewtonFractal extends Fractal { 	private static final Complex ONE = new Complex(1.0F, 0.0F); 	private static final Complex THREE = new Complex(3.0F, 0.0F); 	public NewtonFractal(int widthImage, int heightImage) { 		super(widthImage, heightImage); 		 		// default start point and end point 		// primary group,  		this.x1 = -1.0f; 		this.y1 = -1.0f; 		this.x2 = 1.0f; 		this.y2 = 1.0f; 		 		// second group 		//	this.x1 = -3.0f; 		//	this.y1 = -1.76f; 		//	this.x2 = 3.0f; 		//	this.y2 = 1.76f; 		// end comment 		 	}  	@Override 	public void BuildFractal() { 		int[] inPixels = new int[getWidth()*getHeight()];         getRGB(fractalImage, 0, 0, getWidth(), getHeight(), inPixels );         int index = 0;         float xDelta = ((x2 - x1) / (float)width);         float yDelta = ((y2 - y1) / (float)height);         for(int row=0; row<height; row++) {         	int ta = 0, tr = 0, tg = 0, tb = 0;         	for(int col=0; col<width; col++) {         		Complex localComplex2;                 float f1 = this.x1 + col * xDelta;                 float f2 = this.y2 - (row * yDelta);                 Complex localComplex1 = new Complex(f1, f2);                  int k = 0;                 do {                   Complex localComplex3 = localComplex1.multiply(localComplex1);                   Complex localComplex4 = localComplex3.multiply(localComplex1);                    localComplex2 = localComplex1;                   localComplex1 = localComplex1.subtract(localComplex4.subtract(ONE).divide(THREE.multiply(localComplex3)));                 }                  while ((++k < MAX_ITERS) && (!(localComplex1.equal(localComplex2))));                  int l = 20 * k % 10; // keep value scope between 0 and 255                  // if root is 1 then                 if (localComplex1.real() > 0.0F)                 {                 	tr = tg = l;                 	tb = 255;                 }                                  // if root is second complex = -0.5+0.87i                 else if (localComplex1.imaginary() > 0.0F)                 {                 	tr = tb = l;                 	tg = 255;                 }                 else                 {                   tr = 255;                   tg = tb = l;                 }         		         		index = row * width + col;         		ta = 255;         		inPixels[index] = (ta << 24) | (tr << 16) | (tg << 8) | tb;         	}         }         setRGB(fractalImage, 0, 0, getWidth(), getHeight(), inPixels); 	}  } 
曼德尔波特分形算法如下:

package com.gloomyfish.fractal;  public class MandelbrotSetFractal extends Fractal { 	private float delta = 0.01f; 	public MandelbrotSetFractal(int widthImage, int heightImage) { 		super(widthImage, heightImage); 	    this.delta = 0.01F; 	    this.x1 = (-(this.width / 2) * this.delta); 	    this.y1 = (-(this.height / 2) * this.delta); 	    this.x2 = (-this.x1); 	    this.y2 = (-this.y1); 	}  	@Override 	public void BuildFractal() { 		int[] inPixels = new int[getWidth()*getHeight()];         getRGB(fractalImage, 0, 0, getWidth(), getHeight(), inPixels );         int index = 0;         for(int row=0; row<height; row++) {         	int ta = 0, tr = 0, tg = 0, tb = 0;         	float f1 = y2 - (row * delta);         	for(int col=0; col<width; col++) {         		float f5;                 int i1;                 float f2 = x1 + col * delta;                 Complex localComplex1 = new Complex(f2, f1);                 Complex localComplex2 = new Complex(0.0F, 0.0F);                  int k = 0;                 int l = 0;                 do                 {                   localComplex2 = localComplex2.multiply(localComplex2).add(localComplex1);                   f5 = localComplex2.modulus();                   k = (f5 > 2.0F) ? 1 : 0; }                 while ((++l < 32) && (k == 0));                  index = row * width + col;                 if (k != 0) {                   i1 = 255 - (255 * l / 32);                   i1 = Math.min(i1, 240);                   tr = tg = tb = i1;                 }                 else                 {                   i1 = (int)(100.0F * f5) / 2 + 1;                    int i2 = 101 * i1 & 0xFF;                   int i3 = 149 * i1 & 0xFF;                   int i4 = 199 * i1 & 0xFF;                   tr = i2;                   tg = i3;                   tb = i4;                 }         		         		ta = 255;         		inPixels[index] = (ta << 24) | (tr << 16) | (tg << 8) | tb;         	}         }         setRGB(fractalImage, 0, 0, getWidth(), getHeight(), inPixels); 	}  } 
递归分形树代码如下:

package com.gloomyfish.fractal;  import java.awt.BorderLayout; import java.awt.Color; import java.awt.Dimension; import java.awt.Font; import java.awt.FontFormatException; import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.RenderingHints; import java.io.IOException; import java.io.InputStream; import java.util.Date;  import javax.swing.JComponent; import javax.swing.JFrame;  public class FractalTree extends JComponent { 	 	/** 	 *  	 */ 	private static final long serialVersionUID = 8812325148970066491L;  	private int maxRecursions = 8; //never make this too big or it'll take forever 	private double angle = 0.2 * Math.PI; //angle in radians 	private double shrink = 1.8; //relative size of new branches 	public FractalTree() { 		super(); 	} 	protected void paintComponent(Graphics g) { 		Graphics2D g2 = (Graphics2D) g; 		g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); 		g2.setPaint(Color.WHITE); 		g2.fillRect(0, 0, 400, 400); 		renderTree(g2); 		g2.setPaint(Color.RED); 		try { 			g2.setFont(loadFont()); 		} catch (FontFormatException e) { 			// TODO Auto-generated catch block 			e.printStackTrace(); 		} catch (IOException e) { 			// TODO Auto-generated catch block 			e.printStackTrace(); 		} 		g2.drawString("Created by Gloomyfish " + new Date(System.currentTimeMillis()), 10, 320); 	} 	 	/** 	 * create fractal tree using recursion 	 * @param Graphics2D g2 	 */ 	private void renderTree(Graphics2D g2) { 		g2.setPaint(new Color(128, 96, 64)); 		recursion(400.0d / 2.0d, 400.0d -1.0d, 0.0d, -1.0d, 400.0d / 2.3d, 0, g2); 	} 	 	// http://www.cg.info.hiroshima-cu.ac.jp/~miyazaki/knowledge/teche31.html 	void recursion(double posX, double posY, double dirX, double dirY, double size, int n, Graphics2D g2) 	{ 	    int x1, x2, y1, y2; 	    x1 = (int)posX; 	    y1 = (int)posY; 	    x2 = (int)(posX + size * dirX); 	    y2 = (int)(posY + size * dirY); 	    g2.drawLine(x1, y1, x2, y2);  	    if(n >= maxRecursions) return; 	    double posX2, posY2, dirX2, dirY2, size2; 	    int n2; 	     	    // calculate the new start point coordinate 	    posX2 = posX + size * dirX; 	    posY2 = posY + size * dirY; 	    size2 = size / shrink; // make different length of line. 	    n2 = n + 1; 	     	    // rotate angle and get the new directX, directY 	    // http://www.jimloy.com/geometry/trigz.htm 	    // sin(theta + angle) = sin(theta) * cos(angle) + cos(theta) * sin(angle) 	    // cos(theta + angle) = -sin(angle) * sin(theta) + cos(theta) * cos(angle) 	    dirX2 = Math.cos(angle) * dirX + Math.sin(angle) * dirY; 	    dirY2 = -Math.sin(angle) * dirX + Math.cos(angle) * dirY; 	    recursion(posX2, posY2, dirX2, dirY2, size2, n2, g2); 	     	    dirX2 = Math.cos(-angle) * dirX + Math.sin(-angle) * dirY; 	    dirY2 = -Math.sin(-angle) * dirX + Math.cos(-angle) * dirY; 	    recursion(posX2, posY2, dirX2, dirY2, size2, n2, g2); 	} 	 	/** 	 * http://en.wikipedia.org/wiki/Mandelbrot_set 	 * http://www.urbanfonts.com/fonts/sans-serif-fonts.htm 	 * @return 	 * @throws FontFormatException 	 * @throws IOException 	 */ 	public Font loadFont() throws FontFormatException, IOException{ 	    String fontFileName = "AMERSN.ttf"; 	    InputStream is = this.getClass().getResourceAsStream(fontFileName); 	    Font actionJson = Font.createFont(Font.TRUETYPE_FONT, is); 	    Font actionJsonBase = actionJson.deriveFont(Font.BOLD, 12); 	    return actionJsonBase; 	} 	 	public static void main(String[] args) { 		JFrame frame = new JFrame("Fractal Tree UI - GloomyFish"); 		frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 		frame.getContentPane().setLayout(new BorderLayout()); 		 		// Display the window. 		frame.getContentPane().add(new FractalTree(), BorderLayout.CENTER); 		frame.setPreferredSize(new Dimension(450,400)); 		frame.pack(); 		frame.setVisible(true); 	} }