2015-04-16 25 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