색상을 음영으로 분해하는 기능. - 페이지 18

 
Реter Konow :

"R = Initial_R"에 관해서는 당신이 옳았지만, 알고리즘의 원리가 이렇게 하면 더 명확하기 때문에 나는 그대로 두었습니다.

알고리즘은 확실히 더 많은 작업이 필요합니다. 그는 완벽하지 않습니다. 아마도 결국 나는 당신과 같은 알고리즘에 도달하게 될 것입니다. 그러나 이 모든 길을 가다 보면 비할 데 없이 더 많은 것을 얻게 될 것입니다. 결국, 나는 지식과 이해의 길을 갈 것입니다. 즉, 알고리즘을 구현하는 창의적인 영역은 단순히 누군가의 솔루션을 복사하는 것보다 훨씬 더 넓습니다. 그래서 저는 항상 제 길을 선택합니다.

라인

 StringToColor (( string ) MathRound (Первая_компонента) + "," + ( string ) MathRound (Вторая_компонента) + "," + ( string ) MathRound (Третья_компонента));

미친 브레이크의 근원

프로파일링을 시도합니다.

이것은 훨씬 더 빠를 것입니다:

(( uint ) MathRound (Первая_компонента))|(( uint ) MathRound (Вторая_компонента)<< 8 )|(( uint ) MathRound (Третья_компонента)<< 16 );
 
Nikolai Semko :

라인

미친 브레이크의 근원

프로파일링을 시도합니다.

이것은 훨씬 더 빠를 것입니다:

쓰레기. 글쎄, 내 알고리즘은 당신과 같은 속도를 가지고 있습니다.))

고마워요, 니콜라이!

나는 그런 작업에 익숙하지 않습니다.
 
Реter Konow :

쓰레기. 글쎄, 내 알고리즘은 당신과 같은 속도를 가지고 있습니다.))

고마워요, 니콜라이!

아직 아님. 몇 가지 더 수정할 사항이 있습니다.

 

중복 기능을 제거했습니다. 이제 주요 기능만:

 //+------------------------------------------------------------------+
//|                                              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 ()); }
   double d= 5 ;
   uint 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);
       //Gradient(C.clr,Gradient,256);
      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));
         canvas.LineHorizontal( 0 , 767 ,y, ColorToARGB (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 _Цвет, uint &Все_оттенки[])
{
 color R = 0 , G = 0 ,  B = 0 ;
 int    q = 0 , w1 = 0 , w2 = 0 ;
 double Components[ 3 ];
 //------------------------------------------------------
 uint Этот_цвет;
 double Тангенс_угла_старшего_треугольника_1,      
        Тангенс_угла_среднего_треугольника_1,                  
        Тангенс_угла_младшего_треугольника_1,                       
        Значение_в_точке_преломления_старшей_компоненты,  
        Значение_в_точке_преломления_средней_компоненты,
        Значение_в_точке_преломления_младшей_компоненты,    
        Тангенс_угла_старшего_треугольника_2,
        Тангенс_угла_среднего_треугольника_2,    
        Тангенс_угла_младшего_треугольника_2;
 //------------------------------------------------------
 double pi = 3.1415926536 ,
        Comp_1,Comp_2,Comp_3,
         //-----------------------------------------------
        Первая_компонента = 0.0 ,
        Вторая_компонента = 0.0 ,
        Третья_компонента = 0.0 ,
         //-----------------------------------------------
        Исходный_R = (_Цвет)& 0xff , 
        Исходный_G = (_Цвет>> 8 )& 0xff , 
        Исходный_B = (_Цвет>> 16 )& 0xff ;        
         //-----------------------------------------------

   //-----------------------------------------------
   Components[ 0 ] = Исходный_R;
   Components[ 1 ] = Исходный_G;
   Components[ 2 ] = Исходный_B;
   //---------------------------
   ArraySort (Components);
   //---------------------------
   double Старшая_компонента         = Components[ 2 ]; 
   double Средняя_компонента         = Components[ 1 ]; 
   double Младшая_компонента         = Components[ 0 ]; 
//-----------------------------------------------
   double Координата_исходного_цвета=Старшая_компонента/ tan (( 63.43989 *pi)/ 180 )+Младшая_компонента/ 2 ;
//-----------------------------------------------
 //-----------------------------------------------
 if (Старшая_компонента == Исходный_R)R = ( color )Старшая_компонента;
 if (Старшая_компонента == Исходный_G)G = ( color )Старшая_компонента; 
 if (Старшая_компонента == Исходный_B)B = ( color )Старшая_компонента;     
 //------------------------
 if (Средняя_компонента == Исходный_R)R = ( color )Средняя_компонента;
 if (Средняя_компонента == Исходный_G)G = ( color )Средняя_компонента; 
 if (Средняя_компонента == Исходный_B)B = ( color )Средняя_компонента; 
 //------------------------
 if (Младшая_компонента == Исходный_R)R = ( color )Младшая_компонента;
 if (Младшая_компонента == Исходный_G)G = ( color )Младшая_компонента; 
 if (Младшая_компонента == Исходный_B)B = ( color )Младшая_компонента; 
 //------------------------------------------------
   
 //==========================================================================================
 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;
       //---------------------------------------------------
       Все_оттенки[a1] = (( uint ) MathRound (Первая_компонента))|(( uint ) MathRound (Вторая_компонента)<< 8 )|(( uint ) MathRound (Третья_компонента)<< 16 );
       //---------------------------------------------------------------------------    
       w1++;
      }
     //------------------------------------------------------------------------------
     for ( int a2 = 255 ; a2 >= w1; 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;
       //---------------------------------------------------
       Все_оттенки[a2] = (( uint ) MathRound (Первая_компонента))|(( uint ) MathRound (Вторая_компонента)<< 8 )|(( uint ) MathRound (Третья_компонента)<< 16 );
       //---------------------------------------------------------------------------
       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;
       //---------------------------------------------------
       Все_оттенки[b1] = (( uint ) MathRound (Первая_компонента))|(( uint ) MathRound (Вторая_компонента)<< 8 )|(( uint ) MathRound (Третья_компонента)<< 16 );
       //---------------------------------------------------------------------------    
       w2++;
      }
     //------------------------------------------------------------------------------
     for ( int b2 = 255 ; b2 >= w2; 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;
       //---------------------------------------------------
       Этот_цвет = (( uint ) MathRound (Первая_компонента))|(( uint ) MathRound (Вторая_компонента)<< 8 )|(( uint ) MathRound (Третья_компонента)<< 16 );
       //---------------------------------------------------------------------------    
       Все_оттенки[b2] = Этот_цвет; 
       //---------------------------------------------------------------------------
       q++;
      }
   }   
 //------------------------------------------------------------------------------  
}
//=============================================================================
 
Nikolai Semko :
망했어, 안드레이. :)
사실, 흥미로운 작업은 색상 응고가 없고 색상 왜곡을 최소화하는 색상 팔레트를 얻는 것입니다. 분명히 색상 구성 요소 간의 델타는 일정하지 않아야 하고 부드럽게 변해야 합니다. 위의 예에서 검은색과 흰색의 두 가지 값이 있습니다. 그래서 그것이 나를 사로 잡았습니다.

네, 18페이지가 문제에 대한 토론에 할애되었습니다. 그리고 OOP, 러시아 변수 이름 및 자동 거래의 미래에 대한 단어가 아닙니다)

 
Andrey Khatimlianskii :

네, 18페이지가 문제에 대한 토론에 할애되었습니다. 그리고 OOP, 러시아 변수 이름 및 자동 거래의 미래에 대한 단어가 아닙니다)

이 스레드에서만 키릴 문자에 대해 여러 번 이야기했습니다 . 그러나 Peter는 OOP 및 키릴 자모 문제에서 뚫을 수 없습니다. 이미 포기했으며 키릴 자모가 없고 디버깅을 사용하여 자신의 클래스가 포함된 그의 코드를 볼 때까지 그에 대한 내 "이동"이 끝난 것으로 생각합니다. 나는 OOP와 디버깅 가능성이 있는 스타일이 없으면(즉, 키릴 자모가 없는) GUI가 결코 빛을 보지 못할 것이며, 그렇다면 야유를 받고 썩은 계란과 토마토를 던질 것이라고 반복해서 말했습니다. . Peter가 그의 환상적인 인내심과 효율성(디버거 없이 코드를 작성할 수 있음)으로 동일한 수준의 보수성과 집요함을 가지고 있다면 당신은 무엇을 할 수 있습니까?

그러나 Peter가 없었다면 이 포럼은 그렇게 카리스마가 없었을 것입니다. ))
 
TheXpert :

아마도 다음과 같이 조금 더 빠를 것입니다.

 void Gradient( uint clr1, uint clr2, uint &arr[], uint size)
  {
   if (size== 0 ) return ;
   ArrayResize (arr,size);
   arr[ 0 ]=clr1; 
   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 );
   R1 += 0.4999 ;
   G1 += 0.4999 ;
   B1 += 0.4999 ;
   for ( uint i= 1 ;i<size;i++)
     {
      R1+=deltaR; c1.c[ 2 ]= uchar (R1);
      G1+=deltaG; c1.c[ 1 ]= uchar (G1);
      B1+=deltaB; c1.c[ 0 ]= uchar (B1);
      arr[i]=c1.clr;
     }
  }

동의한다.

 
Nikolai Semko :

동의한다.

니콜라스, 객관적이 되자.

이 테스트에서 관련 없는 그림을 제거하여 스크립트를 최대한 단순하게 만들었고 다음과 같은 불일치를 드러냈습니다.

보시다시피 알고리즘에서 색상 범위의 중심이 맨 위로 이동합니다. 가장 밝은 밴드가 중앙에 있어야 합니다. 이것은 Windows 팔레트에서 확인됩니다.


아래는 테스트용 스크립트입니다.

파일:
 

셀 127은 색조 배열의 중심입니다. 이 셀은 팔레트와 동일한 색상을 포함해야 합니다. 나는 1의 오류가 있고 당신은 63입니다.

깜박임과 과도한 그리기로 인해 알고리즘의 정확성을 확인하는 데 집중하기 어려웠습니다. 따라서 Alert 에서 출력물로 확인하는 것을 제안했습니다.

추신. 일반적으로 배열의 중심은 셀 128이지만 본질은 바뀌지 않습니다.
 

새로운 흥미로운 사실:

  • 색상 파란색 - C'0,0,255'

  • 색상 녹색 - C'0,255,0'

  • 색상 그레이 - C'128,128,128' (두 옵션 동일)

  • 색상 - C'128,64,0' (엄청난 차이)



Nikolai는 공격하지 않지만 알고리즘은 더 빠르고 짧지만(사실상) 올바르게 작동하지 않습니다(사실상). 사려 깊은 개념적 기반이 부족합니다.

내 알고리즘은 처음에 속도(하지만 도움이 되었습니다)와 디버깅이 부족했습니다. 동시에 그의 작업에는 처음에 사려 깊고 정확한 개념이 제시되었습니다.

따라서 그러한 차이가 나타났습니다.