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

简介: <span style="color: rgb(51, 51, 51); font-family: Arial; font-size: 14px; line-height: 26px;">1. 牛顿分形(Newton Fractal)</span><br style="color: rgb(51, 51, 51); font-family: Arial; font-size: 14px; li
1. 牛顿分形(Newton Fractal)
在复数域上使用牛顿迭代生成分形图像,函数公式F(z) = z^3 – 1在复数域上面有
三个根,一个是1,另外两个分别是复数-0.5+0.87i 与 -0.5 – 0.87i根据计算出来根
的值不同转换为RGB三种不同的颜色,根据迭代次数的多少设置颜色值的大小,

即颜色强度。


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

c是一个复数


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


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

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

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

[java]  view plain copy
  1. package com.gloomyfish.fractal;  
  2.   
  3. public class Complex  
  4. {  
  5.   private float real;  
  6.   private float imaginary;  
  7.   
  8.   public Complex(float paramFloat1, float paramFloat2)  
  9.   {  
  10.     this.real = paramFloat1;  
  11.     this.imaginary = paramFloat2;  
  12.   }  
  13.   
  14.   public float real()  
  15.   {  
  16.     return this.real;  
  17.   }  
  18.   
  19.   public float imaginary()  
  20.   {  
  21.     return this.imaginary;  
  22.   }  
  23.   
  24.   public float modulus()  
  25.   {  
  26.     return (float)Math.sqrt(this.real * this.real + this.imaginary * this.imaginary);  
  27.   }  
  28.   
  29.   public boolean equal(Complex paramComplex)  
  30.   {  
  31.     return ((this.real == paramComplex.real()) && (this.imaginary == paramComplex.imaginary()));  
  32.   }  
  33.   
  34.   public Complex add(Complex paramComplex)  
  35.   {  
  36.     return new Complex(this.real + paramComplex.real(), this.imaginary + paramComplex.imaginary());  
  37.   }  
  38.   
  39.   public Complex subtract(Complex paramComplex)  
  40.   {  
  41.     return new Complex(this.real - paramComplex.real(), this.imaginary - paramComplex.imaginary());  
  42.   }  
  43.   
  44.   public Complex multiply(Complex paramComplex)  
  45.   {  
  46.     return new Complex(this.real * paramComplex.real() - (this.imaginary * paramComplex.imaginary()), this.real * paramComplex.imaginary() + this.imaginary * paramComplex.real());  
  47.   }  
  48.   
  49.   public Complex divide(Complex paramComplex)  
  50.   {  
  51.     float f1 = paramComplex.real() * paramComplex.real() + paramComplex.imaginary() * paramComplex.imaginary();  
  52.     float f2 = (this.real * paramComplex.real() + this.imaginary * paramComplex.imaginary()) / f1;  
  53.     float f3 = (this.imaginary * paramComplex.real() - (this.real * paramComplex.imaginary())) / f1;  
  54.   
  55.     return new Complex(f2, f3);  
  56.   }  
  57.   
  58.   public String toString()  
  59.   {  
  60.     String str = (this.imaginary >= 0.0F) ? "+" : "-";  
  61.     return this.real + str + Math.abs(this.imaginary) + "i";  
  62.   }  
  63. }  
牛顿分形的算法代码如下:

[java]  view plain copy
  1. package com.gloomyfish.fractal;  
  2.   
  3. public class NewtonFractal extends Fractal {  
  4.     private static final Complex ONE = new Complex(1.0F, 0.0F);  
  5.     private static final Complex THREE = new Complex(3.0F, 0.0F);  
  6.     public NewtonFractal(int widthImage, int heightImage) {  
  7.         super(widthImage, heightImage);  
  8.           
  9.         // default start point and end point  
  10.         // primary group,   
  11.         this.x1 = -1.0f;  
  12.         this.y1 = -1.0f;  
  13.         this.x2 = 1.0f;  
  14.         this.y2 = 1.0f;  
  15.           
  16.         // second group  
  17.         //  this.x1 = -3.0f;  
  18.         //  this.y1 = -1.76f;  
  19.         //  this.x2 = 3.0f;  
  20.         //  this.y2 = 1.76f;  
  21.         // end comment  
  22.           
  23.     }  
  24.   
  25.     @Override  
  26.     public void BuildFractal() {  
  27.         int[] inPixels = new int[getWidth()*getHeight()];  
  28.         getRGB(fractalImage, 00, getWidth(), getHeight(), inPixels );  
  29.         int index = 0;  
  30.         float xDelta = ((x2 - x1) / (float)width);  
  31.         float yDelta = ((y2 - y1) / (float)height);  
  32.         for(int row=0; row<height; row++) {  
  33.             int ta = 0, tr = 0, tg = 0, tb = 0;  
  34.             for(int col=0; col<width; col++) {  
  35.                 Complex localComplex2;  
  36.                 float f1 = this.x1 + col * xDelta;  
  37.                 float f2 = this.y2 - (row * yDelta);  
  38.                 Complex localComplex1 = new Complex(f1, f2);  
  39.   
  40.                 int k = 0;  
  41.                 do {  
  42.                   Complex localComplex3 = localComplex1.multiply(localComplex1);  
  43.                   Complex localComplex4 = localComplex3.multiply(localComplex1);  
  44.   
  45.                   localComplex2 = localComplex1;  
  46.                   localComplex1 = localComplex1.subtract(localComplex4.subtract(ONE).divide(THREE.multiply(localComplex3)));  
  47.                 }  
  48.   
  49.                 while ((++k < MAX_ITERS) && (!(localComplex1.equal(localComplex2))));  
  50.   
  51.                 int l = 20 * k % 10// keep value scope between 0 and 255  
  52.   
  53.                 // if root is 1 then  
  54.                 if (localComplex1.real() > 0.0F)  
  55.                 {  
  56.                     tr = tg = l;  
  57.                     tb = 255;  
  58.                 }  
  59.                   
  60.                 // if root is second complex = -0.5+0.87i  
  61.                 else if (localComplex1.imaginary() > 0.0F)  
  62.                 {  
  63.                     tr = tb = l;  
  64.                     tg = 255;  
  65.                 }  
  66.                 else  
  67.                 {  
  68.                   tr = 255;  
  69.                   tg = tb = l;  
  70.                 }  
  71.                   
  72.                 index = row * width + col;  
  73.                 ta = 255;  
  74.                 inPixels[index] = (ta << 24) | (tr << 16) | (tg << 8) | tb;  
  75.             }  
  76.         }  
  77.         setRGB(fractalImage, 00, getWidth(), getHeight(), inPixels);  
  78.     }  
  79.   
  80. }  
曼德尔波特分形算法如下:

[java]  view plain copy
  1. package com.gloomyfish.fractal;  
  2.   
  3. public class MandelbrotSetFractal extends Fractal {  
  4.     private float delta = 0.01f;  
  5.     public MandelbrotSetFractal(int widthImage, int heightImage) {  
  6.         super(widthImage, heightImage);  
  7.         this.delta = 0.01F;  
  8.         this.x1 = (-(this.width / 2) * this.delta);  
  9.         this.y1 = (-(this.height / 2) * this.delta);  
  10.         this.x2 = (-this.x1);  
  11.         this.y2 = (-this.y1);  
  12.     }  
  13.   
  14.     @Override  
  15.     public void BuildFractal() {  
  16.         int[] inPixels = new int[getWidth()*getHeight()];  
  17.         getRGB(fractalImage, 00, getWidth(), getHeight(), inPixels );  
  18.         int index = 0;  
  19.         for(int row=0; row<height; row++) {  
  20.             int ta = 0, tr = 0, tg = 0, tb = 0;  
  21.             float f1 = y2 - (row * delta);  
  22.             for(int col=0; col<width; col++) {  
  23.                 float f5;  
  24.                 int i1;  
  25.                 float f2 = x1 + col * delta;  
  26.                 Complex localComplex1 = new Complex(f2, f1);  
  27.                 Complex localComplex2 = new Complex(0.0F, 0.0F);  
  28.   
  29.                 int k = 0;  
  30.                 int l = 0;  
  31.                 do  
  32.                 {  
  33.                   localComplex2 = localComplex2.multiply(localComplex2).add(localComplex1);  
  34.                   f5 = localComplex2.modulus();  
  35.                   k = (f5 > 2.0F) ? 1 : 0; }  
  36.                 while ((++l < 32) && (k == 0));  
  37.   
  38.                 index = row * width + col;  
  39.                 if (k != 0) {  
  40.                   i1 = 255 - (255 * l / 32);  
  41.                   i1 = Math.min(i1, 240);  
  42.                   tr = tg = tb = i1;  
  43.                 }  
  44.                 else  
  45.                 {  
  46.                   i1 = (int)(100.0F * f5) / 2 + 1;  
  47.   
  48.                   int i2 = 101 * i1 & 0xFF;  
  49.                   int i3 = 149 * i1 & 0xFF;  
  50.                   int i4 = 199 * i1 & 0xFF;  
  51.                   tr = i2;  
  52.                   tg = i3;  
  53.                   tb = i4;  
  54.                 }  
  55.                   
  56.                 ta = 255;  
  57.                 inPixels[index] = (ta << 24) | (tr << 16) | (tg << 8) | tb;  
  58.             }  
  59.         }  
  60.         setRGB(fractalImage, 00, getWidth(), getHeight(), inPixels);  
  61.     }  
  62.   
  63. }  
递归分形树代码如下:

[java]  view plain copy
  1. package com.gloomyfish.fractal;  
  2.   
  3. import java.awt.BorderLayout;  
  4. import java.awt.Color;  
  5. import java.awt.Dimension;  
  6. import java.awt.Font;  
  7. import java.awt.FontFormatException;  
  8. import java.awt.Graphics;  
  9. import java.awt.Graphics2D;  
  10. import java.awt.RenderingHints;  
  11. import java.io.IOException;  
  12. import java.io.InputStream;  
  13. import java.util.Date;  
  14.   
  15. import javax.swing.JComponent;  
  16. import javax.swing.JFrame;  
  17.   
  18. public class FractalTree extends JComponent {  
  19.       
  20.     /** 
  21.      *  
  22.      */  
  23.     private static final long serialVersionUID = 8812325148970066491L;  
  24.   
  25.     private int maxRecursions = 8//never make this too big or it'll take forever  
  26.     private double angle = 0.2 * Math.PI; //angle in radians  
  27.     private double shrink = 1.8//relative size of new branches  
  28.     public FractalTree() {  
  29.         super();  
  30.     }  
  31.     protected void paintComponent(Graphics g) {  
  32.         Graphics2D g2 = (Graphics2D) g;  
  33.         g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);  
  34.         g2.setPaint(Color.WHITE);  
  35.         g2.fillRect(00400400);  
  36.         renderTree(g2);  
  37.         g2.setPaint(Color.RED);  
  38.         try {  
  39.             g2.setFont(loadFont());  
  40.         } catch (FontFormatException e) {  
  41.             // TODO Auto-generated catch block  
  42.             e.printStackTrace();  
  43.         } catch (IOException e) {  
  44.             // TODO Auto-generated catch block  
  45.             e.printStackTrace();  
  46.         }  
  47.         g2.drawString("Created by Gloomyfish " + new Date(System.currentTimeMillis()), 10320);  
  48.     }  
  49.       
  50.     /** 
  51.      * create fractal tree using recursion 
  52.      * @param Graphics2D g2 
  53.      */  
  54.     private void renderTree(Graphics2D g2) {  
  55.         g2.setPaint(new Color(1289664));  
  56.         recursion(400.0d / 2.0d, 400.0d -1.0d, 0.0d, -1.0d, 400.0d / 2.3d, 0, g2);  
  57.     }  
  58.       
  59.     // http://www.cg.info.hiroshima-cu.ac.jp/~miyazaki/knowledge/teche31.html  
  60.     void recursion(double posX, double posY, double dirX, double dirY, double size, int n, Graphics2D g2)  
  61.     {  
  62.         int x1, x2, y1, y2;  
  63.         x1 = (int)posX;  
  64.         y1 = (int)posY;  
  65.         x2 = (int)(posX + size * dirX);  
  66.         y2 = (int)(posY + size * dirY);  
  67.         g2.drawLine(x1, y1, x2, y2);  
  68.   
  69.         if(n >= maxRecursions) return;  
  70.         double posX2, posY2, dirX2, dirY2, size2;  
  71.         int n2;  
  72.           
  73.         // calculate the new start point coordinate  
  74.         posX2 = posX + size * dirX;  
  75.         posY2 = posY + size * dirY;  
  76.         size2 = size / shrink; // make different length of line.  
  77.         n2 = n + 1;  
  78.           
  79.         // rotate angle and get the new directX, directY  
  80.         // http://www.jimloy.com/geometry/trigz.htm  
  81.         // sin(theta + angle) = sin(theta) * cos(angle) + cos(theta) * sin(angle)  
  82.         // cos(theta + angle) = -sin(angle) * sin(theta) + cos(theta) * cos(angle)  
  83.         dirX2 = Math.cos(angle) * dirX + Math.sin(angle) * dirY;  
  84.         dirY2 = -Math.sin(angle) * dirX + Math.cos(angle) * dirY;  
  85.         recursion(posX2, posY2, dirX2, dirY2, size2, n2, g2);  
  86.           
  87.         dirX2 = Math.cos(-angle) * dirX + Math.sin(-angle) * dirY;  
  88.         dirY2 = -Math.sin(-angle) * dirX + Math.cos(-angle) * dirY;  
  89.         recursion(posX2, posY2, dirX2, dirY2, size2, n2, g2);  
  90.     }  
  91.       
  92.     /** 
  93.      * http://en.wikipedia.org/wiki/Mandelbrot_set 
  94.      * http://www.urbanfonts.com/fonts/sans-serif-fonts.htm 
  95.      * @return 
  96.      * @throws FontFormatException 
  97.      * @throws IOException 
  98.      */  
  99.     public Font loadFont() throws FontFormatException, IOException{  
  100.         String fontFileName = "AMERSN.ttf";  
  101.         InputStream is = this.getClass().getResourceAsStream(fontFileName);  
  102.         Font actionJson = Font.createFont(Font.TRUETYPE_FONT, is);  
  103.         Font actionJsonBase = actionJson.deriveFont(Font.BOLD, 12);  
  104.         return actionJsonBase;  
  105.     }  
  106.       
  107.     public static void main(String[] args) {  
  108.         JFrame frame = new JFrame("Fractal Tree UI - GloomyFish");  
  109.         frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);  
  110.         frame.getContentPane().setLayout(new BorderLayout());  
  111.           
  112.         // Display the window.  
  113.         frame.getContentPane().add(new FractalTree(), BorderLayout.CENTER);  
  114.         frame.setPreferredSize(new Dimension(450,400));  
  115.         frame.pack();  
  116.         frame.setVisible(true);  
  117.     }  
  118. }  
相关文章
|
2月前
|
算法 Java 编译器
【递归算法】斐波那契变形问题(C/C++)
【递归算法】斐波那契变形问题(C/C++)
|
6月前
|
算法 Java
二叉树递归分形,牛顿分形图案
二叉树递归分形,牛顿分形图案
43 0
|
7月前
|
JavaScript
【leetcode】221. 最大正方形 动态规划法
【leetcode】221. 最大正方形 动态规划法
28 0
|
7月前
|
算法 Java 测试技术
【广度优先搜索】【网格】【割点】1263. 推箱子
【广度优先搜索】【网格】【割点】1263. 推箱子
C++ 绘制圣诞树 (找规律 多层循环)
C++ 绘制圣诞树 (找规律 多层循环)
782 0
|
算法
【LeetCode】移动零&&颜色分类&&有序数组的平方&&有效的山脉数组
【LeetCode】移动零&&颜色分类&&有序数组的平方&&有效的山脉数组
【LeetCode】移动零&&颜色分类&&有序数组的平方&&有效的山脉数组
洛谷P3194 [HNOI2008]水平可见直线(计算几何+单调栈)
洛谷P3194 [HNOI2008]水平可见直线(计算几何+单调栈)
111 0
洛谷P3194 [HNOI2008]水平可见直线(计算几何+单调栈)
进阶指南图论——闇の連鎖 I. 黑暗的锁链(树上差分+LCA)
进阶指南图论——闇の連鎖 I. 黑暗的锁链(树上差分+LCA)
190 0