색상을 음영으로 분해하는 기능.

 

한 달 동안 나는 색을 음영으로 분해하는 문제를 완고하게 해결했습니다. 작업은 어려운 것으로 판명되었습니다. 연구의 기초로 Windows 색상표를 사용했습니다( 차트 속성에 있는 색상표). 오랜 연구 끝에 나는 여전히 패턴을 찾았습니다. 방법은 다음과 같습니다.

  • 먼저 색상을 세 가지 주요 구성 요소로 분해하여 최고, 중, 최저를 결정했습니다.
  • 또한 구성 요소의 값을 통해 그래프를 만들고 선을 그리기 시작했습니다.
  • 슬라이더를 끌 때 팔레트에서 숫자의 변화를 관찰하면서 특정 순간에 숫자의 변화율이 바뀌었기 때문에 선의 상승 각도의 굴절이 있다는 것을 깨달았습니다.
  • 선의 굴절축을 그래프의 중앙으로 설정하고 각 선이 각각 고유한 상승각을 갖는 두 개의 세그먼트로 구성되어 있음을 확인했습니다.
  • 또한 색상 팔레트를 실험하면서 가장 높은 구성 요소의 최대 상승 각도가 있음을 깨달았습니다. 처음에는 67.5도인 줄 알았습니다. 그러나 실습에 따르면 63.5도와 같습니다.
  • 오랫동안 나는 색상 구성 요소의 선분을 올바르게 그리는 방법을 알 수 없었습니다. 알려지지 않은 것이 많았습니다. 그러나 가장 중요한 것은 차트에서 원래 색상의 좌표를 찾는 방법입니다.
  • 팔레트를 계속 실험하면서 색상 값을 특정 숫자만큼 변경하면 슬라이더가 특정 거리를 이동한다는 것을 알았습니다. 점차적으로 슬라이더의 이동 거리는 보조 구성 요소 값의 절반과 같다는 것을 깨달았습니다.
  • 최대상승각선에서 가장 높은 성분의 좌표를 찾아 이 점에 가장 낮은 성분의 값의 절반을 더하면 그래프에서 원래 색의 좌표를 찾게 된다고 가정했다. 실습을 통해 가정이 옳았다는 것이 입증되었습니다.
  • 원래 색상의 좌표와 굴절 축이 주어지면 각 세그먼트의 각도를 계산하고 해당 선을 따라 각 구성 요소에 대한 값을 얻을 수 있습니다. 이를 위해 학교 삼각법을 사용했습니다.
  • 종이에 계산을 확인한 후 함수를 작성하기 시작했습니다. 이제 모두와 공유하고 싶습니다.
 //+------------------------------------------------------------------+
//|                                                Full Gradient.mqh |
//|                                                      Peter Konow |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
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]);
}

 

다음은 테스트용 스크립트입니다.

 void OnStart ()
  {
   color Main_color     = C'213,0,0' ; //здесь ставите нужный цвет. Компилируете. Тот же цвет ставите в цветовой палитре виндоус. Сравниваете цвета.
   string Gradient[ 256 ];
   //------------------------
   Диапазон_оттенков(Main_color,Gradient);
   //------------------------
   for ( int a1 = 0 ; a1 < 256 ; a1++) Alert ( __FUNCTION__ , "  Gradient[" ,a1, "]  " ,Gradient[a1]);
  }
파일:
 
Реter Konow :

다음은 테스트용 스크립트입니다.

덕분에! 댓글과 함께 영어로 코드를 작성해서 도서관에 보내면 좋을텐데...

 
CCanvas 클래스 를 사용하여 이 작업을 해결하는 방법도 매우 흥미롭습니다. 원래 색상의 모든 음영을 어떻게 통과할 수 있습니까?
 
Vladimir Pastushak :

덕분에! 댓글과 함께 영어로 코드를 작성해서 도서관에 보내면 좋을텐데...

동의한다. 여가 시간에 번역하겠습니다. 코드베이스를 말씀하시는 건가요?

 
Реter Konow :

동의한다. 여가 시간에 번역하겠습니다. 코드베이스를 말씀하시는 건가요?

코드 베이스에는 이러한 코드가 추가 및 업데이트되는 라이브러리 섹션이 있습니다.

 
Vladimir Pastushak :

코드 베이스에는 이러한 코드가 추가 및 업데이트되는 라이브러리 섹션이 있습니다.

알았습니다.

 
Vladimir Pastushak :

덕분에! 댓글과 함께 영어로 코드를 작성해서 도서관에 보내면 좋을텐데...

물론 CodeBade의 경우 국제 언어로 작성해야 합니다. 그러나 러시아어를 사용하는 포럼에서 이것을 주장하는 이유는 무엇입니까?

개인적으로, 이 국제적 언어는 나에게 역겹습니다. 왜냐하면 저는 그것을 전혀 모르고 제 모국어인 러시아어가 훨씬 더 명확하기 때문입니다.

 

내가 기억하는 한 비색계에는 다양한 시스템이 있습니다.

아마도 요구 사항을 충족하는 기성 시스템과 이들 사이를 이동하는 공식이 있을 수 있습니다.

 
Georgiy Merts :

내가 기억하는 한 비색계에는 다양한 시스템이 있습니다.

아마도 요구 사항을 충족하는 기성 시스템과 이들 사이를 이동하는 공식이 있을 수 있습니다.

한 가지 기능이 있습니다. 색상을 보냈습니다 - 모든 음영을 얻었습니다. 또한 배열을 반복하는 것만으로 모든 그라디언트를 그릴 수 있습니다.

 

조금 후에 나는 변경을 했다. 처음에는 함수가 void입니다. 값을 반환하지 않습니다. 그러나 그 후에 나는 그것을 int 유형 으로 만들고 아래에 추가했습니다.

 return (Координата_исходного_цвета);

따라서 음영 배열 외에도 함수는 원래 색상이 있는 셀의 번호를 반환하기 시작했습니다. 이렇게 하면 그라디언트를 더 쉽게 그릴 수 있습니다. 원래 색상에서 배열의 왼쪽이나 오른쪽으로 이동할 수 있습니다.