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

 

Ну, на сегодня достаточно наворачивать круги. Всем огромное спасибо за участие и помощь в нахождении багов и проблем моего алгоритма. Отдельное спасибо тебе Николай и также большое спасибо Юрию Куликову на указание на ошибки.

Специальное спасибо Николаю, за алгоритм визуализации. 

Буду совершенствовать код и выкладывать сюда новые, более хорошие версии. Надеюсь - кому то пригодится.


ЗЫ. Знаю, что бывает искушение бросить на прощание в человека тухлыми яйцами, но давайте воздержимся.)))

 
Реter Konow:

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

Не пойму - ты прикалываешься уже что-ли? 

Я же написал:

deltaR=(R2-R1)/(size-1);

Ну могу сказать не языком формул:

Дельта R - равна разнице межу R-составляющими двух цветов, поделенной на необходимое колличество градиентов.

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

y= a+b*x;

в наше случае 

текущая_составляющая_цветаR = составляющая_R_ цвета1 + дельта_R * номер_текущего_элемента_массива;
текущая_составляющая_цветаG = составляющая_G_ цвета1 + дельта_G * номер_текущего_элемента_массива;
текущая_составляющая_цветаB = составляющая_B_ цвета1 + дельта_B * номер_текущего_элемента_массива;
 
Реter Konow:

Ну, на сегодня достаточно наворачивать круги. Всем огромное спасибо за участие и помощь в нахождении багов и проблем моего алгоритма. Отдельное спасибо тебе Николай и также большое спасибо Юрию Куликову на указание на ошибки.

Специальное спасибо Николаю, за алгоритм визуализации. 

Буду совершенствовать код и выкладывать сюда новые, более хорошие версии. Надеюсь - кому то пригодится.

ЗЫ. Знаю, что бывает искушение бросить на прощание в человека тухлыми яйцами, но давайте воздержимся.)))

Согласен! Просто если вдруг нужен будет код, то возьмём код Николая с десятком строк, а не портянку в сотню строк)

 
Не перестаю удивляться, как, вроде бы, адекватные люди продолжают вестись на провокации топикстартера. Он же просто поговорить хочет, люди!
 
Andrey Khatimlianskii:
Не перестаю удивляться, как, вроде бы, адекватные люди продолжают вестись на провокации топикстартера. Он же просто поговорить хочет, люди!
Подколол, Андрей. :)
На самом деле интересная задача получить палитру цвета без цветовых сгустков и минимальным искажением цвета. Очевидно, что дельта между составляющими цвета не должна быть константой и должна плавно меняться  . В приведенных выше примерах она имеет два значения : от чёрного и от белого. Поэтому это меня и зацепило.
 
Andrey Khatimlianskii:
Не перестаю удивляться, как, вроде бы, адекватные люди продолжают вестись на провокации топикстартера. Он же просто поговорить хочет, люди!

Вы зря удивляетесь. Я вам объясню и вы поймете.

  1.    Срабатывает подсознательный рефлекс - напасть на незнакомую форму. Если форма видимого нестандартна и претендует на свое место в этом мире, - она должна быть уничтожена. Почему? - Две причины:

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

Очевидно, этот рефлекс существует в подсознании каждого индивидуума. Я представляю собой воплощение всего нестандартного в программировании. Нестандартный подход, нестандартный стиль. Поэтому некоторые, подсознательно, воспринимают меня как угрозу их картине мира, а другие - как слабость. В обоих случаях, возникает искушение "напасть" и уничтожить мою позицию. Мотивация усиливается желанием набрать себе побольше "баллов".

Однако, - нестандартная форма (которую я представляю), может быть признаком не только слабости или деградации, но и признаком феноменальной силы и способностей. В этом случае, нестандартная Форма может претендовать стать новым Стандартом.


     2. Срабатывает бессознательный вывод:  "Форма = Суть". Большинство людей судит о Сути по Форме. Если Форма кажется нелепой или смешной, такой же они считают Суть. Мы все знаем, что это не признак великого ума, но мы подвержены этому стереотипу.

На первой странице, я подробно объяснил суть своей концепции. Но, мои оппоненты не оценили ее. Они сразу зациклились на Форме. На конкретном алгоритме. Мол - он плохой, нелепый, медленный. Они решили, что разнести мой алгоритм достаточно, чтобы уничтожить мою позицию. Но идею, которую я заложил в алгоритм - они не поняли.  Поэтому, критикуя мой алгоритм, они всего лишь помогают мне делать его лучше. При этом, у него остается прежняя Суть, - тот же принцип разложения цвета

Если бы мои оппоненты уничтожили мою концепцию, а не алгоритм, они бы преуспели. Но у них у самих нет концепции.  Поэтому, - моя позиция сильнее. 

Все вышесказанное имеет отношение и к другим противоречиям с оппонентами. Они судят о моих идеях по форме их реализации, и не смотрят на Суть. Пока это остается так, я всегда буду побеждать. Хотите уничтожить мою позицию? - разнесите мою концепцию в щепки на том же уровне, на котором я ее создаю. Но это посложнее, чем воевать с формой реализации.

 
Реter Konow:

Вы зря удивляетесь. Я вам объясню и вы поймете.

...

Пётр, вы воюете с ветряными мельницами. Ну есть ещё вариант: вы - Неуловимый Джо со всеми из того вытекающими :)

 
Реter Konow:



Где работающий mql5 код?

 
Nikolai Semko:


Где работающий mql5 код?

//+------------------------------------------------------------------+
//|                                              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();
//------------------------
  }
//+------------------------------------------------------------------+
//================================================================================================================================================================
void Диапазон_оттенков(color _Цвет, uint &Все_оттенки[])
{
 color R = 0, G = 0,  B = 0;
 int   q = 0, w1 = 0, w2 = 0;
 //------------------------------------------------------
 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 = GetR(_Цвет), 
        Исходный_G = GetG(_Цвет),  
        Исходный_B = GetB(_Цвет),  
        //-----------------------------------------------
        Старшая_компонента         = Нужная_компонента(Исходный_R,Исходный_G,Исходный_B, 2), 
        Средняя_компонента         = Нужная_компонента(Исходный_R,Исходный_G,Исходный_B, 1), 
        Младшая_компонента         = Нужная_компонента(Исходный_R,Исходный_G,Исходный_B, 0), 
        //-----------------------------------------------
        Координата_исходного_цвета = Старшая_компонента/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] = StringToColor((string)MathRound(Первая_компонента) + "," + (string)MathRound(Вторая_компонента) + "," + (string)MathRound(Третья_компонента));
       //---------------------------------------------------------------------------    
       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] = StringToColor((string)MathRound(Первая_компонента) + "," + (string)MathRound(Вторая_компонента) + "," + (string)MathRound(Третья_компонента)); 
       //---------------------------------------------------------------------------
       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] = StringToColor((string)MathRound(Первая_компонента) + "," + (string)MathRound(Вторая_компонента) + "," + (string)MathRound(Третья_компонента));
       //---------------------------------------------------------------------------    
       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;
       //---------------------------------------------------
       Этот_цвет = StringToColor((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);
 //----------------------------------------------
 return(Components[Index]);
}
//=============================================================================
 
Nikolai Semko:


Где работающий mql5 код?

Насчет "R = Исходный_R" ты прав, но я оставил так, потому что так понятней принцип работы алгоритма. 

Над алгоритмом безусловно нужно еще работать. Он не идеален. Может быть, в конце я приду к такому же алгоритму, как у тебя. Но пройдя весь этот путь я получу несравненно больше. Ведь, я пройду путь познания и понимания, а значит творческая область реализации алгоритма будет гораздо шире, чем если бы просто скопировал чье то решение. Поэтому, я всегда выбираю свой путь.
Причина обращения: