Some days ago I was thinking how to make deep Mandelbrot zoom to run in real time. We already have shallow low-res zooms running in real time, but deep zooms require more and more iterations per pixel, so unfortunately our only way to work around this seems to be to precompute zoom in some way, and then make whole thing to appear as if it was running in real time, i.e. make it interactive. Obvious way to do this would be to seek in zoom video, but what’s the fun in that? Instead, I was looking for some way to zoom in single image, CSI style.
What I originally came up with was simple r→rp transformation that produced results similar to spherize filter: multiple scales of same area were combined in a single image. Then, applying inverse transform in realtime would allow to reconstruct any scale within encoded scale range. This worked, but ultimately proved itself to be very inefficient. So I was back to the drawing board, looking for more efficient transform. It turned out to be well–known trick: polar coords with radius in log scale. This way, I was finally able to do smooth interactive zoom of Google map all the way down to my house in decent quality within wonderfl 500KB image size limit!
Wait, Google map? What about Mandelbrot thing? Well, Anders Sandberg happened to post a lot of log scale Mandelbrot maps on flickr for their aesthetic quality, so I just plugged those in my script, and – presto! I wish they were in higher resolution.
Fuck Mandelbrot – how did you do Google map one?
The key thing to know here is that every zoom step in Google map actually doubles the resolution, so what you do is just snap array of screenshots made while zooming to your point of interest and then use log2 (max (|x|, |y|)) to select a screenshot to read a color for (x,y) from. If you have loads of time, you may want to edit every screenshot to add transparency, and blend all of screenshots together instead to have highest quality composite.
Fuck Google map – where’s the code for this?
Here you go, lazy boy:
<languageVersion : 1.0;>
kernel Zoomer
< namespace : "experimental";
vendor : "makc";
version : 2;
description : "logarithm image zoomer";
>
{
input image4 map;
output pixel4 dst;
parameter float map_height
<
minValue:float(10.0);
maxValue:float(10000.0);
defaultValue:float(1000.0);
>;
parameter float map_width
<
minValue:float(10.0);
maxValue:float(10000.0);
defaultValue:float(1000.0);
>;
parameter float dst_half_side
<
minValue:float(10.0);
maxValue:float(1000.0);
defaultValue:float(232.5);
description:"square images for now";
>;
parameter float map_scale
<
minValue:float(10.0);
maxValue:float(1000.0);
defaultValue:float(200.0);
description:"where zoom level doubles?";
>;
parameter float zoom
<
minValue:float(0.0);
maxValue:float(1.0);
defaultValue:float(1.0);
>;
void
evaluatePixel()
{
float2 c = outCoord () / dst_half_side - float2(1.0, 1.0); // -1 to 1
dst = sampleLinear(map, float2 (
(0.5 + atan (c.y, c.x) / 6.2831853) * (map_width -1.0),
clamp ( -map_scale * log2 (length (c) * zoom), 0.0, map_height -1.0)
));
}
}



impressive what you’re up to when it comes to proving that fractals don’t look like shit ;)
good one, very neat tricks, will doubtlessly prove useful.
keep up :)
Pretty cool stuff. I dig it. Keep up the good work.
excellent work here! Ive never even heard about log scale maps until this post. This code will come in handy.
Great demo! But the most puzzling to me is, how do you generate the log-scale polar coordinate image map?
It’s very simple, for every pixel you pick radius and angle (the formula is exact reverse of the one in PB kernel above), and then you use polar-to-cartesian transform to get good old x and y – from here, finding color of pixel should be straightforward.
Quite simple for anyone good at math…I presume you wrote a script to create that image, any chance to see it?? *curious* (I’m a lazy mortal…with no math skills)
Man, that was almost a year ago, of course I don’t have that script by now.
No worries, just really liked the look of that map and was thinking if running some animation through the process.
Thanks for taking the time to reply!
Cheers //O.
why is there no sound?
Most useful…and in one word: AWESOME :)