El lienzo es genial.

 

Me propuse una tarea: demostrar las capacidades de los gráficos personalizados a través de la clase CCanvas en un código corto.

Esto es lo que ha resultado.

Este script funciona tanto en MQL5 como en MQL4. Pero es mucho más rápido en MT5.

Cada fotograma es único y no se repite, es decir, el guión no es cíclico.

#include <Canvas\Canvas.mqh>

void OnStart()
  {
   ChartSetInteger(0,CHART_FOREGROUND,true);
   CCanvas C;
   int Width=(ushort)ChartGetInteger(0,CHART_WIDTH_IN_PIXELS);  // получаем Ширину окна
   int Height=(ushort)ChartGetInteger(0,CHART_HEIGHT_IN_PIXELS); // получаем Высоту окна
   if(!C.CreateBitmapLabel(0,0,"CanvasExamlple",0,0,Width,Height,COLOR_FORMAT_XRGB_NOALPHA)) // создаем канвас размером текущего окна
   Print("Error creating canvas: ",GetLastError()); 
   uint i=0,j=100000;
   int size=Width*Height;
   uchar h[25600];
   for (int w=0;w<25600;w++) 
   h[w]= uchar(128+128*sin(double(w)/256));//создаем массив для ускорения работы
   double X1=0,Y1=0,X2=0,Y2=0;
   while(!IsStopped())
     {
      int pos=int(i%size);
      if(pos==0)
        {
         C.Update();
         //Sleep(30);
         X1= Width-(sin((double)j/100)*(double)Width);
         Y1= Height-(cos((double)j/140)*(double)Height);
         X2= Width+(cos((double)j/80)*(double)Width);
         Y2= Height+(sin((double)j/20)*(double)Height);
         j++;
        }
      int X=pos%Width;
      int Y=int(pos/Width);
      double d= ((X1-X)*(X1-X)+(Y1-Y)*(Y1-Y))/(((X1-X)*(X1-X)+(Y1-Y)*(Y1-Y))+((X2-X)*(X2-X)+(Y2-Y)*(Y2-Y)));
      C.m_pixels[pos]=XRGB(h[int(d*11520)],h[int(d*17920)],h[int(d*6400)]);
      i++;
     }
   C.Destroy();
  }


Antes de compilar, mueve el array m_pixels[] de protected: a public en Canvas.mqh:

public:
   uint              m_pixels[];               // array of pixels

                     CCanvas(void);
                    ~CCanvas(void);
Archivos adjuntos:
Swirl.mq5  3 kb
Swirl.ex5  16 kb
 

¡Genial, seguro!

E incluso se puede utilizar para cosas útiles ;)

 
Andrey Khatimlianskii:

¡Genial, seguro!

E incluso se puede utilizar para cosas útiles ;)

Para que la gente empiece a usar Kanvas para cosas útiles, hay que empezar por mostrar cosas inútiles. :))

 
Nikolai Semko:

Tienes que mover el array m_pixels[] de protected: a public en el archivo Canvas.mqh antes de la compilación:

No es necesario cambiar nada en el SB.

class CCanvas2 : public CCanvas
{
private:
  int Pos;

public:
  CCanvas2* operator []( const int iPos )
  {
    this.Pos = iPos;
    
    return(&this);
  }
  
  void operator =( const uint Color )
  {
    this.m_pixels[this.Pos] = Color;
  }
};


CCanvas2 C;
//..
// C.m_pixels[pos]=XRGB(h[int(d*11520)],h[int(d*17920)],h[int(d*6400)]);
C[pos]=XRGB(h[int(d*11520)],h[int(d*17920)],h[int(d*6400)]);
 
fxsaber:

No tienes que cambiar nada en el SB.


¡Genial! :))

Pero, por desgracia, no es gratis.

Lo he comprobado. La ralentización general en MT5 fue de ~11%.

 
Nikolai Semko:

¡Genial! :))

Pero, por desgracia, no es gratis.

Lo he comprobado. La ralentización total en MT5 fue de ~11%.

Su caso utiliza el 1% de CCanvas. Pruébalo sin CCanvas. El código no será más complicado y la velocidad mejorará aún más.

 
fxsaber:

En su caso, se utiliza el 1% de CCanvas. Pruébalo sin CCanvas. El código no se complicará lo más mínimo y la velocidad aumentará aún más.

Por supuesto, también puedes prescindir de la clase CCanvas. Pero el código aumentará, mientras que la velocidad de procesamiento no mejorará, ya que todo lo que realmente uso de la clase CCanvas es la matriz de recursos gráficos m_pixels[] (y las funciones Update() y Destroy(), pero no serán de ninguna utilidad, y apenas ahorraremos dinero en ellas).

Pero un array sigue siendo un array. ¿Cómo puede hacerlo más rápido? No se puede. Simplemente la clase CCanvas se encarga de alguna rutina, cuando se crea un recurso, se actualiza (o más bien se recrea) y se elimina.

¿O estás diciendo que C.m_pixels[] no compila como acceso directo a un array? Creo que es directo. Sin ningún gesto intermedio. ¿O me equivoco?

Sería aún más lógico que los desarrolladores de esta clase metieran la etiqueta CreateBitmapLabel en el propio constructor de la clase para evitar que se pierda. Si creas una nueva instancia de la clase sin parámetros, entonces creas un lienzo con el tamaño en la ventana (como en mi caso), y si quieres, puedes especificar parámetros al crear una instancia de la clase. Yo mismo lo hice así.

 
Nikolai Semko:

Por supuesto, podría prescindir de la clase CCanvas. Pero el código aumentará, pero no habrá ganancia de velocidad, porque todo lo que uso de la clase CCanvas es el array de recursos gráficos m_pixels[] (y las funciones Update() y Destroy(), pero puedes obviarlas, porque no te ahorrarán nada).

Pero un array sigue siendo un array. ¿Cómo puede hacerlo más rápido? No se puede. Simplemente la clase CCanvas se encarga de alguna rutina, cuando se crea un recurso, se actualiza (o más bien se recrea) y se elimina.

¿O estás diciendo que C.m_pixels[] no compila como acceso directo a un array? Creo que es directo. Sin ningún gesto intermedio. ¿O me equivoco?

CCanvas es una envoltura para ResourceCreate. Así, por ejemplo, tienes 20 imágenes ya hechas en forma de matrices. Si quieres cambiarlos a través del canvas, tendrás que hacer un costoso ArrayCopy+Update.

Y si lo haces sin CCanvas, sólo necesitarás ResourceCreate+ChartRerdraw. He publicado varios trabajos de dibujo dinámico en kodobase. Allí era obvio que CCanvas no es bueno.

 
Nikolai Semko:

Tienes que mover el array m_pixels[] de protected: a public en el archivo Canvas.mqh antes de compilar:

¿Estásseguro de que PixelSet no te ayudará?

 
Rashid Umarov:

¿Estásseguro de que PixelSet no te ayudará?

Por supuesto, ayudará, pero será terriblemente lento. En primer lugar, una llamada a una función no es libre, porque los parámetros son pasados y almacenados (en PixelSet, esto ni siquiera se hace por referencia), todos los registros deben ser empujados a la pila y luego sacados de nuevo. En segundo lugar, la propia función comprueba si X e Y están dentro del rango especificado, y en tercer lugar, calcula el índice de la matriz. Y no necesito todo esto porque ya tengo un índice y en mi algoritmo no puedo salirme del rango.

 
Un gráfico de arco iris muy chulo. También me gustaría hacer que las velas bailaran al ritmo de la música y se retorcieran entre sí.
Razón de la queja: