A lona é legal!

 

Eu me propus uma tarefa: demonstrar as capacidades dos gráficos personalizados através da classe CCanvas em um código curto.

Eis o que resultou disso.

Este script funciona tanto na MQL5 quanto na MQL4. Mas é muito mais rápido no MT5.

Cada quadro é único e não se repete, ou seja, o roteiro não é 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, mover o array m_pixels[] de protegidos: para o público em Canvas.mqh:

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

                     CCanvas(void);
                    ~CCanvas(void);
Arquivos anexados:
Swirl.mq5  3 kb
Swirl.ex5  16 kb
 

Legal, com certeza!

E pode até ser usado para coisas úteis ;)

 
Andrey Khatimlianskii:

Legal, com certeza!

E pode até ser usado para coisas úteis ;)

Para que as pessoas comecem a usar Kanvas para coisas úteis, você precisa começar mostrando coisas inúteis. :))

 
Nikolai Semko:

Você precisa mover o array m_pixels[] de protegidos: para público no arquivo Canvas.mqh antes da compilação:

Você não precisa mudar nada na 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:

Você não precisa mudar nada na SB.


Legal! :))

Mas infelizmente, não é grátis.

Verifiquei. A desaceleração geral na MT5 foi de ~11%.

 
Nikolai Semko:

Legal! :))

Mas infelizmente, não é grátis.

Verifiquei. A desaceleração total na MT5 foi de ~11%.

Seu caso utiliza 1% da CCanvas. Experimente sem CCanvas. O código não será nem um pouco mais complicado e a velocidade irá melhorar ainda mais.

 
fxsaber:

No seu caso, 1% é utilizado a partir do CCanvas. Experimente sem CCanvas. O código não será um pouco mais complicado e a velocidade será ainda mais rápida.

É claro que você também pode prescindir da classe CCanvas. Mas o código vai aumentar, enquanto a velocidade de processamento não vai melhorar, uma vez que tudo que eu realmente uso da classe CCanvas é m_pixels[] array de pixels de recursos gráficos (e funções Update() e Destroy(), mas eles não serão de qualquer utilidade, e mal vamos economizar dinheiro neles).

Mas uma matriz ainda é uma matriz. Como você pode fazer isso mais rápido? Você não pode. Apenas a classe CCanvas cuida de alguma rotina, quando você cria um recurso, atualiza-o (ou melhor, recria-o) e o apaga.

Ou você está dizendo que a C.m_pixels[] não se compila como acesso direto ao array? Eu acho que é direto. Sem nenhum gesto intermediário. Ou eu estou errado?

Seria ainda mais lógico para os desenvolvedores desta classe empurrar o CreateBitmapLabel para dentro do próprio construtor da classe para evitar que ele se aproxime. Se você criar uma nova instância da classe sem parâmetros, então você cria uma tela com o tamanho na janela (como no meu caso), e se você quiser, você pode especificar parâmetros ao criar uma instância da classe. Eu mesmo o fiz dessa maneira.

 
Nikolai Semko:

Claro, eu poderia prescindir da aula de CCanvas. Mas o código vai aumentar, mas não haverá ganho de velocidade, porque tudo que eu uso da classe CCanvas é a matriz de recursos gráficos m_pixels[] (e funções Update() e Destroy(), mas você pode negligenciá-los, porque não economizarão dinheiro).

Mas uma matriz ainda é uma matriz. Como você pode fazer isso mais rápido? Você não pode. Apenas a classe CCanvas cuida de alguma rotina, quando você cria um recurso, atualiza-o (ou melhor, recria-o) e o apaga.

Ou você está dizendo que a C.m_pixels[] não se compila como acesso direto ao array? Eu acho que é direto. Sem nenhum gesto intermediário. Ou eu estou enganado?

CCanvas é um invólucro para ResourceCreate. Assim, por exemplo, você tem 20 imagens prontas sob a forma de matrizes. Se você quiser mudá-los via tela, você terá que fazer o caro ArrayCopy+Update.

E se você fizer isso sem CCanvas, você precisará apenas de ResourceCreate+ChartRerdraw. Coloquei vários trabalhos de desenho dinâmico na kodobase. Era óbvio ali que o CCanvas não é bom.

 
Nikolai Semko:

Você precisa mover o array m_pixels[] de protegidos: para público no arquivo Canvas.mqh antes de compilar:

Você tem certeza de que a PixelSet não vai ajudar?

 
Rashid Umarov:

Você tem certeza de que a PixelSet não vai ajudar?

É claro que isso ajudará, mas será terrivelmente lento. Primeiro, uma chamada de função não é livre, porque os parâmetros são passados e salvos (no PixelSet, não é nem por referência), todos os registros devem ser empurrados para a pilha e depois puxados novamente para fora. Em segundo lugar, a própria função verifica se X e Y se enquadram na faixa especificada, e em terceiro lugar, calcula o índice da matriz. E eu não preciso de tudo isso porque já tenho um índice e em meu algoritmo não posso sair do alcance.

 
Gráfico de arco-íris frio! Eu também gostaria de fazer as velas dançarem ao som da música e girarem umas com as outras!
Razão: