229 lines
6.3 KiB
MQL5
229 lines
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
|
||
|
//+------------------------------------------------------------------+
|