Color  

Robert P. Munafo, 2010 Sep 7.



For the purpose of this discussion there are two types of color drawing situations.

"Limited color" refers to the situation where there is some rather small number N of colors available (typically 256 or less) and you specify which color to use by giving a single number from 1 to N.

"Full color" refers to the situation where you specify the color to use by giving three separate numbers, specifying the color in terms of some kind of three-dimensional color space (like red-green-blue, or hue-saturation-luminance)

Limited Color

When working in limited color it is typical to pick a color from 1 to N based on the number of escape iterations of the point. If the number of iterations is less than N it can be used directly. If it is bigger than N you can pick a fixed "overflow" value, or use (iterations modulo N), which has the effect of cycling through the colors as many times as needed to cover all the possible iteration values.

Full Color

The best approach when working in full color is to treat your available colors as a two-dimensional or three-dimensional space and plot different attributes of the iterated point on each dimension. There are lots of possibilities; here are two examples:

Two dimensions of color: Two attributes of point: HUE _Escape Iterations_ BRIGHTNESS _Distance Estimate_   Three dimensions of color: Three attributes of point: HUE _Escape Iterations_ SATURATION Final point's _Angle_ BRIGHTNESS Final point's _Radius_

Both of these will produce fairly stunning results and of course there are dozens of other possible combinations.

One of the best ways to color the Mandelbrot Set uses the HSV color space. Use the Distance Estimator function for V and Escape-Iterations for H, and make S alternate between odd and even values of Escape-Iterations. The result is stunning.

It is much better to use the hue/saturation/brightness system rather than something like red/green/blue, because of the psychology and physiology of human vision. Most good graphics environments provide a function that converts from HSV to RGB; if your's doesn't, look it up in a book like Graphics Gems or Fundamentals of Interactive Computer Graphics.

For each dimension you want to translate the attribute to the dimension in such a way that you use the whole range, and use it evenly. For example, hue is expressed as an angle on the color wheel. To convert iterations to hue, I would recommend some sort of logarithmic function, so if it takes 20 iterations to go around the wheel the first time, it takes another 40 to go around the second time, then 80, then 160 and so on. Then, to preserve the appearance of stripes at all iterations, you could add 20 degrees to the angle if the iteration is odd. The resulting formula would look like this:

hue = (360 * log2(iterations)) modulo 360 if (iterations mod 2 = 1) then hue = (hue + 20) modulo 360

Algorithm Used in the Mu-Ency Illustrations

Most of the JPG and PNG images used to illustrate the Mu-Ency articles are colored using an algorithm similar to the following:

iterate to determine D using the continuous dwell method (see also escape-iterations) set dwell = floor(D) set finalrad = D - floor(D) (The floor function gives the integer part of D) compute angle of final coordinate of iteration and call it finalang (if the escape radius is big enough, this is also a fractional part of the external angle) compute distance estimate set dscale = log2(distance_estimate / pixel_spacing) if dwell exceeds iterations limit, skip all the following and plot a white point comment Convert the scaled distance estimate to a brightness (called "value" in the HSV color space) from 0.0 to 1.0 in 8 intervals. if dscale > 0 value = 1.0 else if dscale > -8 value = (8 + dscale)/8 else value = 0 comment Apply logarithmic scaling to the dwell. P = log(dwell)/log(100000) comment The following re-maps the range 0.0...1.0 onto an "angle" and "radius" on the color wheel. This color wheel has white in the center, pastel hues close to the center, and vivid colors around the edge of the wheel. In order to gain maximum use of all the available colors, we compute an angle and radius in a way that places the resulting points equally far apart from one another. The use of square root means that the radius increases more slowly as we move away from the center. Note also that the angle will be multiplied by a constant below, so we'll end up going around the wheel multiple times. if (P < 0.5) { P = 1.0 - 1.5*P angle = 1 - P radius = sqrt(P) } else { P = 1.5*P - 0.5 angle = P radius = sqrt(P) } comment The following makes every other "stripe" a bit lighter if dwell is odd { value = 0.85 * value radius = 0.667 * radius } comment The following breaks the stripes up into "squares" that make the external angles evident. Combined with the previous "stripe" operation, this gives the image a checkerboard-like appearance if finalang > π { angle = angle + 0.02 } comment The following turns each "square" into a rainbow-like gradient angle = angle + 0.0001 * finalrad comment The following makes every other "stripe" a bit lighter hue = angle * 10.0 hue = hue - floor(hue) saturation = radius - floor(radius) comment hue is now in the range 0.0...1.0. This represents a full circle (normally 0...2 π) convert (hue, saturation, value) to (red, green, blue) using standard HSV to RGB mapping

The intended benefits of this algorithm are:


See also algorithms, dithering, palette, representation functions.


revisions: 20100907 oldest on record; 20101213 fix a couple typos; add "intended benefits"




From the Mandelbrot Set Glossary and Encyclopedia, by Robert Munafo, (c) 1987-2013.     Mu-ency index
Robert Munafo's home pages on HostMDS   © 1996-2013 Robert P. Munafo.   about   contact   Google+   mrob27   @mrob_27

This work is licensed under a Creative Commons Attribution-NonCommercial 2.5 License. Details here s.11