Color Gradient Generator

November 12, 2013

A while back, I created a WPF Mandelbrot Set program with zoom abilities. I demonstrated the use of async/await for writing code that works asynchronously (to keep the UI responsive), but is easy to write as synchronous code. Here’s a sample image:

image

The image is grayscale, so I wanted to make it use colors, to indicate the level of “being part of” the Mandelbrot set. The problem here is how to create a nice color gradient that moves smoothly from color to color.

One possible option might be to leverage an existing class, such as WPF’s LinearGradientBrush, set up a bunch of gradient stops with the colors to be interpolated, and then extract a color in a specific offset as needed. There are two issues with this: the first is that LinearGradientBrush has no method to get the color at a specified offset, and second, I would rather create a generic algorithm that did not depend on a particular technology.

My goal would be to create a color gradient of some kind and apply it to the Mandelbrot set to get images such as the following:

image

image

image

image

There are several ways to do this, here I’ll describe one that works for me, and is not too complex to understand and implement.

The idea is to change the color based on a sine wave. This gives a nice smooth gradient effect (although it’s not linear, which is not a requirement anyway). By changing the frequency of the RGB components (we could theoretically work with other color spaces such as HSV) we can get various gradients. Also, we can also play with the phase of each color component, creating a “shifting” effect. The basic implementation of such a gradient can be implemented like so:

  1. public Color[] GenerateColors(int number) {
  2.     var colors = new List<Color>(number);
  3.     double step = MaxAngle / number;
  4.     for(int i = 0; i < number; ++i) {
  5.         var r = (Math.Sin(FreqRed * i * step + PhaseRed) + 1) * .5;
  6.         var g = (Math.Sin(FreqGreen * i * step + PhaseGreen) + 1) * .5;
  7.         var b = (Math.Sin(FreqBlue * i * step + PhaseBlue) + 1) * .5;
  8.         colors.Add(Color.FromRgb((byte)(r * 255), (byte)(g * 255), (byte)(b * 255)));
  9.     }
  10.     return colors.ToArray();
  11. }

Where the Freq* are the frequencies of the respective RGB colors and Phase* are the phase shift values. Note that all calculations are done with floating point numbers (ranging from 0.0 to 1.0), converting to a WPF Color structure (in this case) at the very end. This is simply convenient, as we’re working with trigonometric functions, which like floating point numbers rather than integers. The result is normalized to the range 0 to 1, as the sine function produces results from –1 to 1, so we add one to get a range of 0 to 2 and finally divide by 2 to get to the desired range.

To create nice gradients, a lot of trial and error is needed. To make things easier, I created a helper program that allows changing the aforementioned properties using sliders, getting an immediate feedback of the result. I also added an option to export the selected values to an XML file and vice versa for importing. Here are some screenshots of the tool:

image

image

The Size slider sets the number of color entries in the returned array, and the MaxAngle parameter effectively sets the number of sine cycles to use; or put another way, the rate in which the gradient changes.

The color gradient generator and the color based Mandelbrot set can be downloaded from the following link:

Async Mandelbrot Color

Add comment
facebook linkedin twitter email

Leave a Reply

Your email address will not be published.

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>

*