2015-04-16 17 views
5

Fraktallerle büyük bir ilgim var ancak yakın zamana kadar bunları uygulama fırsatı bulamadım. Önce siyah ve beyaz bir mandelbrot seti uyguladıktan sonra renk eklemeyi denedim. İşte Mandelbrot setine renk katmanları ekleniyor

bunu çizildikten sonra

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(); 
    } 

} 

Ben setini görüntülemek için özel Görüntüleyici sınıfını kullanıyorum (Ben karmaşık sayılar için org.apache.commons.math3.complex.Complex kullanıyorum) benim Mandelbrot en uygulamasıdır bir görüntü nesnesi. İşte Görüntüleyici

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()); 
} 

kodu doğru render kümesi ancak beklediğim sonucu elde etmiyorum kümesi yöntemidir. İstediğim bu

beautiful mandelbrot

için renkli bir dizi benzer üretmeye muktedir olduğunu Ya da bu

Beautiful mandelbrot II

Ama bundan daha iyi bir renkli set alamadı.

not very beautiful mandelbrot

Ben here ve here ilgili bazı teorik açıklama okudum ama açıkçası pratikte yanlış bir şey yapıyorum. Renklendirme yaklaşımımın nesi yanlış? Bunu nasıl düzeltebilirim? Teşekkürler

cevap

3

Gösterdiğiniz örneklerde, renk, noktadan önceki yineleme sayısına dayanır ve ilk karmaşık koordinat z0 üzerinde değildir.

 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); 

kod yukarıdaki doygunluğunu veya parlaklığını değişmez: o kaçmadan önce bir yaklaşım örneğin getHSBColor() kullanarak Ton-Doygunluk-Parlaklık renk değerlerini kullanmak ve tekrarlamalar sayısına dayalı tonu değiştirmektir (her ikisi de 1.0'a ayarlıdır), ancak ne tür bir etkiye sahip olduğunuza bağlı olarak bunları da değiştirebilirsiniz.

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

Ayrıca belirli bir renk başlamak yapmak için sürekli ekleyebilirsiniz:

Bir sabit örneğin tarafından ton değeriyle çarpılmasıyla tonlar renk çemberin defadan fazla içinden renk döngüsü yapabiliriz .

escapeIterations bir int olduğundan, renk her yineleme için adım adım atlayacaktır. maksimum yukarı yinelemenin bir renk tablosu, her biri için birini kullanmak,

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

Son olarak renkler üzerinde en fazla özgürlük ve kontrol verecektir başka bir yaklaşım olduğunu: Sen numberOfIterationsToCheck bir şamandıra döndürerek renkleri pürüzsüzleştirebilirim ve isteğe bağlı olarak aralarında enterpolasyon yapın.

+0

Cevabınız için teşekkür ederiz. – alainlompo

+0

en kısa sürede başvuru yapacağım, bunu bir dakika içinde uygulayayım ve – alainlompo

+0

geri döneceğim, bu mükemmel! – alainlompo