Hello everyone!
After a long time of struggling with the scroll to zoom feature, I finally made it! This program can zoom into the mandelbrot set with huge accuracy. The largest zoom is 10^-17. That means that for every pixel we move on the screen, the coordinate changes by 10^-17. Beyond that, double reaches it’s limits and this appears:
I am still trying to shift the values used by double, so instead of using: x&y offset mostly between -2 and 2, and shift it into something like -2 * 10^6 and 2 * 10^6. Well it will take a while so for now, I will share this!
And this is just one of the infinite voyages the mandelbrot set offers!
I haven’t added a limit to iterations when unzoomed, so it lags quite a bit. Try to avoid black areas, since they take the longest to calculate.
I’ll try to add a drag feature, as well as a control center so you don’t need to do everything with scrolling. Well enjoy!
Code
int iter = 64*3;
double offx = -2, offy=-1.5, scale=1.0/200.0;
color clr[] = new color[64]; //how many colors, excluding black. Any additional color just loop around
color inside = #000000;
double zoom = 0.9;
void setup() {
size(600,600);
colorMode(HSB);
for(int i = 0; i < 64; i++) clr[i] = color(i*4,255,255);
}
void mouseWheel(MouseEvent event) {
float e = -event.getCount();
float x = (float)mouseX/(float)width, y = (float)mouseY/(float)height;
double px = x*(1-zoom)*width*e, py = y*(1-zoom)*height*e;
offx+=px*scale;
offy+=py*scale;
if(e<0) scale/=zoom;
else if(e>0) scale*=zoom;
println(scale,1/scale);
}
void draw() {
loadPixels();
for(int i = 0; i < width; i++) for(int j = 0; j < height; j++) {
complex c = getPosC((float)i,(float)j,offx,offy,scale), z = new complex(c.re,c.im);
int it = 0;
boolean loop = true;
for(it = 0; it < iter-1 && loop; it++) {z.setValue(z2pc(z,c)); if(inBounds(z)==false) loop = false;}
//if(i==mouseX&&j==mouseY) println(it);
pixels[i+j*width] = (it==iter-1? inside : clr[it%63]);
}
updatePixels();
if(mousePressed) getPosC(mouseX,mouseY,offx,offy,scale).printC();
}
boolean inBounds(complex c) {
return(c.re*c.re+c.im*c.im<4);
}
class complex {
double re, im;
complex(double re, double im) {
this.re=re;
this.im=im;
}
void setValue(complex c) {
re = c.re;
im = c.im;
}
void printC() {
println(re+" + "+im+"i");
}
}
//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, double xoff, double yoff, double scl) {
return new complex(xoff+x*scl,yoff+y*scl);
}
If you are curious how I made the zoom work, use this for reference:
Code
float zoom = 0.9;
void setup() {
size(600,600);
stroke(255); noFill();
}
void draw() {
background(0);
float x = mouseX, y = mouseY;
float nW = (float)width*zoom;
float nx = map(x,0,width,0,1), ny = map(y,0,height,0,1);
float px = nx*(width-nW), py = ny*(height-nW);
float npx = px+nW*nx, npy = py + nW*ny;
circle(npx,npy,5);
rect(px,py,nW,nW);
}
I am trying to make the mouse be on the same point even after zoom. I used desmos as inspiration and did all of the coding to mimic the zoom. After hours of failing, I finally succeeded, but I had to recode the entire program again.
So far, zoom is asymetric, so zooming out after zooming in doesn’t yield the same result. I will try to fix this in the next version.
Enjoy!