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

 
Vladislav Andruschenko:


Ну названия на английском придумали не просто так. 

Я могу Вам привести еще один такой пример, когда русские названия убьют ваш код:

Вы передаете код заказчику, у которого нет кириллицы. Все. .... все пропало..... :-) 

А заказчику нужен именно код, или решение?

 
Реter Konow:

А заказчику нужен именно код, или решение?

вот поэтому нужно определится с целью и конечными пользователями. 

Поставьте себя на место пользователя и забудьте все, что Вы делали: что будет чувствовать пользователь? 

будем ли ему все понятно? 

 
Vladislav Andruschenko:

вот поэтому нужно определится с целью и конечными пользователями. 

Поставьте себя на место пользователя и забудьте все, что Вы делали: что будет чувствовать пользователь? 

будем ли ему все понятно? 

Cогласен. Я ведь пишу на двух языках. Могу чисто на английском.  

 
Реter Konow:

Вы, как англоязычный человек, смело игнорьте мое решение. Там мало английских слов.  

Кстати, раз уж вы так хорошо разбираетесь с английским кодом, помогите разобрать код предложенный Николаем Семко:

Честно говоря, не понял как он работает. Тут много коротких английских слогов. Как раз, то что вам нравится.

В том-то и дело, что английский Я примерно знаю где-то на 30%, и только технический, но не разговорный.

В программировании слов всего пару десятков, и их запомнить можно написав буквально 1-2 программы.

P.S. Код который вы выложили, там всего 5 переменных, как с ними можно не разобраться?

 
Vitaly Muzichenko:

В том-то и дело, что английский Я примерно знаю где-то на 30%, и только технический, но не разговорный.

В программировании слов всего пару десятков, и их запомнить можно написав буквально 1-2 программы.

P.S. Код который вы выложили, там всего 5 переменных, как с ними можно не разобраться?

Ну, я насчитал 30 переменных в своем коде (в главной функции). А до скольки вы считаете? (шутка).

30% технического английского - это очень сильно. Вы знаете, насколько богат технический английский?

Пара десятков слов в программировании? Теперь понятно, почему мы друг друга не понимаем.))


зы. Если вы имеете ввиду код Николая, то просветите, как он работает. 

 
В общем, тему можно закрывать. Рад, если код кому то окажется полезным. Ну а нет, так нет...
 
Реter Konow:

Кстати, судя по картинке, разложение цвета здесь не полное. Только половина. Диапазон должен простираться от абсолютно белого до абсолютно черного, через все оттенки конкретного цвета.

Да, ты прав. 

Я попробовал реализовать это и проанализировать  и визуализировать твой код.

Вот что из этого получилось:

#include <Canvas\iCanvas.mqh> //https://www.mql5.com/ru/code/22164

union rgb {uint clr; uchar c[4];};
void OnStart()
  {
   rgb c,cc;
   double d=5;
   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;
      uint CLR[];
      ulong t=GetMicrosecondCount();
      Gradient(c.clr,CLR,W.Height);
      t=GetMicrosecondCount()-t;
      for(int y=0; y<W.Height; y++)
        {
         Canvas.LineHorizontal(0,W.Width-1,y,ColorToARGB(CLR[y],240));
         c.clr=CLR[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(W.Width/2-80,W.Height/2-50,W.Width/2+80,W.Height/2+50,ColorToARGB(cc.clr,240));
      Canvas.CurentFont("Tahoma",20,22,ColorToARGB(~cc.clr)); // 20 -  размер шрифта, 22 - межстрочный интервал
      Canvas.TextPosition(W.Width/2-70,W.Height/2-40); // Стартовая позиция для шрифта в пикселях
      Canvas.Comm("Текущий цвет:");
      Canvas.Comm("R = "+string(cc.c[2]));
      Canvas.Comm("G = "+string(cc.c[1]));
      Canvas.Comm("B = "+string(cc.c[0]));
      Canvas.CurentFont("Times New Roman",30);
      Canvas.TextPosition(25.0,10.0);  // Стартовая позиция для шрифта в процентах от размеров экрана
      Canvas.Comm("Время формирования градиентного массива из "+string(W.Height)+" элементов = "+string(t)+" микросекунд");
      ChartChanged(); // на всякий случай контролируем изменение размеров окна, т.к. это скрипт (в индикаторах и экспертах это происходит автоматически)
      Canvas.Update();
      d+=0.01;
      Sleep(30);
     }
  }
//+------------------------------------------------------------------+

void Gradient(uint clr,uint &arr[],uint size)
  {
   if(size==0) return;
   ArrayResize(arr,size);
   rgb c;
   c.clr=clr;
   uchar R=c.c[2],G=c.c[1],B=c.c[0];
   uint i=0, tone=uint((size-1)*(((double)R+(double)G+(double)B)/765.0)+0.4999);
   double kR,kG,kB;
   if(tone!=0)
     {
      kR=(double)R/tone;
      kG=(double)G/tone;
      kB=(double)B/tone;
      for(i=0;i<=tone;i++)
        {
         c.c[2]=uchar(i*kR+0.4999);
         c.c[1]=uchar(i*kG+0.4999);
         c.c[0]=uchar(i*kB+0.4999);
         arr[i]=c.clr;
        }
     }
   if(tone!=(size-1))
     {
      kR=(double)(255-R)/(size-i);
      kG=(double)(255-G)/(size-i);
      kB=(double)(255-B)/(size-i);
      for(uint j=1;i<size;i++,j++)
        {
         c.c[2]=uchar(R+j*kR+0.4999);
         c.c[1]=uchar(G+j*kG+0.4999);
         c.c[0]=uchar(B+j*kB+0.4999);
         arr[i]=c.clr;
        }
     }
  }

Твой вариант


мой вариант:


Поясню:

Белая линия это линия тона (сумма цветов R+B+G) - в идеале это должна быть строго прямая диагональная линия. У меня это реализовано, у тебя нет.

Красная, синяя и зеленая линии — это линии соотношения цветов. Назовем их гармониками спектра.  В идеале это должны быть вертикальными. Но это осуществить невозможно после того как изначально максимальный цвет стал 255. Но зато можно достигнуть ситуации, когда это не будет точек перегиба (отмечено красными стрелками) а сделать плавную дугу. Тогда градиент будет выглядеть без "сгустков". Данная проблема существует и в твоем и моем алгоритмах. Это можно исправить, но я пока не вижу смысла, поэтому жалко времени. На практике мне градиент нужен от одного цвета до другого. Это легко реализуется со строго вертикальными гармониками спектра (распушение гармоники вверху это нормально, т.к. это следствие округления). В данной же задаче градиент идет от черного  до белого через третий цвет, поэтому эти перегибы и существуют.

Странно, я был уверен, что ты пишешь на MQL5. Но кроме того, что была сама программа 4-ки, но у тебя еще и стиль программирования 4-ки. Попытался твой алгоритм перенести на 5-ку и ничего не получилось, т.к. рисует вообще какие-то цветные полосы. Это скорей всего происходит из-за путаницы с областью видимости переменных, но исправить ввиду того что код не поддается отладке крайне тяжело и я махнул рукой. Я понимаю, что ты привык к своему стилю программирования и мой стиль тебе не понятен. Это взаимно, т.к. я привык не читать программу как книгу, а видеть структуру программы. А у тебя кроме невозможности отладки и понять в какой момент определения переменной, длинные имена переменных заполоняют собой 90% текста программы, в результате чего структура программы теряется, растворяясь в этих длинных именах переменных цвета барби. В общем твой код лично для меня воспринимается как какой-то садомазо.  

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

И попробуй освоить union – очень полезная вещь.

Чтобы лучше понять о чем я говорил, стоит запустить оба скрипта, которые я прикрепил с твоим алгоритмом (MQL4) и моим (MQL5).


Так же у тебя встречаются такие казусы:

только пока не понял, это проблема тормознутости MT4 и ошибка твоего алгоритма.

Файлы:
 
Nikolai Semko:


1. Николай, даже сравнив две первые картинки которые ты привел, сразу можно увидеть что над твоим вариантом висит серая дымка. Присмотрись внимательно. А в моем варианте цвет значительно ярче. Ты считаешь что твой вариант лучше передает цвет?  

2. За эталон я брал цветовую палитру виндоус. Я добился 99%-ного совпадения цветов. Проверь свои цвета на совпадения с цветами виндоус. Распечатай массив с оттенками как сделал я. Потом открой свойства графика и палитру. Введи в окошки значения компонентов исходного цвета и далее, веди ползунок вверх вниз. Цифры будут менятся. Ты ищи эти цифры в своей распечатке и смотри насколько они совпадают.

3. Я понимаю, что конкретная реализация может варьироваться. Специально на скорость свой алгоритм не проверял и ради скорости его не оптимизировал. Возможно, твое решение дает большую скорость. Не буду отрицать. 

4. В оптике есть понятие призмы. Преломления света. Я отталкивался именно от этой парадигмы. Я построил график 256*256 (от 0 до 255). Далее, строил линии. Нашел ось преломления цвета. Она находится в центре графика. Каждая компонета - это кривая состоящая из двух отрезков. Всего цвет имеет три кривые линии, каждая из которых преломляется в центре графика делясь на два отрезка. Каждый отрезок имеет свой угол. Исходный цвет имеет координату на графике. Его можно найти среди его оттенков. Моя задача была, - найти исходный цвет, определить углы всех шести отрезков и получить значения каждой компонеты на протяжении ее линии.

5. Тангенсы - это соотношения прилежащих катетов к противолежащим. Необходимы для расчета углов отрезков и вычесления высоты противолежащих катетов (которая есть значение компонеты в конкретном тоне цвета). 

6. Что касается стилей программирования - предлогаю это не обсуждать. К сути темы это отношения не имеет.

7. Насчет казусов - возможно они есть. Но пока что мне не попались. Поэтому, не знаю.


Кстати, расскажи как работает разложение цвета в твоем варианте. Я не до конца понял.

Просмотр и настройка графиков - Графики котировок, технический и фундаментальный анализ - MetaTrader 5
Просмотр и настройка графиков - Графики котировок, технический и фундаментальный анализ - MetaTrader 5
  • www.metatrader5.com
Графики в торговой платформе отображают изменение котировок финансовых инструментов во времени. Они необходимы для проведения технического анализа и работы советников. Они позволяют трейдерам наглядно следить за котировками валют и акций в режиме реального времени и моментально реагировать на любое изменение ситуации на финансовых рынках...
 
Nikolai Semko:


только пока не понял, это проблема тормознутости MT4 и ошибка твоего алгоритма.

Насчет разницы в скорости алгоритмов:

1. Твой алгоритм заполняет массив uint, а мой - массив string.  (мне нужен именно string, чтобы легко вычленять нужные компоненты из оттенка и далее, работать с ними). Разницу в скорости заполнения обоих типов массивов ты сможешь увидеть из приведенного ниже скрипта.

2. Твой алгоритм работает на МТ5, а мой на МТ4. Разница в скорости заполнения массивов на этих платформах обсуждалось мною здесь - https://www.mql5.com/ru/forum/222333. Из приведенного ниже скрипта, ты сам увидешь эту разницу. Поставь его на обоих платформах и сравни.

//+------------------------------------------------------------------+
//|                        Проверка скорости заполнения массивов.mq5 |
//|                                                      Peter Konow |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Peter Konow"
#property link      "https://www.mql5.com"
#property version   "1.00"
//+------------------------------------------------------------------+
//+------------------------------------------------------------------+
int int_Array[30000];
string string_Array[30000];
//+------------------------------------------------------------------+
//| Script program start function                                    |
//+------------------------------------------------------------------+
void OnStart()
  {
   ulong t1 = GetMicrosecondCount();
   //--------------------------
   for(int b1 = 0; b1 < 30000; b1++)int_Array[b1] = 1;
   //--------------------------
   ulong t2 = GetMicrosecondCount();
   //--------------------------
   int q = int_Array[0] + int_Array[1];//Этот код нужен, иначе компилятор не заполняет массив.
   //--------------------------
   Print("//----------------------------------------------------------------------------------");
   Print(" Время заполнения массива      int:  ",t2-t1);
   
 
 
   ulong t3 = GetMicrosecondCount();
   //--------------------------
   for(int b2 = 0; b2 < 30000; b2++)string_Array[b2] = "1";
   //--------------------------
   ulong t4 = GetMicrosecondCount();
   //--------------------------
   int q2 = int_Array[0] + int_Array[1];//Этот код нужен, иначе компилятор не заполняет массив.
   //--------------------------
   Print(" Время заполнения массива string:  ",t4-t3);   
   Print("//----------------------------------------------------------------------------------");
   
   Alert(q + q2);//Этот код нужен, иначе компилятор не заполняет массив.
  }
//+------------------------------------------------------------------+

Результаты замера скорости заполнения 30-ти тысяч ячеек массивов int  и  string  на платформах МТ4 и MT5 (мс):

MT5
2018.10.11 13:29:24.502 Замер скорости заполнения массивов (RTS-12.18,H1)  Время заполнения массива string:  464
2018.10.11 13:29:24.502 Замер скорости заполнения массивов (RTS-12.18,H1)  Время заполнения массива    int:  14

MT4
2018.10.11 13:30:39.199 Замер скорости заполнения массивов GBPUSD,M30:     Время заполнения массива string:  692
2018.10.11 13:30:39.199 Замер скорости заполнения массивов GBPUSD,M30:     Время заполнения массива    int:  363

Как ты видишь, мой алгоритм работает медленнее по двум причинам: 

  1. Он заполняет массив string а не uint.
  2. Ты его проверял только на МТ4. Скорость заполнения массивов между платформами может разниться в десятки раз.
P.S. Помимо этого, мой алгоритм может возвращать номер ячейки массива, в которой находится исходный цвет. Это помогает создавать градиент. Ведь нужно знать от какой ячейки двигаться влево или вправо.
MT5 vs MT4. Скорость заполнения массивов.
MT5 vs MT4. Скорость заполнения массивов.
  • 2017.12.12
  • www.mql5.com
Возникла необходимость замерить и сравнить скорость заполнения локальных и глобальных массивов на МТ4 и МТ5...
 
Реter Konow:

Насчет разницы в скорости алгоритмов:

1. Твой алгоритм заполняет массив uint, а мой - массив string.  (мне нужен именно string, чтобы легко вычленять нужные компоненты из оттенка и далее, работать с ними). Разницу в скорости заполнения обоих типов массивов ты сможешь увидеть из приведенного ниже скрипта.

2. Твой алгоритм работает на МТ5, а мой на МТ4. Разница в скорости заполнения массивов на этих платформах обсуждалось мною здесь - https://www.mql5.com/ru/forum/222333. Из приведенного ниже скрипта, ты сам увидешь эту разницу. Поставь его на обоих платформах и сравни.

Результаты замера скорости заполнения 30-ти тысяч ячеек массивов int  и  string  на платформах МТ4 и MT5 (мс):

Как ты видишь, мой алгоритм работает медленнее по двум причинам: 

  1. Он заполняет массив string а не uint.
  2. Ты его проверял только на МТ4. Скорость заполнения массивов между платформами может разниться в десятки раз.
P.S. Помимо этого, мой алгоритм может возвращать номер ячейки массива, в которой находится исходный цвет. Это помогает создавать градиент. Ведь нужно знать от какой ячейки двигаться влево или вправо.
Я убрал стринги из твоего алгоритма. Для меня была загадка зачем ты их использовал. Загляни в код, как бы я тогда выводил реальный цвет.  У тебя куча ненужных проверок, ты используешь такие функции как тангенс, сортировка массива, я же только +-*/. Мт4 медленнее, это понятно, но не в 30 раз. 
Хорошо, чуть позже засуну свой алгоритм на 4 и посмотрю. Зачем ты вообще юзаешь 4-ку? Для графического интерфейса 4 совсем не годиться. У нее даже ресурсы не читаются. С 4 на 5 код переделывать гораздо сложнее, чем наоборот.
Причина обращения: