The function of decomposing color into shades. - page 13

 

Added. Check out this script.

 //+------------------------------------------------------------------+
//|                                              Gradient test 1.mq4 |
//|                                                      Peter Konow |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Peter Konow"
#property link        "https://www.mql5.com"
#property version    "1.00"
#include <Canvas\Canvas.mqh>
//+------------------------------------------------------------------+
//| Script program start function                                    |
//+------------------------------------------------------------------+
union rgb { uint clr; uchar c[ 4 ];};
rgb C,cc;
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
void OnStart ()
  {
   CCanvas canvas;
   if (!canvas.CreateBitmapLabel( "Gradient" , 200 , 200 , 768 , 256 , COLOR_FORMAT_ARGB_NORMALIZE )) { Print ( "Error creating canvas: " , GetLastError ()); }
   string Main_color = C'190,215,160' ;
   double d= 5 ;
   string Gradient[ 256 ];

   while (! IsStopped ())
     {
      C.c[ 2 ]= uchar ( 127.5 *( 1 + sin (d* 1.2 ))+ 0.4999 ); C.c[ 1 ]= uchar ( 127.5 *( 1 + sin (d* 1.9 ))+ 0.4999 ); C.c[ 0 ]= uchar ( 127.5 *( 1 + sin (d* 2.8 ))+ 0.4999 );   // генерируем новый цвет
      cc.clr=C.clr;
       ulong t= GetMicrosecondCount ();
      Диапазон_оттенков(C.clr,Gradient); //Диапазон_оттенков(Main_color,Gradient);
      t= GetMicrosecondCount ()-t;
       for ( int y= 0 ; y< 256 ; y++)
        {
         //Alert(__FUNCTION__,"  Gradient[",y,"]  ",Gradient[y]);
         canvas.LineHorizontal( 0 , 767 ,y, ColorToARGB ( StringToColor (Gradient[y]), 255 ));
         C.clr=Gradient[y];
         canvas.PixelSet(( int )C.c[ 2 ]+( int )C.c[ 1 ]+( int )C.c[ 0 ],y, ColorToARGB ( clrWhite ));
         if (C.c[ 1 ]> 0 ) canvas.PixelSet( int ( 50.0 *( int )C.c[ 2 ]/( double )C.c[ 1 ]+ 50.0 *( int )C.c[ 0 ]/( double )C.c[ 1 ]),y, ColorToARGB ( clrGreen ));
         if (C.c[ 2 ]> 0 ) canvas.PixelSet( int ( 50.0 *( int )C.c[ 1 ]/( double )C.c[ 2 ]+ 50.0 *( int )C.c[ 0 ]/( double )C.c[ 2 ]),y, ColorToARGB ( clrRed ));
         if (C.c[ 0 ]> 0 ) canvas.PixelSet( int ( 50.0 *( int )C.c[ 2 ]/( double )C.c[ 0 ]+ 50.0 *( int )C.c[ 1 ]/( double )C.c[ 0 ]),y, ColorToARGB ( clrBlue ));
        }
      canvas.FillRectangle( 500 , 75 , 660 , 150 , ColorToARGB (cc.clr, 240 ));
      canvas.FontSet( "Tahoma" , 20 ); 
      canvas. TextOut ( 510 , 85 , "R = " + string (cc.c[ 2 ]), ColorToARGB (~cc.clr)); 
      canvas. TextOut ( 510 , 107 , "G = " + string (cc.c[ 1 ]), ColorToARGB (~cc.clr)); 
      canvas. TextOut ( 510 , 129 , "B = " + string (cc.c[ 0 ]), ColorToARGB (~cc.clr));
      canvas.FontSet( "Times New Roman" , 15 );
      canvas. TextOut ( 300 , 10 , "Время формирования градиентного массива из 256 элементов = " + string (t)+ " микросекунд" , ColorToARGB ( clrWhite ));
      canvas.Update();
      d+= 0.01 ;
       Sleep ( 30 );
     }
   canvas.Destroy();
//------------------------
// for(int a1 = 0; a1 < 256; a1++)Alert(__FUNCTION__,"  Gradient[",a1,"]  ",Gradient[a1]);
  }
//+------------------------------------------------------------------+
//================================================================================================================================================================
void Диапазон_оттенков( color _Цвет, string &Все_оттенки[ 256 ])
{
 color R,G,B,q;
 //------------------------------------------------------
 string Этот_цвет;
 double Тангенс_угла_старшего_треугольника_1,      
        Тангенс_угла_среднего_треугольника_1,                  
        Тангенс_угла_младшего_треугольника_1,                       
        Значение_в_точке_преломления_старшей_компоненты,  
        Значение_в_точке_преломления_средней_компоненты,
        Значение_в_точке_преломления_младшей_компоненты,    
        Тангенс_угла_старшего_треугольника_2,
        Тангенс_угла_среднего_треугольника_2,    
        Тангенс_угла_младшего_треугольника_2;
 //------------------------------------------------------
 double pi = 3.1415926536 ,
        Comp_1,Comp_2,Comp_3,
         //-----------------------------------------------
        Первая_компонента,
        Вторая_компонента,
        Третья_компонента,
         //-----------------------------------------------
        Исходный_R = GetR(_Цвет), 
        Исходный_G = GetG(_Цвет),  
        Исходный_B = GetB(_Цвет),  
         //-----------------------------------------------
        Старшая_компонента         = Нужная_компонента(Исходный_R,Исходный_G,Исходный_B, 0 ), 
        Средняя_компонента         = Нужная_компонента(Исходный_R,Исходный_G,Исходный_B, 1 ), 
        Младшая_компонента         = Нужная_компонента(Исходный_R,Исходный_G,Исходный_B, 2 ), 
         //-----------------------------------------------
        Координата_исходного_цвета = Старшая_компонента/ tan (( 63.43989 *pi)/ 180 ) + Младшая_компонента/ 2 ; 
         //-----------------------------------------------
        
 //-----------------------------------------------
 if (Старшая_компонента == Исходный_R)R = Старшая_компонента;
 if (Старшая_компонента == Исходный_G)G = Старшая_компонента; 
 if (Старшая_компонента == Исходный_B)B = Старшая_компонента;     
 //------------------------
 if (Средняя_компонента == Исходный_R)R = Средняя_компонента;
 if (Средняя_компонента == Исходный_G)G = Средняя_компонента; 
 if (Средняя_компонента == Исходный_B)B = Средняя_компонента; 
 //------------------------
 if (Младшая_компонента == Исходный_R)R = Младшая_компонента;
 if (Младшая_компонента == Исходный_G)G = Младшая_компонента; 
 if (Младшая_компонента == Исходный_B)B = Младшая_компонента;     
 //==========================================================================================
 if (Координата_исходного_цвета <= 127 )
   {
    Тангенс_угла_старшего_треугольника_1  = Старшая_компонента/Координата_исходного_цвета;
    Тангенс_угла_среднего_треугольника_1  = Средняя_компонента/Координата_исходного_цвета;     
    Тангенс_угла_младшего_треугольника_1  = Младшая_компонента/Координата_исходного_цвета;
     //-----------------------------------------------
    Значение_в_точке_преломления_старшей_компоненты  = Тангенс_угла_старшего_треугольника_1* 128 ;
    Значение_в_точке_преломления_средней_компоненты  = Тангенс_угла_среднего_треугольника_1* 128 ;
    Значение_в_точке_преломления_младшей_компоненты  = Тангенс_угла_младшего_треугольника_1* 128 ;    
     //-----------------------------------------------    
    Тангенс_угла_старшего_треугольника_2  = ( 255 - Значение_в_точке_преломления_старшей_компоненты)/ 128 ;
    Тангенс_угла_среднего_треугольника_2  = ( 255 - Значение_в_точке_преломления_средней_компоненты)/ 128 ;       
    Тангенс_угла_младшего_треугольника_2  = ( 255 - Значение_в_точке_преломления_младшей_компоненты)/ 128 ;
     //-----------------------------------------------    
     for ( int a1 = 0 ; a1 < 128 ; a1++)
      {
       Comp_1 = Тангенс_угла_старшего_треугольника_1*a1;
       Comp_2 = Тангенс_угла_среднего_треугольника_1*a1;
       Comp_3 = Тангенс_угла_младшего_треугольника_1*a1;
       //---------------------------------------------------
       if (Comp_1 > 255 )Comp_1 = 255 ;
       if (Comp_1 > 255 )Comp_2 = 255 ;
       if (Comp_1 > 255 )Comp_3 = 255 ;
       if (Comp_1 < 0 )Comp_1 = 0 ; //добавлено
       if (Comp_2 < 0 )Comp_2 = 0 ; //добавлено
       if (Comp_3 < 0 )Comp_3 = 0 ; //добавлено           
       //---------------------------------------------------
       if (R == Старшая_компонента)Первая_компонента = Comp_1;
       if (R == Средняя_компонента)Первая_компонента = Comp_2;
       if (R == Младшая_компонента)Первая_компонента = Comp_3;
       //---------------------------------------------------
       if (G == Старшая_компонента)Вторая_компонента = Comp_1;
       if (G == Средняя_компонента)Вторая_компонента = Comp_2;
       if (G == Младшая_компонента)Вторая_компонента = Comp_3;
       //---------------------------------------------------
       if (B == Старшая_компонента)Третья_компонента = Comp_1;
       if (B == Средняя_компонента)Третья_компонента = Comp_2;
       if (B == Младшая_компонента)Третья_компонента = Comp_3;
       //---------------------------------------------------
       Этот_цвет = ( string ) MathRound (Первая_компонента) + "," + ( string ) MathRound (Вторая_компонента) + "," + ( string ) MathRound (Третья_компонента);
       //---------------------------------------------------------------------------    
       Все_оттенки[a1] = Этот_цвет; 
       //---------------------------------------------------------------------------
      }
     //------------------------------------------------------------------------------
     for ( int a2 = 255 ; a2 >= a1; a2--)
      {
       Comp_1 = 255 - Тангенс_угла_старшего_треугольника_2*q;
       Comp_2 = 255 - Тангенс_угла_среднего_треугольника_2*q;
       Comp_3 = 255 - Тангенс_угла_младшего_треугольника_2*q;
       //---------------------------------------------------
       if (Comp_1 > 255 )Comp_1 = 255 ;
       if (Comp_1 > 255 )Comp_2 = 255 ;
       if (Comp_1 > 255 )Comp_3 = 255 ;
       if (Comp_1 < 0 )Comp_1 = 0 ; //добавлено
       if (Comp_2 < 0 )Comp_2 = 0 ; //добавлено
       if (Comp_3 < 0 )Comp_3 = 0 ; //добавлено          
       //---------------------------------------------------       
       if (R == Старшая_компонента)Первая_компонента = Comp_1;
       if (R == Средняя_компонента)Первая_компонента = Comp_2;
       if (R == Младшая_компонента)Первая_компонента = Comp_3;
       //---------------------------------------------------
       if (G == Старшая_компонента)Вторая_компонента = Comp_1;
       if (G == Средняя_компонента)Вторая_компонента = Comp_2;
       if (G == Младшая_компонента)Вторая_компонента = Comp_3;
       //---------------------------------------------------
       if (B == Старшая_компонента)Третья_компонента = Comp_1;
       if (B == Средняя_компонента)Третья_компонента = Comp_2;
       if (B == Младшая_компонента)Третья_компонента = Comp_3;
       //---------------------------------------------------
       Этот_цвет = ( string ) MathRound (Первая_компонента) + "," + ( string ) MathRound (Вторая_компонента) + "," + ( string ) MathRound (Третья_компонента);
       //---------------------------------------------------------------------------    
       Все_оттенки[a2] = Этот_цвет; 
       //---------------------------------------------------------------------------
       q++;
      }
  } 
 //------------------------------------------------------------------------------
 if (Координата_исходного_цвета > 127 )
   {
    Тангенс_угла_старшего_треугольника_1  = ( 255 - Старшая_компонента)/( 255 - Координата_исходного_цвета);
    Тангенс_угла_среднего_треугольника_1  = ( 255 - Средняя_компонента)/( 255 - Координата_исходного_цвета);       
    Тангенс_угла_младшего_треугольника_1  = ( 255 - Младшая_компонента)/( 255 - Координата_исходного_цвета);
     //-----------------------------------------------
    Значение_в_точке_преломления_старшей_компоненты  = 255 - (Тангенс_угла_старшего_треугольника_1* 128 );
    Значение_в_точке_преломления_средней_компоненты  = 255 - (Тангенс_угла_среднего_треугольника_1* 128 );
    Значение_в_точке_преломления_младшей_компоненты  = 255 - (Тангенс_угла_младшего_треугольника_1* 128 );    
     //-----------------------------------------------    
    Тангенс_угла_старшего_треугольника_2  = Значение_в_точке_преломления_старшей_компоненты/ 128 ;
    Тангенс_угла_среднего_треугольника_2  = Значение_в_точке_преломления_средней_компоненты/ 128 ;      
    Тангенс_угла_младшего_треугольника_2  = Значение_в_точке_преломления_младшей_компоненты/ 128 ;
     //-----------------------------------------------    
     for ( int b1 = 0 ; b1 < 128 ; b1++)
      {
       Comp_1 = Тангенс_угла_старшего_треугольника_2*b1;
       Comp_2 = Тангенс_угла_среднего_треугольника_2*b1;
       Comp_3 = Тангенс_угла_младшего_треугольника_2*b1;
       //---------------------------------------------------
       if (Comp_1 > 255 )Comp_1 = 255 ;
       if (Comp_1 > 255 )Comp_2 = 255 ;
       if (Comp_1 > 255 )Comp_3 = 255 ;
       if (Comp_1 < 0 )Comp_1 = 0 ; //добавлено
       if (Comp_2 < 0 )Comp_2 = 0 ; //добавлено
       if (Comp_3 < 0 )Comp_3 = 0 ; //добавлено           
       //---------------------------------------------------
       if (R == Старшая_компонента)Первая_компонента = Comp_1;
       if (R == Средняя_компонента)Первая_компонента = Comp_2;
       if (R == Младшая_компонента)Первая_компонента = Comp_3;
       //---------------------------------------------------
       if (G == Старшая_компонента)Вторая_компонента = Comp_1;
       if (G == Средняя_компонента)Вторая_компонента = Comp_2;
       if (G == Младшая_компонента)Вторая_компонента = Comp_3;
       //---------------------------------------------------
       if (B == Старшая_компонента)Третья_компонента = Comp_1;
       if (B == Средняя_компонента)Третья_компонента = Comp_2;
       if (B == Младшая_компонента)Третья_компонента = Comp_3;
       //---------------------------------------------------
       Этот_цвет = ( string ) MathRound (Первая_компонента) + "," + ( string ) MathRound (Вторая_компонента) + "," + ( string ) MathRound (Третья_компонента);
       //---------------------------------------------------------------------------    
       Все_оттенки[b1] = Этот_цвет; 
       //---------------------------------------------------------------------------
      }
     //------------------------------------------------------------------------------
     for ( int b2 = 255 ; b2 >= b1; b2--)
      {
       Comp_1 = 255 - Тангенс_угла_старшего_треугольника_1*q;
       Comp_2 = 255 - Тангенс_угла_среднего_треугольника_1*q;
       Comp_3 = 255 - Тангенс_угла_младшего_треугольника_1*q;
       //---------------------------------------------------
       if (Comp_1 > 255 )Comp_1 = 255 ;
       if (Comp_1 > 255 )Comp_2 = 255 ;
       if (Comp_1 > 255 )Comp_3 = 255 ;
       if (Comp_1 < 0 )Comp_1 = 0 ; //добавлено
       if (Comp_2 < 0 )Comp_2 = 0 ; //добавлено
       if (Comp_3 < 0 )Comp_3 = 0 ; //добавлено          
       //---------------------------------------------------       
       if (R == Старшая_компонента)Первая_компонента = Comp_1;
       if (R == Средняя_компонента)Первая_компонента = Comp_2;
       if (R == Младшая_компонента)Первая_компонента = Comp_3;
       //---------------------------------------------------
       if (G == Старшая_компонента)Вторая_компонента = Comp_1;
       if (G == Средняя_компонента)Вторая_компонента = Comp_2;
       if (G == Младшая_компонента)Вторая_компонента = Comp_3;
       //---------------------------------------------------
       if (B == Старшая_компонента)Третья_компонента = Comp_1;
       if (B == Средняя_компонента)Третья_компонента = Comp_2;
       if (B == Младшая_компонента)Третья_компонента = Comp_3;
       //---------------------------------------------------
       Этот_цвет = ( string ) MathRound (Первая_компонента) + "," + ( string ) MathRound (Вторая_компонента) + "," + ( string ) MathRound (Третья_компонента);
       //---------------------------------------------------------------------------    
       Все_оттенки[b2] = Этот_цвет; 
       //---------------------------------------------------------------------------
       q++;
      }
   }   
 //------------------------------------------------------------------------------  
}
//+------------------------------------------------------------------+
//| Получение значения компонента R                                  |
//+------------------------------------------------------------------+
double GetR( const color aColor)
  {
   return (aColor& 0xff );
  }
//+------------------------------------------------------------------+
//| Получение значения компонента G                                  |
//+------------------------------------------------------------------+
double GetG( const color aColor)
  {
   return ((aColor>> 8 )& 0xff );
  }
//+------------------------------------------------------------------+
//| Получение значения компонента B                                  |
//+------------------------------------------------------------------+
double GetB( const color aColor)
  {
   return ((aColor>> 16 )& 0xff );
  }
//--------------------------------------------------------------------
double Нужная_компонента( double C1, double C2, double C3, int Index)
{
 double Components[ 3 ]; 
 //----------------------------------------------
 Components[ 0 ] = C1;
 Components[ 1 ] = C2;
 Components[ 2 ] = C3;
 //----------------------------------------------
 ArraySort (Components, WHOLE_ARRAY , 0 , MODE_DESCEND );
 //----------------------------------------------
 return (Components[Index]);
}
 
There's still a blue line on the left. We need to find the cause.
 
Nikolai Semko:

And the code?

What do you think, Nikolai?

Would you admit to making a lot of noise out of nothing? Yes, the algorithm may be slower than yours and it had a couple of bugs. It hasn't been debugged on MT5 yet. But it works.

 
Yury Kulikov:

Your algorithm doesn't work, provide a script (proof with visualisation) that your algorithm works on the whole range of colours.

I did.

It works. Slightly different from Nikolai's script. There's a blue bar on the left. But don't you think it's not very smart to say"your algorithm doesn't work"? Especially for a man of experience.

And about "I understand why we need MT4... MT4 will take it out..." and so on... - That's not brilliant at all. Yes, MT4's syntax requirements are lower than MT5's. But, it's also slower. Which means you have to try really hard to make everything work fast.

That is the purpose of MT4. In order to reach the maximum speed on it, and then get even more, when you switch to MT5.

You, as a developer, should understand that.

 
Реter Konow:

Provided.

It works. Slightly different to Nikolai's script. There's a blue bar on the left. But don't you think it's not very smart to say"your algorithm doesn't work"? Especially for a man of experience.

And about "I understand why we need MT4... MT4 will take it out..." and so on... - That's not brilliant at all. Yes, MT4's syntax requirements are lower than MT5's. But, it's also slower. Which means you have to try very hard to make everything work fast.

That is the purpose of MT4. In order to reach the maximum speed on it, and then get even more, when you switch to MT5.

You, as a developer, should understand that.

I did not. mql5 code please.

 
Реter Konow:

What do you think, Nikolai?

Why don't you admit to making a lot of noise out of nothing? Yes, the algorithm may be slower than yours and it had a couple of bugs. It's not yet debugged on MT5. But it works.

Pyotr, are you aware that

Координата_исходного_цвета=Старшая_компонента/tan((63.43989*pi)/180)+Младшая_компонента/2;

Is equal to .

Координата_исходного_цвета=Старшая_компонента/2+Младшая_компонента/2;

You've asked for a number 2 with a tangent. Top-notch.

Woe betide.
Let's call the number63.43989 Peter's number.

Peter's theorem:

The tangent of Peter's number equals two.

 
Nikolai Semko:

Not provided. mql5 code please.

I will debug it and provide it. Do you think I can't do it?))

I understand that the algorithm should work on both platforms. I slightly underestimated the difference in platforms. I thought that it would not be a problem to port it from MT4. I was wrong about that.

But the concept of the algorithm is correct. You can see it on MT4.

Speed lags behind your analogue on MT4, because I'm using string type.

Later, I will make a variant with type uint. Then we will compare speed of both algorithms on MT4.

Then, we will move on to comparison on MT5.

 
О
Nikolai Semko:

Peter, are you aware that

equals .

and that the parameter for the tan function is not in degrees, but in radians.
You're asking for the number 2 with a tangent. That's aerobatics.

Woe is me.
Let's call the number63.43989 the number of Peter.

If you don't understand, I'm translating degrees into radians.

tan((63.43989*pi)/180)

That is the translation. Look on the internet to find out how to convert degrees to radians and vice versa.

Yes, the value oftan((63.43989*pi)/180) is constant. You think I haven't seen it? However, I prefer to see it that way.


 
Реter Konow:

Provided.

It works. Slightly different to Nikolai's script. There's a blue bar on the left. But don't you think it's not very smart to say"your algorithm doesn't work"? Especially for a man of experience.

And about "I understand why we need MT4... MT4 will take it out..." and so on... - That's not brilliant at all. Yes, MT4's syntax requirements are lower than MT5's. But, it's also slower. Which means you have to try very hard to make everything work fast.

That is the purpose of MT4. In order to reach the maximum speed on it, and then get even more, when you switch to MT5.

You, as a developer, should understand that.

The code presented on the first page does not work, and only thanks to comments of forum visitors it starts working.

Check your algorithm on colour 0,0,0 and 255,255,255,255.

 
Yury Kulikov:

The code presented on the first page does not work, and only thanks to comments from forum members does it start to work.

Check your algorithm on colour 0,0,0 and 255,255,255,255.

Take the script from this page. In it the range of colour change is given by Nikolay's algorithm. I have connected my function to it.

The script on the first page is intended only for outputting shades via Alert.

If you are not satisfied with Nikolai's range, then why did you give his rendering as an example?