The function of decomposing color into shades. - page 7

 
Vladislav Andruschenko:


Well, English names were invented for a reason.

I can give you another example where Russian names will kill your code:

You give your code to a customer who does not have Cyrillic. That's it. .... all gone..... :-)

And does the customer need the code, or the solution?

 
Реter Konow:

Does the customer want the code or the solution?

that's why you need to decide on the target and the end users.

Put yourself in the user's shoes and forget everything you did: how will the user feel?

Will everything make sense to him or her?

 
Vladislav Andruschenko:

that's why you need to decide on the target and the end users.

Put yourself in the user's shoes and forget everything you did: how will the user feel?

Will he or she understand everything?

I agree. I do write in two languages. I can do it purely in English.

 
Реter Konow:

You, as an English speaker, feel free to ignore my decision. There are few English words there.

By the way, since you are so good with English code, please help me with the code proposed by Nikolay Semko:

Honestly, I don't understand how it works. It has a lot of short English syllables. Just what you like.

That's the thing I know about 30% of English, and only technical, not conversational.

In programming, there are only a couple dozen words, and you can memorize them after writing literally 1-2 programs.

P.S. The code you posted, there are only 5 variables, how can they not understand?

 
Vitaly Muzichenko:

That's the thing, I know about 30% of English, and only technical, not conversational.

In programming there are only a couple of dozens of words, and they can be memorized by writing literally 1-2 programs.

P.S. The code you posted there are only 5 variables, how can you not understand them?

Well, I counted 30 variables in my code (in the main function). And how many do you count to? (just kidding).

30% technical English is very strong. Do you know how rich technical English is?

A couple of dozen words in programming? Now I see why we don't understand each other)).


zy. If you mean Nikolai's code, enlighten how it works.

 
All in all, the subject can be closed. I'm glad if someone finds the code useful. If not, then no...
 
Реter Konow:

By the way, judging from the picture, the colour decomposition here is not complete. Only half. The range should extend from completely white to completely black, through all the shades of a particular colour.

Yes, you're right.

I tried to implement it and analyze and visualize your code.

Here is what came out of it:

#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;
        }
     }
  }

Your variant


my variant:


Let me explain:

The white line is the tone line (sum of colours R+B+G) - ideally it should be a straight diagonal line. I have it implemented, you don't.

The red, blue and green lines are lines of colour ratio. Let's call them harmonics of the spectrum. Ideally they should be vertical. But it is impossible to realise it after the initial maximum colour became 255. But it is possible to reach a situation when it will not be points of inflection (marked by red arrows) and to make a smooth arc. Then the gradient will look without "clumps". This problem exists in both your and my algorithms. It can be fixed, but I don't see the point yet, so it's a waste of time. In practice I need a gradient from one colour to another. This is easily implemented with strictly vertical harmonics of the spectrum (the blurring of the harmonic at the top is normal, as it is a consequence of rounding). In this problem, however, the gradient goes from black to white through a third colour, which is why these kinks exist.

Strange, I was sure you were writing in MQL5. But besides the 4's program itself, you also have the 4's programming style. I tried to transfer your algorithm to 5 but it did not work, because it only displays some colour stripes. This most likely happens because of confusion with scope of variables, but to fix it because the code is not amenable to debugging is extremely difficult, so I gave up. I understand that you are used to your programming style and you don't understand my style. It's mutual because I'm used to seeing a program's structure instead of reading it like a book. And in your code it's impossible to debug and understand at what moment of variable definition, the long variable names occupy 90% of the program text, as a result of which the program structure is lost, dissolving in these long barbie-colored variable names. All in all, your code looks to me personally like some kind of S&M.

In addition, your algorithm turned out to be dozens of times slower, and the reason is not even MQL4. I could not figure it out. What tangents, what triangles when there is only RGB?

And try to master union - very useful thing.

To better understand what I mean, you should try to run both scripts I attached with your algorithm (MQL4) and mine (MQL5).


You also have such mishaps:

only I don't understand it yet, is it a problem of MT4 sluggishness or a bug in your algorithm.

Files:
 
Nikolai Semko:


1. Nikolai, even comparing the first two pictures you cited, you can immediately see that there is a grey haze hanging over your version. Look closely. And in my version the colour is much brighter. Do you think that your version conveys the colour better?

2. I took the Windows colour palette as a reference. I got a 99% colour match. Check your colours to see if they match with Windows. Print out an array of shades like I did. Then open the chart properties and the palette. Enter in windows of component values of initial colour and then move the slider up and down. The numbers will change. You look for these numbers on your printout and see how well they match.

3. I understand that the specific implementation may vary. I haven't checked my algorithm specifically for speed, and I haven't optimized it for speed. Your solution may appear to give you a better speed. I won't deny it.

4. There is a notion of a prism in optics. There is a notion of light refraction. I was starting from this very paradigm. I plotted 256*256 (from 0 to 255). Then I plotted lines. I found the axis of refraction of colour. It is in the centre of the graph. Each component is a curve consisting of two segments. In total the colour has three curved lines, each of which is refracted in the centre of the graphic, dividing into two segments. Each segment has its own angle. The original colour has a coordinate on the graph. It can be found among its shades. My task was to find the initial colour, determine the angles of all six segments and get the values of each component along its line.

5. Tangents are ratios of adjoining cathetuses to opposing ones. It is necessary for calculation of angles of segments and calculation of height of the opposing cathetuses (which is the value of a component in a concrete tone of colour).

6. As for the programming styles - I suggest that we not discuss this. To the essence of the topic is not relevant.

7. About mishaps - perhaps they are. But I haven't come across them yet. Therefore I do not know.


By the way, tell me how colour decomposition works in your version. I don't fully understand it.

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


I just don't get it yet, is it a problem of MT4 slowness or a bug in your algorithm.

About the difference in speed of the algorithms:

1. Your algorithm fills uint array , while mine fills string array. (I need exactly string, to easily extract the necessary components from the shade and then work with them). You can see the difference in the speed of filling both types of arrays from the script below.

2. your algorithm works on МТ5, and mine on МТ4. The difference in array filling speed on these platforms was discussed by me here -https://www.mql5.com/ru/forum/222333. From the script below you can see the difference yourself. Put it on both platforms and compare.

//+------------------------------------------------------------------+
//|                        Проверка скорости заполнения массивов.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);//Этот код нужен, иначе компилятор не заполняет массив.
  }
//+------------------------------------------------------------------+

I measured the speed of 30 000 cells of int and string arrays on MT4 and MT5 (ms):

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

As you can see, my algorithm is slower for two reasons:

  1. It fills the string array and not the uint array.
  2. You only tested it on MT4. The speed of filling arrays between platforms can vary dozens of times.
P.S. Besides, my algorithm can return the number of array cell where the original colour is located. It helps to create a gradient. After all, you need to know from which cell to move left or right.
MT5 vs MT4. Скорость заполнения массивов.
MT5 vs MT4. Скорость заполнения массивов.
  • 2017.12.12
  • www.mql5.com
Возникла необходимость замерить и сравнить скорость заполнения локальных и глобальных массивов на МТ4 и МТ5...
 
Реter Konow:

About the difference in the speed of the algorithms:

1. your algorithm fills a uint array , while mine fills a string array. (I need string to easily extract the necessary components from the shade and then work with them). You can see the difference in the speed of filling both types of arrays from the script below.

2. your algorithm works on МТ5, and mine on МТ4. The difference in array filling speed on these platforms was discussed by me here -https://www.mql5.com/ru/forum/222333. From the script below you can see the difference yourself. Put it on both platforms and compare.

I measured the speed of 30 000 cells of int and string arrays on MT4 and MT5 (ms):

As you can see, my algorithm is slower for two reasons:

  1. It fills the string array and not the uint array.
  2. You only tested it on MT4. The speed of filling arrays between platforms can vary dozens of times.
P.S. Besides, my algorithm can return the number of array cell where the original colour is located. It helps to create a gradient. After all, you need to know from which cell to move left or right.
I took the thongs out of your algorithm. It was a mystery to me why you used them. Look in the code, how would I output the real colour then. You have a lot of unnecessary checks, you use functions like tangent, array sorting, I only +-*//. Mt4 is slower, that's understandable, but not 30 times slower.
Ok, I'll put my algorithm on 4 later and see. Why are you even using 4? For a GUI, 4's no good at all. It doesn't even read resources. From 4 to 5, it's much more difficult to redo the code than the other way around.
Reason: