A quadratic Julia set with both basins of attraction colored by smoothed iterations.
Freely redistributable and usable subject to the Creative Commons Attribution license, version 3.0.
Detailed statistics:
Name: Dragon
Date: February 4, 2009
Fractal: Julia set
Location:
c = -0.7875 + 0.0875
iDepth: Shallow
Min Iterations: 1
Max Iterations: 894
Layers: 2
Anti-aliasing: 3x3, threshold 0.10, depth 1
Preparation time: 5 minutes
Calculation time: 30 seconds (2GHz dual-core Athlon XP)
Some technical info on the interior coloring:
Dissatisfied with the performance, for this and other images, of the existing algorithms for smoothed iterations in convergent basins, I did something especially simple.
I noted that approach to an attracting (but not superattracting) fixed point tends to spiral in in a very regular way once it gets close -- the difference from the attractor point tending to multiply by a near-constant complex number smaller in magnitude than 1:
Here, the large black dot is the attractor and the small black dots and small blue dots are two orbits. The larger and paler red circle is the target disk; the point at its center, marked with a black X, is not exactly at the attractor but is some point close to the attractor discovered by forward iterating the critical point and waiting for the cycle detector to trip.
If one colors simply by iterations, both points get a 3, since the third iteration lands inside the disk. This gives sharp bands, with the disk itself as the centermost one.
It occurred to me, however, that besides how many steps it took to hit the disk, one could also use the proportion of the distance out from the center of the disk that the point landed. If it landed near the center, it got very close to the attractor in only three iterations; if it landed near the edge, it took "nearly" four iterations. So my first naive refinement made the fractional part of the iteration the ratio of the distance from the X to the disk radius.
This didn't work very well -- the resulting "smoothed iteration" values would creep up from 2.8 say to 3.0 and then jump to 3.8. The exact point of the jump, here .8, also depended on the Julia seed in a non-obvious way. Then I considered: most of the points close to the center of the disk are not reached in a single jump from outside the disk. The disk's own image under the mapping is a smaller disk (darker red) within it, and points that lie outside the larger disk land, in one iteration, outside the smaller disk. So it is not how far out the point landed from the X to the edge of the disk; it is how far from the inner disk's edge to the outer disk's edge that counts.
In the diagram, the blue point's third iteration lands close to the inner disk but the black point does not; the black point's next iteration lands close to the outside of the inner disk, but inside it.
If the blue point had been a little closer to the attractor, its third iteration would have landed just inside the inner disk instead of just outside, and its second
iteration would have been just inside the outer disk. That blue point should only be a 2.1 or so, not a 2.8.
But how is the inner disk's radius to be determined? I considered two extra iterations of the black point. One lands just inside the inner disk; one lands even closer to the attractor (points 4 and 5 in the diagram). The ratio of the distances spanned by these successive jumps should be close to the ratio of the disk radii. And this lets the inner disk radius be determined from the outer one by the same ratio. Call this ratio the "
x-factor" for that particular attractor. (It is related to the derivative of the map at the fixed point.)
This worked much better: all of the iteration values from 3.0001 to 3.9999 now occurred. However, they were not distributed as one would wish; the iteration dropped rapidly from nearly 4 to only 3.2 or so within a few pixels of the outer edge of the iteration-3 band and then from 3.2 to 3 more slowly over the bulk of the band's width.
The next insight was to consider where 3.5 should really occur between 3 and 4. The 4-band was about an
x-factor wider than the 3-band, so if we split the bands in two, the half-width bands should get wider in steps of the square root of the
x-factor. In particular, the band between the outer and inner target disks should be divided up similarly, with .5 being not halfway between but
sqrt(
x) between.
Generalizing this to any proportion, it becomes any power -- a fractional part of .5 should occur at
x.5 of the way out, a fractional part of .3 at
x.3; basically, the linear distance's base
x logarithm had to be used for the fractional part instead of just the linear distance.
This worked beautifully in the basins of fixed points! It failed if the fixed point was superattracting (but there the standard smoothed iterations algorithm works beautifully) and it failed if the attractor was a cycle of period 2 or greater.
Fixing cycles was slightly tricky. First, only successive points that approached the same point within the attractor could be used to determine the inner-disk radius. So instead of just taking the next two iterations, I modified the code to iterate until it landed within the target disk again and note that as the "second" iteration, then do it again until it landed within the target disk a third time and note that as the "third" iteration. For a period-two attractor like the one in
Dragon I, the points skip back and forth between two spirals converging on the two points of the attractor. Imagine the diagram above, but with a second copy elsewhere without the red disks and with points 1.5, 2.5, 3.5, and so on, and the orbit going from point 1 to 1.5 to 2 to 2.5 and so on. In this case, every second point lands back within the outer disk, instead of every point.
With this modification, however, there was still distinct banding of the basins. I debugged by drawing a grey gradient for the fractional part, and saw that the fractional part was banding as it should, going from 1 down to 0, 1 down to 0 repeatedly as one approached the attractor. The fractional part was being calculated correctly. It had to be the integer part that was causing the problem, and indeed it was: if it just missed the red disk on iteration 2, for instance, it would land within the target radius of the
other point in the 2-cycle (far from the X) on iteration 3 and only land inside the red disk on iteration 4. More generally, only once every period of the attractor did it get a chance to get "caught" in the red disk. So the integer part had to be not simply the number of iterations, but the floor of the number of iterations divided by the cycle period.
The same logic that calculated the successive points for the
x-factor calculation could calculate the period by counting iterations between successive landings within the target disk. With this final modification in place, and a detection of superattractors to fall back on the older smoothed-iteration algorithm in that case (in practise, the
x factor being over one thousand indicates that it's "close enough for government business" and the superattractor version gives good results, and below that the new algorithm gives good results), I got perfectly smooth gradients inside Julia set basins of every period, and also inside the buds of Mandelbrots.
Forthcoming in the next few days will be more images with stunning smooth-colored basins, Mandelbrot components, and similarly, based on the same mathematics described above.
I will probably also start grouping several images together in some posts to avoid crowding out other people's posts in the forum too much.