0

I am basically drawing a line representing a water flow. I want to give the user an approximation of the temperature of the water by coloring it from 100% blue to 100% red. I though; That's very simple, i'm done in 2 minuts.. Two hours later I'm looking at very advanced color system when all I need is something very simple.

I'm making a WinForm and using System.Drawing together with a Pen:

Pen Pen1 = new Pen(Color.FromArgb(0, 0, 0, 0), 2);

I was hoping to make a function with inputs (Double) from -1 to 1 with this output Color something like

Public Color TemperatureRange(double BlueToRed)
    {

     Color MyColor = new Color();
     byte a, r, g, b;

     //Insert math function that take from -1 to 1 and
     //produces and argb-output ranging from blue to red

     MyColor = Color.FromArgb(a, r, g, b);

     return MyColor;
    }
Mobz
  • 344
  • 1
  • 16
  • Do you mean [gradient](https://learn.microsoft.com/en-us/dotnet/framework/winforms/advanced/using-a-gradient-brush-to-fill-shapes)? I found [here](https://graphicdesign.stackexchange.com/q/100917) a question with some math. – Sinatr Jan 23 '19 at 10:15

2 Answers2

1

Here is a naive linear RGB scaling method:

public Color TemperatureRange(double value)
{
    // start = blue = #0000FF
    // end = red = #FF0000
    // range [-1; 1]
    var r = (int)(0xff * (value + 1) / 2);
    var g = 0;
    var b = (int)(0xff * (1 - value) / 2);
    return Color.FromArgb(r, g, b);
}

In the middle it will produce Color.Purple (#800080).

The "more correct" version should deal with HSL. You will need conversion methods, I've used this class and then it could be something like:

public Color TemperatureRange(double value)
{
    if (value < 0)
    {
        // blue range
        var max = new ColorRGB(Color.Blue);
        var color = ColorRGB.FromHSL(max.H, max.S * (-value), max.L);
        return Color.FromArgb(color.R, color.G, color.B);
    }
    else
    {
        // red range
        var max = new ColorRGB(Color.Red);
        var color = ColorRGB.FromHSL(max.H, max.S * value, max.L);
        return Color.FromArgb(color.R, color.G, color.B);
    }
}

In the middle it produces some kind of gray color (demo is made by ScreenToGif):

Sinatr
  • 20,892
  • 15
  • 90
  • 319
1

If you want the middle color be green try this.

public static Color TemperatureRange(double BlueToRed)
{
    double r, g, b;

    // blue to cyan
    if (BlueToRed < -0.5)
    {
        r = 0;
        g = 2 + BlueToRed * 2;
        b = 1;
    }

    // cyan to green
    else if (BlueToRed < 0)
    {
        r = 0;
        g = 1;
        b = -BlueToRed * 2;
    }

    // green to yellow
    else if (BlueToRed < 0.5)
    {
        r = BlueToRed * 2;
        g = 1;
        b = 0;
    }

    // yellow to red
    else
    {
        r = 1;
        g = 2 - BlueToRed * 2;
        b = 0;
    }

    return Color.FromArgb((int)(r * 255), (int)(g * 255), (int)(b * 255));
}
shingo
  • 18,436
  • 5
  • 23
  • 42