Draw a colorful color wheel in C#

[color wheel]

The example Draw a color wheel in C# draws a color wheel. To do that, it makes a series of points along the perimeter of a circle where each point has a different color of the rainbow. It then makes a PathGradientBrush with those colors as the surround colors. The center of the brush, which is white, is at the center of the circle. After it creates the brush, the program simply fills the circle.

The points along the circle include red, green, and blue. The other points interpolate between those colors. For example, halfway between red (255, 0, 0) and green (0, 255, 0) is the color (128, 128, 0), which is brown (dark yellow). The way that program performs its interpolation means the color wheel doesn’t include saturated secondary colors such as yellow (255, 255, 0).

This example uses six main colors instead of just three so it creates a brighter color wheel that includes the secondary colors.

The following code shows how the program draws the color wheel.

// Draw a color wheel in the indicated area.
private void DrawColorWheel(Graphics gr, Color outline_color,
    int xmin, int ymin, int wid, int hgt)
{
    Rectangle rect = new Rectangle(xmin, ymin, wid, hgt);
    GraphicsPath wheel_path = new GraphicsPath();
    wheel_path.AddEllipse(rect);
    wheel_path.Flatten();

    float num_pts = (wheel_path.PointCount - 1) / 6;
    Color[] surround_colors = new Color[wheel_path.PointCount];

    int index = 0;
    InterpolateColors(surround_colors, ref index,
        1 * num_pts, 255, 255, 0, 0, 255, 255, 0, 255);
    InterpolateColors(surround_colors, ref index,
        2 * num_pts, 255, 255, 0, 255, 255, 0, 0, 255);
    InterpolateColors(surround_colors, ref index,
        3 * num_pts, 255, 0, 0, 255, 255, 0, 255, 255);
    InterpolateColors(surround_colors, ref index,
        4 * num_pts, 255, 0, 255, 255, 255, 0, 255, 0);
    InterpolateColors(surround_colors, ref index,
        5 * num_pts, 255, 0, 255, 0, 255, 255, 255, 0);
    InterpolateColors(surround_colors, ref index,
        wheel_path.PointCount, 255, 255, 255, 0, 255, 255, 0, 0);

    using (PathGradientBrush path_brush =
        new PathGradientBrush(wheel_path))
    {
        path_brush.CenterColor = Color.White;
        path_brush.SurroundColors = surround_colors;

        gr.FillPath(path_brush, wheel_path);

        // It looks better if we outline the wheel.
        using (Pen thick_pen = new Pen(outline_color, 2))
        {
            gr.DrawPath(thick_pen, wheel_path);
        }
    }
}

The code creates a GraphicsPath, adds a circle to it, and flattens the path to get points along the circumference of the circle. It will later fill that path.

Using the flattened path’s points lets the program place the gradient’s surround colors exactly on the points used to draw the circle. The code divides the path points into six sections and uses the InterpolateColors method (described next) to assign colors to each section. It uses the returned colors to create the PathGradientBrush and fills the circle.

The following code shows the InterpolateColors method.

// Fill in colors interpolating between the from and to values.
private void InterpolateColors(Color[] surround_colors,
    ref int index, float stop_pt,
    int from_a, int from_r, int from_g, int from_b,
    int to_a, int to_r, int to_g, int to_b)
{
    int num_pts = (int)stop_pt - index;
    float a = from_a, r = from_r, g = from_g, b = from_b;
    float da = (to_a - from_a) / (num_pts - 1);
    float dr = (to_r - from_r) / (num_pts - 1);
    float dg = (to_g - from_g) / (num_pts - 1);
    float db = (to_b - from_b) / (num_pts - 1);

    for (int i = 0; i < num_pts; i++)
    {
        surround_colors[index++] =
            Color.FromArgb((int)a, (int)r, (int)g, (int)b);
        a += da;
        r += dr;
        g += dg;
        b += db;
    }
}

This method generates colors between a starting value and an ending value. It calculates the amount by which the colors’ alpha, red, green, and blue values must be increased to step across the desired range of colors.


Download Example   Follow me on Twitter   RSS feed   Donate




This entry was posted in drawing, graphics, image processing and tagged , , , , , , , , , , , . Bookmark the permalink.

3 Responses to Draw a colorful color wheel in C#

  1. Pingback: Draw a color wheel with alpha and saturation in C# - C# HelperC# Helper

  2. Tamori says:

    Thanks for the post. How would the code look like for WPF?

  3. RodStephens says:

    I don’t think WPF provides a PathGradientBrush (it only has LinearGradientBrush and RadialGradientBrush) so I don’t think this is easy. The simplest solution I can think of off hand would be to use the code in this example to draw the image on a bitmap and then display the bitmap in WPF.

Leave a Reply

Your email address will not be published. Required fields are marked *