Reputation: 194
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.");
}
Upvotes: 1
Views: 637
Reputation: 34313
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.
Upvotes: 1
Reputation: 12592
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.
Upvotes: 0