开发者

to dynamically increment from blue to red using C++

开发者 https://www.devze.com 2022-12-11 02:06 出处:网络
I want to change the color Blue to Dark Red over a set of know values (like Temperature values for instance).

I want to change the color Blue to Dark Red over a set of know values (like Temperature values for instance). I don't know how to dynamically count up to Blue to Red.

Can anyone help me out?

I never took an algorithms class s开发者_开发技巧o I think that might have something to do with this problem.

If you have a better way to do this, then let me know.

I am looking for some kind of code here. Thanks guys. It can be in any language but will inevitably be converted to C++.


A simple linear alpha-blending function could look like this:

float blend(float a, float b, float alpha)
{
  return (1.f - alpha) * a + alpha * b;
}

This will interpolate from a to b as alpha> goes from 0 to 1.

If you were to use this for each of the red, green and blue components that make up a typical color value, you could get the desired effect:

struct Color
{
  float r, g, b;
};

Color color_blend(const Color *a, const Color *b, float alpha)
{
  struct Color x;

  x.r = blend(a->r, b->r, alpha);
  x.g = blend(a->g, b->g, alpha);
  x.b = blend(a->b, b->b, alpha);

  return x;
}

This is a bit C-ish for brevity; feel free to reformulate and use classes of course.


Colours are usually specified as quantities of red, green and blue light. For most purposes, 8-bit resolution in each colour component (red, green, or blue) is sufficient.

So you might have a colour struct like this:

typedef unsigned char uint8;

struct Colour
{
    uint8 red;
    uint8 green;
    uint8 blue;

    Colour(uint8 r, uint8 g, uint8 b) : red(r), green(g), blue(b) {}
};

then you can make colours once you understand the RGB colour model. For your example colours, this is pretty easy:

Colour Red(255, 0, 0);
Colour Blue(0, 0, 255);

Let's say you want to change from blue to red over 100 steps (or 100 seconds, or whatever). You simply increment each component from the source value to the target value, so in your case, blue to red would be:

  • Red: 0 to 255
  • Green: 0 to 0
  • Blue: 255 to 0

So the red component is faded up to full intensity as you move to red, and the blue component is faded down to zero.

Some simple code to do this:

// Fade from blue to red
Colour Source(0, 0, 255);  // blue
Colour Target(255, 0, 0);  // red

Colour MyColour = Source;

const int NumSteps = 100;

for (int i = 0; i <= NumSteps; i++)
{
  MyColour.red   = Source.red   + (((Target.red   - Source.red)   * i) / NumSteps);
  MyColour.green = Source.green + (((Target.green - Source.green) * i) / NumSteps);
  MyColour.blue  = Source.blue  + (((Target.blue  - Source.blue)  * i) / NumSteps);

  // Do something, like update the display
  DoSomethingWithColour(MyColour);
}

This will fade MyColour from blue to red. Note that this will fade through the RGB colour space.

There are other colour spaces, such as HLS and HSV, and fading through those colour spaces will give different effects. For example, halfway through the RGB fade above the colour will be RGB(128, 0, 128), which is purple. If you fade through the HSV space, the hue component will fade from red to purple to blue, so in this case it is the same. However, if you choose different colours, you may get different effects depending on which colour space you use.


I think to get the effect you want (I assume you want a colour gradient) you would get better results converting RGB to HSV, then interpolate between the start and end HSV values. The RGB representation is suited to how colours get displayed, but the HSV (Hue, Saturation, Value) representation is closer to how colours are perceived. See the wikipedia article for the HSV <-> RGB conversion formula.


The C++ language by itself doesn't have any built-in support for colors. This is typically provided by the graphics libraries you use, which themselves are often dependent on your operating system, windowing environment, etc. For example, a C++ program running on Windows and using the base Win32 SDK will treat colors differently than a C++ program using the Carbon framework on OS X. It would be much easier to answer your question if you provided these details.

Having said all that, it's quite likely that whatever libraries you use represent colors in some form of RGB notation, where you have a structure with a separate value, often 0-255, for the red, green, and blue components of your color. One simple approach you could use to move gradually from Blue to Red would be to progressively reduce the blue value while simultaneously increasing the red value.

So, if you started with {R, G, B} = {0, 0, 255} (all blue), you could move in steps like this:

{10, 0, 245} {20, 0, 235} {30, 0, 225} ... ... {255, 0, 0} (all red)

The actual function calls to set the color of your display/button/window/etc. will be part of your graphics library documentation. Good luck!


Other posters have answered this question sufficiently for the general case of blending from one colour to the next. I just want to point out that the blue to red colourmap is interpreted wrong by most humans, by which I mean that depending on where you are on the colourmap the same difference in value between two neighbouring colours looks like a different difference (heh) to a human. A colourmap that is almost as easy as the blue to red clourmap but is interpreted somewhat better by humans is the black -> red -> yellow -> white colourmap. Use blending code from above examples to scale your values linearly over:

RGB (0,0,0) (black, start of your scale)
RGB (255,0,0) (red, 1/3rd through your scale)
RGB (255,255,0) (yellow, 2/3rds through your scale)
RGB (255,255,255) (white, upper end of your scale)

This colourmap gets progressively brighter as you get to higher values, so the change in colour is more obvious, and it also allows for more steps (768 versus 256 in the blue-red map), so you can see and show more resolution.

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号