A função de decompor a cor em tons. - página 12

 
Реter Konow:

Aqui está o resultado do meu algoritmo no MT5. Sem qualquer artifício desnecessário e supérfluo.


E o código?

 
Nikolai Semko:

Já demonstrei a falha em sua abordagem acima, e se ela corresponde à paleta com a qual você a está comparando, então o mesmo acontece, usando o exemplo da linha branca.
Novamente em outras palavras.

Se você mudar a cor suavemente de preto (0,0,0) para branco (255.255.255) passando por uma determinada cor (r1,g1,b1) então a soma das três cores R, G e B é o indicador importante. É melhor se afastar da terminologia aqui, pois ela pode ficar confusa (brilho, luminosidade, tom ....)

É absolutamente óbvio que, idealmente, deveria mudar linearmente de 0 para 3*255=765. Você afina sua cor estritamente no meio, eu primeiro calculo a soma da cor original e a colo no gradiente de acordo com essa soma RGB. É por isso que minha linha branca não tem ponto de ruptura, ao contrário da sua.

Nikolai, embora você não tenha explicado como funciona seu algoritmo e esteja falando de algumas linhas brancas que deveriam ser assim, mas não diferentes...

É óbvio que você mesmo não entende como seu algoritmo se decompõe em sombras. Você não tem um conceito coerente. Apenas uma confusão de termos e códigos emprestados de algum outro lugar.

 
Nikolai Semko:

e o código?

Ainda não está tudo pronto. Admito ter subestimado o grau de diferença de plataforma. O algoritmo no MT5 é defeituoso em alguns lugares. Mas o problema está apenas no código, não no conceito.

 
Реter Konow:

Nikolai, embora você não tenha explicado como funciona seu algoritmo e esteja falando de algumas linhas brancas que deveriam ser assim, mas não assim...

É óbvio que você mesmo não entende como seu algoritmo se decompõe em sombras. Você não tem um conceito coerente. Apenas uma confusão de termos e códigos emprestados de algum outro lugar.

Peter, do que você está falando? Se eu não entendesse, como poderia fazer isso. Escrever um algoritmo em código é muito mais fácil do que descrevê-lo em palavras.
Diga-me, você entende o significado deste código? Afinal, tudo é tão elementar e óbvio que eu não entendo nem mesmo quais comentários podem ser inseridos aqui.

void Gradient(uint clr1,uint clr2,uint &arr[],uint size)
  {
   if(size==0) return;
   ArrayResize(arr,size);
   rgb c1,c2;
   c1.clr=clr1;
   c2.clr=clr2;
   double R1=c1.c[2],G1=c1.c[1],B1=c1.c[0];
   double R2=c2.c[2],G2=c2.c[1],B2=c2.c[0];
   double deltaR=(R2-R1)/(size-1);
   double deltaG=(G2-G1)/(size-1);
   double deltaB=(B2-B1)/(size-1);
   for(uint i=0;i<size;i++)
     {
      R1+=deltaR; c1.c[2]=uchar (R1+0.4999);
      G1+=deltaG; c1.c[1]=uchar (G1+0.4999);
      B1+=deltaB; c1.c[0]=uchar (B1+0.4999);
      arr[i]=c1.clr;
     }
  }
 
Nikolai Semko:

Peter, do que você está falando? Se eu não entendesse, como poderia fazer isso. Escrever um algoritmo em código é muito mais fácil do que descrevê-lo em palavras.
Diga-me, você entende o significado deste código? Afinal, tudo é tão elementar e óbvio que eu não entendo nem mesmo quais comentários podem ser inseridos aqui.

Veja como seu algoritmo funciona, usando esta função como exemplo:

#include <Canvas\iCanvas.mqh> //https://www.mql5.com/ru/code/22164

union rgb {uint clr; uchar c[4];};

void OnStart()
  {
   rgb c,C;
   uint CLR[];
   color clr=clrViolet;
   Gradient(clrWhite, clr, CLR,W.Height/2); // получаем массив градиента от белого цвета до цвета clr 
   for(int y=0; y<W.Height/2; y++) Canvas.LineHorizontal(0,W.Width-1,y,ColorToARGB(CLR[y],240)); // выводим на экран
   Gradient(clr, clrBlack, CLR,W.Height-W.Height/2); // получаем массив градиента от цвета clr до черног цвета  
   for(int y=W.Height/2; y<W.Height; y++) Canvas.LineHorizontal(0,W.Width-1,y,ColorToARGB(CLR[y-W.Height/2],240)); // выводим на экран в продолжение предыдущего
   Canvas.Update();
   Sleep(30000);
   }
//+------------------------------------------------------------------+

void Gradient(uint clr1,uint clr2,uint &arr[],uint size)
  {
   if(size==0) return;
   ArrayResize(arr,size);
   rgb c1,c2;
   c1.clr=clr1;
   c2.clr=clr2;
   double R1=c1.c[2],G1=c1.c[1],B1=c1.c[0];
   double R2=c2.c[2],G2=c2.c[1],B2=c2.c[0];
   double deltaR=(R2-R1)/(size-1);
   double deltaG=(G2-G1)/(size-1);
   double deltaB=(B2-B1)/(size-1);
   for(uint i=0;i<size;i++)
     {
      R1+=deltaR; c1.c[2]=uchar (R1+0.4999);
      G1+=deltaG; c1.c[1]=uchar (G1+0.4999);
      B1+=deltaB; c1.c[0]=uchar (B1+0.4999);
      arr[i]=c1.clr;
     }
  }


 
Nikolai Semko:

Peter, do que você está falando? Se eu não entendesse, como poderia fazer isso. Escrever um algoritmo em código é muito mais fácil do que descrevê-lo em palavras.
Diga-me, você entende o significado deste código? Afinal, tudo é tão elementar e óbvio que eu não entendo nem mesmo quais comentários podem ser inseridos aqui.

Diga seu conceito de decomposição de cores. Se o algoritmo é seu, você o conhece bem.

 
Реter Konow:

Você parece estar se convencendo de algo. Mais uma vez, não houve tempo para fazer uma visualização. Você já verificou o algoritmo em relação à paleta?

O resultado de seu script para cor 207.255.65

O resultado de seu script para cor 207.255.65.

 
Yury Kulikov:

O resultado de seu script para cor 207.255.65.

Obrigado pela observação. Eu também identifiquei alguns erros. Vou fazer um mt4 gif agora. Funciona bem, mas há problemas em algumas cores.

 

Não consigo gifs de alta qualidade. Aqui está o roteiro. Coloque o MT4 e veja tudo como está.

 //+------------------------------------------------------------------+
//|                                              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 (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 (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 (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 (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]);
}
 

Encontramos o primeiro erro. Corrigido.

Eu deveria ter acrescentado :

       if(Comp_1 < 0 )Comp_1 = 0;
       if(Comp_2 < 0 )Comp_2 = 0;
       if(Comp_3 < 0 )Comp_3 = 0;

em cada laço.

Razão: