문제

I've been working recently on a fractal generator, and have been specifically working on the Mandelbrot set. Unfortunately, zooming and moving seems to be very inneficient and takes quite a while to refresh. I am generating it every time I zoom, and I know this is probably not the most efficient way of doing this, and I can't seem to find code that uses another method that I understand. These are the following methods I use, the first being an intial generation, the second being a refresh method.

    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.");
}
도움이 되었습니까?

해결책

I suppose that cells is some kind of List implementation?

In that case, the most time of your refresh method is spent in this line:

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

More precisely in cells.indexOf(c), where the entire list is iterated to find the correct index of c.

Since you are just changing the colour of each cell, the easiest fix is to change the colour of the cell you are currently working with. I don't know the actual implementation of your Cell class, but if it had a method setColor(...), you could replace the above line with

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

This reduces the runtime of the refreshMandelbrot method to the same as for the genMandelbrot method.

I don't know the purpose of the Cell class, but if you are only using it as a wrapper for a colour, you might gain some more performance if you store the computed colours for each pixel in a two-dimensional array or write directly to a Graphics or Raster object instead of handling a flat list of cell wrappers.

다른 팁

Most likely you need to subdivide the fractal and compute the less interesting tiles less intense. 8000 repetiton is a lot. You can also simplify the calculation a bit.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top