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

 
Yury Kulikov:


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

Сейчас проверю.

 
Yury Kulikov:


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

Проверил. 0,0,0, - приводит к ошибке. Советник выгружается.

255,255,255 - все в порядке.

Благодарю за это наблюдение. Буду разбираться.

 
Реter Konow:

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

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

Ты вообще понимаешь что такой код

//-----------------------------------------------
   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 = Младшая_компонента;

на 100 процентов равносилен такому:

R = Исходный_R;
G = Исходный_G;
B = Исходный_B;

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

 
Реter Konow:

255,255,255 - все в порядке.

Это соответствует на 99% "виндоус оттенкам"?

 
Yury Kulikov:

Присоединюсь к "обвинениям", не выдержал :)

Хороший пример - как не надо программировать. Если таким образом написан весь ваш ГУИ, то мы нескоро его увидим. :(

Что ни строчка, то "шедевр": такое нагромождение ошибок и ляпов, одна надежда, что mql4 вывезет. Теперь стало понятно почему используется мт4.

Публикация таких кодов, и последующая реакция на критику, думаю это не уважение к аудитории форума. Вам не хотят зла - вам хотят помочь.

А по поводу сравнения алгоритмов, то можно сравнить и визуально. Вы же не предложили доказательства в цифрах, что ваш алгоритм дает оттенки на 99% близкие к "виндоус оттенкам".

Слева - как бы ваш подход, справа - Nikolai Semko. (Использован модифицированный скрипт  Nikolai Semko)


Спасибо, Юрий за участие и понимание сути вопроса а так же за наглядный пример. После ваших изменений на мой код приятнее стало смотреть.

только вот маленькое уточнение:

int x;//индекс исходного цвета в массиве оттенков
if(_mode==0) x=(clr.x[ArrayMaximum(clr.x,0,3)]+clr.x[ArrayMinimum(clr.x,0,3)])/2; // Светлота= (MAX+MIN)/2  Вариант из https://ru.wikipedia.org/wiki/HSL. Тот вариант к которому изначально стремился Петр.
if(_mode==1) x=(int)round((clr.rgb.b+clr.rgb.g+clr.rgb.r)/3.0); // мой вариант, который мне кажется более логичным и правильным
if(_mode==2) x=127;                                             // То, что в результате получилась у Петра из-за его алгоритмической путаницы. У него цветовой "сгусток" не гуляет, а стоит ровно по центру.
 
Nikolai Semko:

Спасибо, Юрий за участие и понимание сути вопроса а так же за наглядный пример. После ваших изменений на мой код приятнее стало смотреть.

только вот маленькое уточнение:

Может так :)

int ColorShades(uint _clr,uint& _shades[],int _mode=0)
{
   SuintRGB clr;
   if(ArrayResize(_shades,256)!=256) return(-1);   //ошибка resize()
   clr.clr=_clr; 
   int x;//индекс исходного цвета в массиве оттенков
   if(_mode==0) x=(ArrayMaximum(clr.x,3)+ArrayMinimum(clr.x,3))/2; // Светлота= (MAX+MIN)/2  Вариант из https://ru.wikipedia.org/wiki/HSL. Тот вариант к которому изначально стремился Петр.
   else if(_mode==1) x=(int)round((clr.rgb.b+clr.rgb.g+clr.rgb.r)/3.0); // мой вариант, который мне кажется более логичным и правильным
   else x=127;                                             // То, что в результате получилась у Петра из-за его алгоритмической путаницы. У него цветовой "сгусток" не гуляет, а стоит ровно по центру.
   double d, kr, kg, kb;
   if(x>0)
   {
      //движение от черного
      d=double(x);
      kr=clr.rgb.r/d;          
      kg=clr.rgb.g/d;
      kb=clr.rgb.b/d;
      for(int i=0; i<=x; i++)
      {
         clr.rgb.r=(uchar)fmin(255,kr*i);
         clr.rgb.g=(uchar)fmin(255,kg*i);
         clr.rgb.b=(uchar)fmin(255,kb*i);
         _shades[i]=clr.clr;
      }
   }
   if(x<255)
   {
      //движение от белого
      d=double(255-x);
      kr=(255-clr.rgb.r)/d;
      kg=(255-clr.rgb.g)/d;
      kb=(255-clr.rgb.b)/d;
      for(int i=255, j=0; i>x; i--, j++)
      {
         clr.rgb.r=(uchar)fmax(0,255.0-kr*j);
         clr.rgb.g=(uchar)fmax(0,255.0-kg*j);
         clr.rgb.b=(uchar)fmax(0,255.0-kb*j);
         _shades[i]=clr.clr;
      }
      if(x==0) _shades[0]=0;
   }
   return(x);
}
 
Nikolai Semko:

Ты вообще понимаешь что такой код

на 100 процентов равносилен такому:

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

Ну, это уже глупость от непонимания моего алгоритма. 

 
Yury Kulikov:

Может так :)

ну да.
только я вначале ошибся и уже исправил в предыдушем сообщении

if(_mode==0) x=(clr.x[ArrayMaximum(clr.x,0,3)]+clr.x[ArrayMinimum(clr.x,0,3)])/2;
 
Yury Kulikov:

Это соответствует на 99% "виндоус оттенкам"?

Да, есть ошибка. Незаметил. Достигает белого цвета к середине диапазона, хотя цвет принадлежит диапазону серого. Значит, к белому должен идти постепенно.

 
Nikolai Semko:

...

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

Вообще, удобно взять чей то проверенный код и будучи прикрытым его безупречностью указывать другим (которые ищут решение своим умом) насколько ты лучше. Не так ли, Николай?))