geforkt von airat77786/MQL5Book
228 Zeilen
6,3 KiB
MQL5
228 Zeilen
6,3 KiB
MQL5
//+------------------------------------------------------------------+
| |||
//| ColorMix.mqh |
| |||
//| https://www.mql5.com |
| |||
//+------------------------------------------------------------------+
| |||
| |||
//+------------------------------------------------------------------+
| |||
//| Color converters between RGB and HSV, color mixer and blender |
| |||
//+------------------------------------------------------------------+
| |||
namespace ColorMix
| |||
{
| |||
// handy local macros
| |||
// RGB bytes order 012 in uint, which is actually BGR
| |||
#define RGB(R,G,B) (color)((uint)(R) | ((uint)(G) << 8) | ((uint)(B) << 16))
| |||
#define CLR_R(C) ((C) & 0xFF)
| |||
#define CLR_G(C) (((C) >> 8) & 0xFF)
| |||
#define CLR_B(C) (((C) >> 16) & 0xFF)
| |||
| |||
//+------------------------------------------------------------------+
| |||
//| Convert Hue/Saturation/Value into color (RGB components) |
| |||
//| H = 0..360 (angle), S = 0..1, V = 0..1 |
| |||
//+------------------------------------------------------------------+
| |||
color HSVtoRGB(double H, double S = 1.0, double V = 1.0)
| |||
{
| |||
int r = 0, g = 0, b = 0;
| |||
| |||
if(S < 0 || S > 1) S = 1;
| |||
if(V < 0 || V > 1) V = 1;
| |||
| |||
if(S == 0.0)
| |||
{
| |||
r = (int)(V * 255);
| |||
g = (int)(V * 255);
| |||
b = (int)(V * 255);
| |||
}
| |||
else
| |||
{
| |||
if(H >= 360.0 || H < 0) H = 0.0;
| |||
else H /= 60;
| |||
int i = (int)H;
| |||
double f = H - i;
| |||
double m, n, k;
| |||
m = V * (1 - S);
| |||
n = V * (1 - S * f);
| |||
k = V * (1 - S * (1 - f));
| |||
| |||
switch(i)
| |||
{
| |||
case 0:
| |||
r = (int)(V * 255);
| |||
g = (int)(k * 255);
| |||
b = (int)(m * 255);
| |||
break;
| |||
case 1:
| |||
r = (int)(n * 255);
| |||
g = (int)(V * 255);
| |||
b = (int)(m * 255);
| |||
break;
| |||
case 2:
| |||
r = (int)(m * 255);
| |||
g = (int)(V * 255);
| |||
b = (int)(k * 255);
| |||
break;
| |||
case 3:
| |||
r = (int)(m * 255);
| |||
g = (int)(n * 255);
| |||
b = (int)(V * 255);
| |||
break;
| |||
case 4:
| |||
r = (int)(k * 255);
| |||
g = (int)(m * 255);
| |||
b = (int)(V * 255);
| |||
break;
| |||
case 5:
| |||
r = (int)(V * 255);
| |||
g = (int)(m * 255);
| |||
b = (int)(n * 255);
| |||
break;
| |||
}
| |||
}
| |||
return (color)RGB(r, g, b);
| |||
}
| |||
| |||
//+------------------------------------------------------------------+
| |||
//| Find max of 3 RGB components |
| |||
//+------------------------------------------------------------------+
| |||
int RGBmax(int R, int G, int B)
| |||
{
| |||
if(R > G)
| |||
{
| |||
if(R > B) return R;
| |||
else return B;
| |||
}
| |||
else
| |||
{
| |||
if(G > B) return G;
| |||
else return B;
| |||
}
| |||
}
| |||
| |||
//+------------------------------------------------------------------+
| |||
//| Find min of 3 RGB components |
| |||
//+------------------------------------------------------------------+
| |||
int RGBmin(int R, int G, int B)
| |||
{
| |||
if(R < G)
| |||
{
| |||
if(R < B) return R;
| |||
else return B;
| |||
}
| |||
else
| |||
{
| |||
if(G < B) return G;
| |||
else return B;
| |||
}
| |||
}
| |||
| |||
//+------------------------------------------------------------------+
| |||
//| Convert RGB color in Hue/Saturation/Value |
| |||
//| H = 0..360 (angle), S = 0..1, V = 0..1 |
| |||
//+------------------------------------------------------------------+
| |||
void RGBtoHSV(color rgb, double &H, double &S, double &V)
| |||
{
| |||
int r = CLR_R(rgb);
| |||
int g = CLR_G(rgb);
| |||
int b = CLR_B(rgb);
| |||
| |||
H = 0;
| |||
| |||
// determine the value (brightness)
| |||
V = RGBmax(r, g, b);
| |||
| |||
// determine saturation
| |||
double temp = RGBmin(r, g, b);
| |||
| |||
if(V == 0)
| |||
{
| |||
S = 0;
| |||
}
| |||
else
| |||
{
| |||
S = (V - temp) / V;
| |||
}
| |||
| |||
// determine the hue
| |||
if(S == 0)
| |||
{
| |||
H = 0;
| |||
}
| |||
else
| |||
{
| |||
double Cr, Cg, Cb;
| |||
Cr = (V - r) / (V - temp);
| |||
Cg = (V - g) / (V - temp);
| |||
Cb = (V - b) / (V - temp);
| |||
// the color is between yellow and magenta
| |||
if(r == V)
| |||
H = Cb - Cg;
| |||
// the color is between cyan and yellow
| |||
if(g == V)
| |||
H = 2 + Cr - Cb;
| |||
// the color is between magenta and cyan
| |||
if(b == V)
| |||
H = 4 + Cg - Cr;
| |||
// convert to degrees
| |||
H = 60 * H;
| |||
// prevent negative value
| |||
if(H < 0)
| |||
H += 360;
| |||
}
| |||
V /= 255;
| |||
}
| |||
| |||
//+------------------------------------------------------------------+
| |||
//| Construct a color (one of several grades) between 2 given colors |
| |||
//| using hue circle or linear manner |
| |||
//+------------------------------------------------------------------+
| |||
color RotateColors(const color clr1, const color clr2, const int gradeCount, const int i, const bool colourScheme = true)
| |||
{
| |||
color clr;
| |||
| |||
if(colourScheme)
| |||
{
| |||
double hh, s, v;
| |||
double h1, s1, v1;
| |||
double h2, s2, v2;
| |||
| |||
RGBtoHSV(clr1, h1, s1, v1);
| |||
RGBtoHSV(clr2, h2, s2, v2);
| |||
| |||
hh = h1 + ((h2 - h1) / (gradeCount)) * i;
| |||
s = s1 + ((s2 - s1) / (gradeCount)) * i;
| |||
v = v1 + ((v2 - v1) / (gradeCount)) * i;
| |||
if(hh < 0) hh += 360;
| |||
if(hh > 360) hh -= 360;
| |||
clr = HSVtoRGB(hh, s, v);
| |||
}
| |||
else
| |||
{
| |||
int r, g, b;
| |||
int r1 = CLR_R(clr1), g1 = CLR_G(clr1), b1 = CLR_B(clr1);
| |||
int r2 = CLR_R(clr2), g2 = CLR_G(clr2), b2 = CLR_B(clr2);
| |||
| |||
r = (int)(r1 + (((r2 - r1) / (1.0 * gradeCount)) * i));
| |||
g = (int)(g1 + (((g2 - g1) / (1.0 * gradeCount)) * i));
| |||
b = (int)(b1 + (((b2 - b1) / (1.0 * gradeCount)) * i));
| |||
clr = RGB(r, g, b);
| |||
}
| |||
| |||
return clr;
| |||
}
| |||
| |||
//+------------------------------------------------------------------+
| |||
//| Mix 2 colors linear manner |
| |||
//+------------------------------------------------------------------+
| |||
color BlendColors(const int col1, const int col2, const double a = 0.5)
| |||
{
| |||
int r1 = CLR_R(col1), g1 = CLR_G(col1), b1 = CLR_B(col1),
| |||
r2 = CLR_R(col2), g2 = CLR_G(col2), b2 = CLR_B(col2);
| |||
return RGB(r1 + a * (r2 - r1), g1 + a * (g2 - g1), b1 + a * (b2 - b1));
| |||
}
| |||
| |||
#undef RGB
| |||
#undef CLR_R
| |||
#undef CLR_G
| |||
#undef CLR_B
| |||
| |||
} // namespace ColorMix
| |||
//+------------------------------------------------------------------+
|