Draw a curve with multiple colors in C#

[colors]

It’s easy enough to draw different lines with different colors but it’s not as easy to draw a single line that uses multiple colors.

One way to accomplish that is to make a LinearGradientBrush that defines the colors that you want to use. You can then use the brush to define a pen and then draw with the pen.

This example assumes you’re drawing a graph and you want the colors to vary vertically. The brush is defined so its colors change vertically across the drawing coordinates with red at the top and blue at the bottom.

The following code shows how the example draws its curve.

private void picCanvas_Paint(object sender, PaintEventArgs e)
{
    e.Graphics.SmoothingMode = SmoothingMode.AntiAlias;

    RectangleF world_rect = new RectangleF(0, 0, 100, 100);
    RectangleF device_rect = new RectangleF(5, 5,
        picCanvas.ClientSize.Width - 10,
        picCanvas.ClientSize.Height - 10);
    SetTransformation(e.Graphics, world_rect, device_rect,
        false, true);

    // Draw the axes.
    using (Pen pen = new Pen(Color.Black, 0))
    {
        for (int y = 10; y < 100; y += 10)
            e.Graphics.DrawLine(pen, -2, y, 2, y);
        e.Graphics.DrawLine(pen, 0, 0, 0, 100);

        for (int x = 10; x < 100; x += 10)
            e.Graphics.DrawLine(pen, x, -2, x, 2);
        e.Graphics.DrawLine(pen, 0, 0, 100, 0);
    }

    // Make a brush for the curve.
    using (LinearGradientBrush brush =
        new LinearGradientBrush(world_rect,
            Color.Red, Color.Blue, 270))
    {
        ColorBlend blend = new ColorBlend();
        blend.Colors = new Color[]
        {
            Color.Red,
            Color.Orange,
            Color.Yellow,
            Color.Green,
            Color.Blue,
        };
        blend.Positions =
            new float[] { 0.0f, 0.2f, 0.4f, 0.6f, 1.0f, };
        brush.InterpolationColors = blend;

        // Make a thick pen defined by the brush.
        using (Pen pen = new Pen(brush, 3))
        {
            pen.LineJoin = LineJoin.Bevel;

            // Draw the curve.
            if (chkCurved.Checked)
                e.Graphics.DrawCurve(pen, Points);
            else
                e.Graphics.DrawLines(pen, Points);
        }
    }
}

The code sets the Graphics object’s SmoothingMode property and uses the SetTransformation method described in this post to map drawing coordinates to device coordinates. It then draws some axes.

Next the code creates a LinearGradientBrush that shades vertically from red to blue. The parameter 270 indicates that the brush shades from top-to-bottom.

After it creates the basic brush, the code gives it a new ColorBlend to define the brush’s colors and their positions within the brush. For example, the color red appears 0.0 of the way through the brush, orange appears 0.2 of the way through the brush, and so forth.

Note that the ColorBlend must have the same number of colors as positions and that the positions must start with 0.0 and end with 1.0.

The code then sets the brush’s InterpolationColors property equal to the ColorBlend to make it use the colors.

Next the program uses the brush to create a pen. The pen is 3 units wide in drawing coordinates and is scaled by the Graphics object’s transformation.

Note that I made the PictureBox square and the drawing area square so the transformation scales by the same amount in the X and Y directions. If the drawing and device coordinates had different shapes, the pen would be scaled unevenly and would give odd results.

Finally the code draws lines connecting some points defined in the form’s Load event handler.

Note that the brush repeats itself if necessary. For example, if a line extended past drawing coordinate 100 vertically, it would “fall off” of the red top of the brush and the brush would start over with blue. Similarly if a value dropped below 0 vertically, it would drop off the blue bottom of the brush and be drawn with red.

To prevent that the code sets the pen’s LineJoin property to Bevel so there are not very long points. The form’s Load event handler also doesn’t generate points with Y coordinates close to 0 or 100.

Alternatively you could extend the brush farther above and below the drawing area, making the top areas red and the bottom areas blue.

You can use a similar method to make a pen with a PathGradientBrush, although getting the result you want might be trickier depending the exact effect you want. Unfortunately I don’t know of a way to make a pen vary its colors along its length.


Download Example   Follow me on Twitter   RSS feed   Donate




About RodStephens

Rod Stephens is a software consultant and author who has written more than 30 books and 250 magazine articles covering C#, Visual Basic, Visual Basic for Applications, Delphi, and Java.

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

One Response to Draw a curve with multiple colors in C#

  1. Pingback: Draw a curve with sharply delineated colors in C# - C# HelperC# Helper

Leave a Reply

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