2013-03-21 3 views
1

Я недавно работал над фрактальным генератором и специально работал над множеством Мандельброта. К сожалению, масштабирование и перемещение, по-видимому, очень малоэффективны и требуют довольно много времени для обновления. Я генерирую его каждый раз, когда я увеличиваю масштаб, и я знаю, что это, вероятно, не самый эффективный способ сделать это, и я не могу найти код, который использует другой метод, который я понимаю. Это следующие методы, которые я использую, причем первое из них - это начальное поколение, второе - метод обновления.Мандельброт очень медленный, чтобы освежить, любой способ сделать это быстрее?

private void genMandelbrot(Dimension size) { 
    for(int x=0;x<size.width;x++) { 
     for(int y=0;y<size.height;y++) { 
      double moveX=globalx; 
      double moveY=globalx; 
      //zoom and x/y offset. 
      double real = 1.5 * (x - size.width/2)/(0.5 * zoom * size.width) + moveX; 
      double imaginary=(y - size.height/2)/(0.5 * zoom * size.height) + moveY; 
      double newRe=0,newIm=0,oldRe=0,oldIm=0; 

      int i; 
      for(i=0;i<8000;i++) { 
       oldRe = newRe; 
       oldIm = newIm; 
       newRe = oldRe * oldRe - oldIm * oldIm + real; 
       newIm = 2 * oldRe * oldIm + imaginary; 
       if((newRe * newRe + newIm * newIm) > 4) break; 
      } 

      Cell c = new Cell(Color.getHSBColor(i % 256, i % 255, 255 * ((i<20)? 1:0)), new Dimension(1,1), new Point(x,y)); 
      cells.add(c); 
     } 
    } 
} 
public void refreshMandelbrot(Dimension size) { 
    for(Cell c : cells) { 
      double moveX=globalx; 
      double moveY=globalx; 
      int x=c.x; 
      int y=c.y; 
      //zoom and x/y offset. 
      double real = 1.5 * (x - size.width/2)/(0.5 * zoom * size.width) + moveX; 
      double imaginary=(y - size.height/2)/(0.5 * zoom * size.height) + moveY; 
      double newRe=0,newIm=0,oldRe=0,oldIm=0; 

      int i; 
      for(i=0;i<8000;i++) { 
       oldRe = newRe; 
       oldIm = newIm; 
       newRe = oldRe * oldRe - oldIm * oldIm + real; 
       newIm = 2 * oldRe * oldIm + imaginary; 
       if((newRe * newRe + newIm * newIm) > 4) break; 
      } 

      cells.set(cells.indexOf(c), new Cell(Color.getHSBColor(i % 256, i % 255, 255 * ((i<20)? 1:0)), new Dimension(1,1), new Point(x,y))); 
    } 
    System.out.println("Set refreshed."); 
} 
+0

Профиль перед тем, как попытаться оптимизировать. Где больше всего времени тратится? – MrSmith42

ответ

1

Я полагаю, что cells - это какая-то List реализация?

В этом случае большую часть времени вашего метода обновления проводится в этой строке:

cells.set(cells.indexOf(c), new Cell(Color.getHSBColor(i % 256, i % 255, 255 * ((i<20)? 1:0)), new Dimension(1,1), new Point(x,y)));

Более точно в cells.indexOf(c), где весь список итерированного, чтобы найти правильный индекс c.

Поскольку вы просто меняете цвет каждой ячейки, самым простым решением является изменение цвета ячейки, с которой вы в настоящее время работаете. Я не знаю, фактической реализации Вашего Cell класса, но если это был метод setColor(...), вы могли бы заменить эту строку с

c.setColor(Color.getHSBColor(i % 256, i % 255, 255 * ((i<20)? 1:0)));

Это уменьшает время выполнения метода refreshMandelbrot к тому же, как для метод genMandelbrot.

Я не знаю цель класса Cell, но если вы используете его только как оболочку для цвета, вы можете получить более высокую производительность, если вы храните вычисленные цвета для каждого пикселя в двумерном массив или записать непосредственно в объект Graphics или Raster вместо обработки плоского списка клеточных оберток.

0

Скорее всего, вам необходимо разделить фрактал и вычислить менее интересные плитки, менее интенсивные. 8000 повторений много. Вы также можете немного упростить вычисление.

Смежные вопросы