Функция разложения цвета на оттенки. - страница 13

 

Добавил. Проверьте этот скрипт.

//+------------------------------------------------------------------+
//|                                              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]);
}
 
Еще синяя линия слева осталась. Нужно найти причину.
 
Nikolai Semko:

а код?

Что скажешь, Николай? 

Может признаешь, что делал много шуму из ничего? Да, алгоримт может медленнее твоего и у него были пара багов. На МТ5 еще не отлажен. Но он работает.

 
Yury Kulikov:

Ваш алгоритм не работает, предоставьте скрипт(доказательства с визуализацией), что ваш алгоритм работает на всем диапазоне цветов.

Предоставил. 

Работает. Чуть иначе, чем скрипт Николая. Синяя полоса есть слева. Но вам не кажется, что сходу заявлять "ваш алгоритм не работает" не очень умно? Особенно, для человека умудренного опытом. 

А насчет "понятно, зачем МТ4 нужен... МТ4 вывезет..." и так далее... - Это совсем не блещет. Да, требования МТ4 к синтаксису ниже чем у МТ5. Но, и скорость меньше. А значит, нужно очень постараться, чтобы все быстро работало. 

Для того и нужен МТ4. Чтобы достичь максимума скорости на нем, а потом получить еще больше, перейдя на МТ5. 

Уж вы как разработчик, должны понимать это.

 
Реter Konow:

Предоставил. 

Работает. Чуть иначе, чем скрипт Николая. Синяя полоса есть слева. Но вам не кажется, что сходу заявлять "ваш алгоритм не работает" не очень умно? Особенно, для человека умудренного опытом. 

А насчет "понятно, зачем МТ4 нужен... МТ4 вывезет..." и так далее... - Это совсем не блещет. Да, требования МТ4 к синтаксису ниже чем у МТ5. Но, и скорость меньше. А значит, нужно очень постараться, чтобы все быстро работало. 

Для того и нужен МТ4. Чтобы достичь максимума скорости на нем, а потом получить еще больше, перейдя на МТ5. 

Уж вы как разработчик, должны понимать это.

Не предоставил. mql5 код пожалуйста.

 
Реter Konow:

Что скажешь, Николай? 

Может признаешь, что делал много шуму из ничего? Да, алгоримт может медленнее твоего и у него были пара багов. На МТ5 еще не отлажен. Но он работает.

Петр, а ты в курсе что 

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

равносильно

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

Ты попросу вывел число 2 с помощью тангенса. Высший пилотаж.

Горе от ума.
Назовем число  63.43989 числом Петра.

Теорема Петра:

Тангенс от числа Петра равняется двум.

 
Nikolai Semko:

Не предоставил. mql5 код пожалуйста.

Отлажу и предоставлю. Думаешь, у меня не получится?))

Понимаю, что алгоритм должен работать на обоих платформах. Я немного недооценил разницу платформ. Решил, что перенести его с МТ4 - не составит никакого труда. В этом, я ошибся. 

Но концепция алгоритма правильная. Ты можешь это видеть на МТ4. 

Скорость отстает от твоего аналога на МТ4, потому что использую тип string

Позже, сделаю вариант с типом uint. Тогда мы сравним скорость обоих алгоритмов на МТ4. 

Потом, перейдем к сравнению на МТ5.

 
О
Nikolai Semko:

Петр, а ты в курсе что 

равносильно

и что для функции tan параметр задается не в градусах, а в радианах.
Ты попросу вывел число 2 с помощью тангенса. Высший пилотаж.

Горе от ума.
Назовем число  63.43989 число Петра.

Если ты не понял, то я перевожу градусы в радианы.

tan((63.43989*pi)/180)

Это и есть перевод. Посмотри в интернете, как перевести градусы в радианы и обратно.

Да, значение tan((63.43989*pi)/180) постоянно.      Думаешь я это не видел? Однако, мне лучше его воспринимать именно так. 


 
Реter Konow:

Предоставил. 

Работает. Чуть иначе, чем скрипт Николая. Синяя полоса есть слева. Но вам не кажется, что сходу заявлять "ваш алгоритм не работает" не очень умно? Особенно, для человека умудренного опытом. 

А насчет "понятно, зачем МТ4 нужен... МТ4 вывезет..." и так далее... - Это совсем не блещет. Да, требования МТ4 к синтаксису ниже чем у МТ5. Но, и скорость меньше. А значит, нужно очень постараться, чтобы все быстро работало. 

Для того и нужен МТ4. Чтобы достичь максимума скорости на нем, а потом получить еще больше, перейдя на МТ5. 

Уж вы как разработчик, должны понимать это.

Код представленный на первой странице не рабочий, и только благодаря замечаниям форумчан он начинает работать.

Проверьте свой алгоритм на цвете 0,0,0 и 255,255,255.

 
Yury Kulikov:

Код представленный на первой странице не рабочий, и только благодаря замечаниям форумчан он начинает работать.

Проверьте свой алгоритм на цвете 0,0,0 и 255,255,255.

Скрипт берите с этой страницы. В нем диапазон изменения цвета задан алгоритмом Николая. Я подключил к нему свою функцию. 

 Скрипт на первой странице предназначен только для вывода оттенков через Алерт.

Если вас не устраивает диапазон Николая, то зачем вы приводили в пример его визуализацию?