2015-04-16 51 views
5

我对分形有很大的兴趣,但直到最近才有机会实现它们。我第一次实现了一个黑色和白色的mandelbrot,然后我试着给它添加颜色。将颜色层添加到mandelbrot集

这里是我的天壤之别的实现(我用org.apache.commons.math3.complex.Complex用于复数)

public class MyMandelbrot { 

    public static int numberOfIterationsToCheck(Complex z0, int max) { 
     Complex z = z0; 
     for (int t = 0; t < max; t++) { 
      if (z.abs() > 2.0) return t; 
      z =z.multiply(z).add(z0); 
     } 
     return max; 
    } 

    public static void main(String[] args) { 
     double xc = Double.parseDouble(args[0]); 
     double yc = Double.parseDouble(args[1]); 
     double size = Double.parseDouble(args[2]); 

     int N = 512; 
     int max = 255; 

     Viewer viewer = new Viewer(N, N); 
     for (int i = 0; i < N; i++) { 
      for (int j = 0; j < N; j++) { 
       double x0 = xc - size/2 + size*i/N; 
       double y0 = yc - size/2 + size*j/N; 
       Complex z0 = new Complex(x0, y0); 
       int gray = max - numberOfIterationsToCheck(z0, max); 

       Color color = new Color(gray, gray, gray); 
       if (z0.abs() > 2.0) { 

        color = new Color(gray, 128, gray); 
       } else if (z0.abs() > 2.0 && numberOfIterationsToCheck(z0,  max) > max/2) { 
        color = new Color(255, gray, 255); 
       } else if (z0.abs() > 2.0 && numberOfIterationsToCheck(z0,  max) < max/2) { 
        color = new Color(gray, 128,128); 
       } 

       else if (z0.abs() > 1.0 && numberOfIterationsToCheck(z0,  max) < max/2) { 
        color = new Color(128, gray, 128); 
       } else if (z0.abs() > 1.0) { 

        color = new Color(128, gray, 128); 
       } 

       else if (z0.abs() <= 1.0) { 
        color = new Color(gray, gray, 128); 
       } 

       viewer.set(i, N-1-j, color); 
      } 
     } 
     viewer.show(); 
    } 

} 

我使用一个自定义浏览器类,以查看集绘图之后一个图像对象。这里是查看器的设置方法

public void set(int col, int row, Color color) { 
    if (col < 0 || col >= width()) throw new IndexOutOfBoundsException("col must be between 0 and " + (width()-1)); 
    if (row < 0 || row >= height()) throw new IndexOutOfBoundsException("row must be between 0 and " + (height()-1)); 
    if (color == null) throw new NullPointerException("can't set Color to null"); 
    if (isOriginUpperLeft) image.setRGB(col, row, color.getRGB()); 
    else     image.setRGB(col, height - row - 1, color.getRGB()); 
} 

代码正确渲染集,但我没有获得预期的结果。我要的是能够产生有色一套类似于这些

beautiful mandelbrot

或者这

Beautiful mandelbrot II

但我不能得到较好的有色集莫过于此。

not very beautiful mandelbrot

我看了一下它herehere一些理论框架的解释,但我明明做错事的做法。我的着色方法有什么问题?我该如何解决它?谢谢

回答

3

在你显示的例子中,颜色只是基于点转义之前的迭代次数,而不是初始的复坐标z0。一种方法是使用getHSBColor()使用色调 - 饱和度 - 亮度的颜色值,并改变基于迭代次数的色相它逸出之前,例如:

 double x0 = xc - size/2 + size*i/N; 
     double y0 = yc - size/2 + size*j/N; 
     Complex z0 = new Complex(x0, y0); 
     int escapeIterations = numberOfIterationsToCheck(z0, max); 

     // set color varying hue based on escape iterations: 
     Color color = Color.getHSBColor((float)escapeIterations/(float)max, 1.0f, 1.0f); 

     viewer.set(i, N-1-j, color); 

上面的代码不改变饱和度或亮度(两者都设置为1.0),但是您可以根据您想要的效果来改变它们。

你可以通过一个常数例如色调值乘以使色彩循环色调的彩色圆圈不止一次:

(float)escapeIterations * 2.0f/(float)max 

您还可以添加一个常数,使其开始在特定的颜色。

因为escapeIterations是一个int类型,所以每次迭代时颜色将跳步跳跃。你可以使色彩更为顺畅从numberOfIterationsToCheck返回一个float:

public static float numberOfIterationsToCheckSmooth(Complex z0, int max) { 
    Complex z = z0; 
    for (int t = 0; t < max; t++) { 
     double fAbs = z.abs(); 
     if (fAbs > 2.0) 
     { 
      // based on the final value, add a fractional amount based on 
      // how much it escaped by (fAbs will be in the range of 2 to around 4):     
      return (float)t + (2.0f - (Math.log(fAbs)/Math.log(2.0))); 
     } 
     z =z.multiply(z).add(z0); 
    } 
    return (float)max; 
} 

最后,另一种方法是将给予最大的自由度和控制的颜色是使用的颜色的表格,每一个迭代了最大,并可选择在它们之间进行插值。

+0

谢谢你的答案。我会尽快申请 – alainlompo

+0

好吧,让我在一分钟内申请,我会回来 – alainlompo

+0

谢谢,这很好! – alainlompo