How to create a good fractal zoom?

Hi!
I created a mandelbrot set explorer, with which, you can zoom into the fractal if you use the mouse wheel. But I can’t seem to get the mouse wheel zoom working correctly. What can I do to fix it?

Right now, both zoom and position shift aren’t working smoothly and can behave weirdly. I tried using mouse selection to zoom, but it worked even worse. Do you have any ideas / examples I could look at?

My current code
PGraphics gen;
int iter = 250;
color clr[] = new color[iter];
float scale = 200;

float offx=0,offy=0;
int genQ, lq = 10;

boolean useSquare = true;

void setup() {
  size(600,600);
  //fullScreen();
  colorMode(HSB);
  rectMode(CORNERS);
  float m = 0.95;
  for(int i = 0; i < iter; i++) clr[i] = color(pow(m,i)*255,255,255);
  clr[iter-1] = #000000;
  gen = createGraphics(width,height);
  stroke(255);
  strokeWeight(3);
  offx = width*0.5;
  offy = height*0.5;
  
  generate(iter);
}
void draw() {
  image(gen,0,0);
  if(frameCount%100==0 && genQ < iter) {
    generate(iter);
  }
}
void generate(int q) {
  genQ = q;
  
  gen.beginDraw();
  gen.loadPixels();
  
  for(int i = 0; i < width; i++) for(int j = 0; j < height ; j++) {
    complex point = getPosC(i,j,offx,offy,scale);
    complex mover = new complex(point.re, point.im);
    int it;
    for(it=0; it < q-1 && inBounds(mover); it++) {
      mover.setValueC(z2pc(mover,point));
    }
    gen.pixels[i+j*width] = clr[it];
  }
  gen.updatePixels();
  gen.endDraw();
}

void mouseWheel(MouseEvent event) { //HERE
  float e = -event.getCount();
  
  float mox = (width*0.5-mouseX)/(width*0.5), moy = (height*0.5-mouseY)/(height*0.5);
  
  //offx-=(mouseX-width*0.5)*0.25*e;
  //offy-=(mouseY-height*0.5)*0.25*e;
  
  offx+=mox*abs(mox)*width*e;
  offy+=moy*abs(moy)*height*e;
  
  if(e>0) {
    scale*=1.1;
  } else {
    scale/=1.1;
  }
  generate(lq);
}


boolean inBounds(complex c) {
  if(useSquare) return( abs(c.re)<2 && abs(c.im)<2 );
  else return( pow(c.re,2)+ pow(c.im,2) < 4 );
}


//COMPLEX NUMBERS--------------------------------------------------------------------------------
class complex {
  float re, im;
  complex(float re, float im) {
    this.re = re;
    this.im = im;
  }
  void setValue(float re, float im) {
    this.re = re;
    this.im = im;
  }
  void setValueC(complex c) {
    this.re = c.re;
    this.im = c.im;
  }
}
//COMPLEX CALCULATIONS ----------------------------------------------------------------------
complex csum(complex z, complex w) {
  return new complex(z.re+w.re,z.im+w.im);
}
complex cmult(complex z, complex w) {
  return new complex(w.re*z.re - w.im*z.im, w.re*z.im + z.re * w.im);
}
complex csq(complex z) {
  return cmult(z,z);
}
complex z2pc(complex z, complex c) { //z^2+c
  return csum(csq(z),c);
}
//VALUE ASSIGNMENT ---------------------------------------------------------------------------
complex getPosC(float x, float y, float xoff, float yoff, float scl) {
  return new complex((x-xoff)/scl,(y-yoff)/scl);
}

1 Like