I started a thread on 2D coloring, then spent most of my time describing a 1D coloring method. So I am forking the thread with a new appropriate title. This post is a follow up of
https://fractalforums.org/fractal-mathematics-and-new-theories/28/2d-coloring/2745/msg13948#msg13948 TL;DR summary:
If f(z,c) is a continuous fractal generating formula, z
i or more properly z
i(c) are the iterations for parameter space value c, N is the max iteration cutoff value, and R is a good escape radius, that is \( |z_i|>R, j>i => |z_j| > R \). Then \( \sum_{i=0}^{N}\max(R-|z_i|,0) \) is a continuous function \( \mathbb{C \rightarrow R} \), and so suitable for use in a smooth coloring algorithm.
I choose R-|z
i| originally because both these values are readily available during the fractal calculation. Actually the proof only requires \[ (1) |z| \geq R => g_1(z)=0 \]
If g
1 satisfies condition (1) then \( \sum_{i=0}^{N}g_1(z_i) \) is continuous.
Consider the more relaxed condition \[ (2) |z| \geq R => g_1(z) \leq 0 \]\[ (3)g_1(z)=\max(g_2(z),0) \]
If g
2 satisfies (2) the g
1 defined by (3) satisfies condition (1). To reduce verbosity, in what follows when I define a function can call it g
2, it satisfies condition (2) and it defines a companion function g
1 via (3).
The function in the last post, \( g_2(z)=R-|z| \), is heavily depends on the value or R. If you are working on an image, then changing R will really mess up your colors.
\( g_2(z)=1-|z|/R \) works much better. It still depends on R, but the color changes due to changes in R are more subtle. Note that \( 0 \leq g_1(z) \leq 1 \). If n is the iteration where the orbit escapes then summation is in the range \( 0 \leq \sum_{i=0}^{N}g_1(z_i) \leq n \). This is starting to look like an iteration count. In fact for large R the summation starts to approach the iteration count step function. Of course, that is what we are trying to avoid. Still it is nice to know that R is a dial we can turn where one extreme is the familiar iteration count.
Both of these examples have \( |z|<R => g_1(z)>0 \). Which kind of complements condition (1). Don't be fooled, it is not necessary. Purists may object to relaxing this condition. It was already blasphemy to not give each iteration its full count value of 1, now some pre-escape steps in the iteration may contribute nothing, or horrors! even negatively to computation. Well you know I am not a purist, this is just another artistic tool to add to the tool box.
\( g_2(z)=1-|z|/R_1 \, where \, R_1 \leq R \). Now the radius that contributes to the summation is smaller, potentially much smaller than the escape radius. Small values for R
1 tends to put stronger emphasis, and direct viewer focus on points close to the fractal boundary. Again an artistic consideration not necessarily a mathematical one.
Variations on absolute value are possible. set z = x + iy
\[ g_2(z)=1-(|x|+|y|)/R_1\\
g_2(z)=1-\max(|x|,|y|)/R_1\\
g_2(z)=1-| |z| - a | / R_1 \, where \, a + R_1 <= R
\]
The first is a filled in diamond, the second is a filled in square, the third, if a > R
1 is a circle of radius a and width R
1. Generally these choices only make subtle differences in the final image. If you do something extreme, like fractal formula is f(z,c) = c, and iteration count is 1, then you will see the shapes described, fuzzy around the edges. Each formula has a personality, but they look nothing like the single-iteration shape.
You can move the center \( g_2(z)=1-| z - c_0 | / R_1 \, where \, c_0 \in \mathbb{C}, |c_0| + R_1 <= R \). There are obvious similar variations for the other functions. Moving the center like this creates some asymmetry in the coloring. The colors are different on different sides of a feature in the image, often creating a shadowing like effect. Don't push this too far, displacing the coloring center too much results in disconnected splotches rather than subtle shading effects.
Want more functions? Let g
1 be any function that satisfies (1). Let h be any function mapping \( \mathbb{C \rightarrow R} \). Any function at all, really, no restrictions. Then h
1(z) = g(z) * h(z) satisfies condition (1) and can be used for continuous colors. Go wild! But make sure your color palette can handle negative numbers.
Sometimes, for functions defined by (3), you get bands where \( g_2(z_i) = 0 \) for some z
i in the orbit. If you look closely the color change is actually continuous but the gradient changes sharply. The problem is the derivative is not continuous. Mathematics define different levels of smoothness. C
0 is the class of continuous functions, C
1 is the class of continuously differentiable functions. See
https://en.wikipedia.org/wiki/Smoothness.
Derivatives, at least in high school calculus, are for functions \( \mathbb{R \rightarrow R} \, or \, \mathbb{C \rightarrow C} \). Our functions are \( \mathbb{C \rightarrow R} \). But let's discard mathematical rigor for now and pretend we can differentiate these functions. (If you insist on rigor, consider g as \( g:\mathbb{R^2 \rightarrow R} \) and look at the partial derivatives.)
Assume g
2 is differentiable, that is, \( g_2 \in C^1 \). g
1(z) = max(g
2(z),0) is continuous, but in general not differentiable. The derivative is discontinuous when g
2(z) = 0. (or undefined, or two-sided, or whatever it is a bad deal)
This is easily fixed. \( h_1(z) = g_1(z)^2 \) is differentiable. Both side of the derivative is 0 where g
2(z)=0. So \( h_1 \in C^1 \).
You can attain any level of smoothness. If \( g_1 \in C^2 \, then \, h_2(z) = g_1(z)^3 \in C^2 \), etc.
Linkback: https://fractalforums.org/fractal-mathematics-and-new-theories/28/smooth-1d-coloring/2753/