• 二叉树递归分形,牛顿分形图案 分类: 视频图像处理 2015-07-24 10:16 50人阅读 评论(0) 收藏


    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一下

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

    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. }  
    牛顿分形的算法代码如下:

    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. }  
    曼德尔波特分形算法如下:

    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. }  
    递归分形树代码如下:

    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. }  

    版权声明:本文为博主原创文章,未经博主允许不得转载。

  • 相关阅读:
    docker-dockerfile构建与部署nginx
    淘宝镜像安装
    css3 中的变量 var 的使用
    CSS样式清除
    css 样式初始化(rem兼容)
    canvas截屏网页为图片下载到本地-html2canvas.js
    移除JSON对象中的某个属性
    js 常用方法集合(持续更新)
    小程序获取上个页面vm对象 解决百度小程序返回上一页不更新onShow更新(适用于uni-app)
    小程序 请求Promise简单封装
  • 原文地址:https://www.cnblogs.com/mao0504/p/4705518.html
Copyright © 2020-2023  润新知