Canvas - это круто! - страница 47

 
Maxim Kuznetsov:

тогда уж не круг на плоскости, а цилиндр в 3d :-) Курс выйдет по спирали. Если удачно разметить цилиндрические координаты, то довольно толковая вещь

Возможно.
 
Maxim Kuznetsov:

тогда уж не круг на плоскости, а цилиндр в 3d :-) Курс выйдет по спирали. Если удачно разметить цилиндрические координаты, то довольно толковая вещь

на самом деле реализовать это совсем не сложно. 2-5 строк кода дополнительно. Если до меня никто не сделает это, то, когда появиться свободная минута, сделаю.

Но здесь лучше иметь экран 4K

 
Maxim Kuznetsov:

тогда уж не круг на плоскости, а цилиндр в 3d :-) Курс выйдет по спирали. Если удачно разметить цилиндрические координаты, то довольно толковая вещь

https://www.mql5.com/en/code/27662

обратите внимание на скорость и размер кода. 
И это все без Direct X

 
Nikolai Semko:

https://www.mql5.com/en/code/27662

обратите внимание на скорость и размер кода. 
И это все без Direct X

Волшебно!

От чего зависит радиус?

Сложно ли кольцо сделать многоцветным?

Возможно, что такая визуализация будет полезна для оценки лучших 50 проходов при оптимизации, или всей оптимизации при уплотнении.

 
Nikolai Semko:

https://www.mql5.com/en/code/27662

обратите внимание на скорость и размер кода. 
И это все без Direct X

Просто, магия. !!!

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

 
Nikolai Semko:

https://www.mql5.com/en/code/27662

обратите внимание на скорость и размер кода. 
И это все без Direct X

+++
 

Спасибо всем!


Aleksey Vyazmikin:

Волшебно!

От чего зависит радиус?

Сложно ли кольцо сделать многоцветным?

Возможно, что такая визуализация будет полезна для оценки лучших 50 проходов при оптимизации, или всей оптимизации при уплотнении.

код этой 3D графики и управление вращением умещается весь в этой функции:

void Draw(double &c[]) {
   double _r=_Height/2-7;
   int Per=int(2*M_PI*_r);
   int X=_Width/2;
   int Y=_Height/2-5;
   double K=10*_Height;
   Canvas.Erase(0xFF000000);
   int Size =ArraySize(c);
   double max = c[ArrayMaximum(c,0)];
   double min = c[ArrayMinimum(c,0)];
   if (max-min<=0) return;
   double _a=2*M_PI/per*(_Width/2  - _MouseX + 5*per); // угол камеры по горизонтали (_MouseX  - текущая координата X указателя мышки)
   double _b=2*M_PI/per*(_Height/2 - _MouseY + 5*per); // угол камеры по вертикали   (_MouseY  - текущая координата Y указателя мышки)
   for (int i=0; i<Size; i++) {
      double r = _r*(0.3+0.7*(c[i]-min)/(max-min));
      double a = 2*M_PI/per*i;
      double z =r -r*2*double(i)/Size;
      double x = cos(a)*r;
      double y = sin(a)*r;
      double R=sqrt(x*x+y*y+z*z);
      double x1=x*cos(_a)+z*sin(_a);
      double z1=-x*sin(_a)+z*cos(_a);
      double y1=y*cos(_b)+z1*sin(_b);
      double z2=-y*sin(_b)+z1*cos(_b);
      z2=z2+_r;
      x=X+K*x1/(z2+K);
      y=Y+K*y1/(z2+K);
      _PixelSet((int)x,(int)y,Grad(double(i)/Size));
   }
   Canvas.Update();
}

На входе этой функции только массив цены. В коде сможет разобраться даже школьник. Одномерный массив цены преобразуется в 3 мерный массив точек. В котором измерение z- это по сути номер элемента массива, В плоскости XY цена представлена в полярной системе кооднитат, где расстояние r=sqrt( x 2+y 2) до центра (0,0) это и есть значение цены.

За выбор цвета отвечает эта функция:

uint Grad(double p) {
   static uint Col[6]= {0xFF0000FF,0xFFFF00FF,0xFFFF0000,0xFFFFFF00,0xFF00FF00,0xFF00FFFF};
   if(p>0.9999) return Col[5];
   if(p<0.0001) return Col[0];
   p=p*5;
   int n=(int)p;
   double k=p-n;
   argb c1,c2;
   c1.clr=Col[n];
   c2.clr=Col[n+1];
   return ARGB(255,c1.c[2]+uchar(k*(c2.c[2]-c1.c[2])+0.5),
               c1.c[1]+uchar(k*(c2.c[1]-c1.c[1])+0.5),
               c1.c[0]+uchar(k*(c2.c[0]-c1.c[0])+0.5));
}

на входе которой p - это число от 0 до 1, а на выходе выбранный градиентный цвет. Сам скелет цветового шаблона в данном случае состоит из 6 цветов (массив Col)

С цветом полная свобода, раскрашивайте как хотите и что хотите

 
Aleksey Panfilov:

Просто, магия. !!!

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

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

 
Nikolai Semko:

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

Николай, вопрос по вашей библиотеке как снимать данные в советник?

 
Martingeil:

Николай, вопрос по вашей библиотеке как снимать данные в советник?

я не понял вопрос. iCanvas - это графическая библиотека.
Вы наверное спрашивате, как считывать данные в советник, если вы создаете индикатор с визуализацией линий через iCanvas и оставляете его безбуфферным? Тогда, пожалуйста, выражайтесь яснее.

Во - первых, Вам никто не запрещает создавать буферные индикаторные массивы, как в обычном индикаторе, а просто делать их INDICATOR_CALCULATIONS, а дальше в обычном порядке осуществлять доступ к данным через iCustom.

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

Разбирайтесь с ресурсами. Это не очень просто, но очень важный инструмент для передачи данных. Можно создать собственные библиотеки, причем более эффективные чем классические индикаторные буферные массивы.

Лично я использую свои разработки, которые не публикую. Они удобнее и рациональнее работают, чем доступ через iCustom. Все реализованно именно через ресурсы.

Причина обращения: