La toile est cool !

 

Je me suis fixé une tâche : démontrer les capacités des graphiques personnalisés via la classe CCanvas dans un code court.

Voici ce qui en est ressorti.

Ce script fonctionne à la fois dans MQL5 et MQL4. Mais il est beaucoup plus rapide sur MT5.

Chaque image est unique et ne se répète pas, c'est-à-dire que le script n'est pas cyclique.

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


Avant de compiler, déplacez le tableau m_pixels[] de protected : à public dans Canvas.mqh :

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

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

Cool, c'est sûr !

Et peut même être utilisé pour des choses utiles ;)

 
Andrey Khatimlianskii:

Cool, c'est sûr !

Et peut même être utilisé pour des choses utiles ;)

Pour que les gens commencent à utiliser Kanvas pour des choses utiles, il faut commencer par montrer des choses inutiles. :))

 
Nikolai Semko:

Vous devez déplacer le tableau m_pixels[] de protected : à public dans le fichier Canvas.mqh avant la compilation :

Vous n'avez pas besoin de changer quoi que ce soit dans le 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:

Vous n'avez pas besoin de changer quoi que ce soit dans le SB.


Cool ! :))

Mais malheureusement, ce n'est pas gratuit.

Je l'ai vérifié. Le ralentissement total sur MT5 était de ~11%.

 
Nikolai Semko:

Cool ! :))

Mais malheureusement, ce n'est pas gratuit.

Je l'ai vérifié. Le ralentissement total sur MT5 était de ~11%.

Votre cas utilise 1% de CCanvas. Sans CCanvas, faites un essai. Le code ne sera pas le moins du monde plus compliqué et la vitesse sera encore améliorée.

 
fxsaber:

Dans votre cas, on utilise 1% de CCanvas. Essayez-le sans CCanvas. Le code ne sera pas un peu plus compliqué et la vitesse sera encore plus rapide.

Bien sûr, vous pouvez aussi vous passer de la classe CCanvas. Mais le code va augmenter, alors que la vitesse de traitement ne s'améliorera pas, puisque tout ce que j'utilise réellement de la classe CCanvas est le tableau m_pixels[] de pixels de ressources graphiques (et les fonctions Update() et Destroy(), mais elles ne seront d'aucune utilité, et nous économiserons à peine de l'argent dessus).

Mais un tableau reste un tableau. Comment pouvez-vous le rendre plus rapide ? Tu ne peux pas. La classe CCanvas se charge simplement de certaines routines, lorsque vous créez une ressource, la mettez à jour (ou plutôt la recrée) et la supprimez.

Ou bien vous voulez dire que C.m_pixels[] n'est pas compilé comme un accès direct à un tableau? Je pense que c'est direct. Sans aucun geste intermédiaire. Ou ai-je tort ?

Il serait encore plus logique pour les développeurs de cette classe de pousser le CreateBitmapLabel dans le constructeur de la classe elle-même pour éviter le looming. Si vous créez une nouvelle instance de la classe sans paramètres, alors vous créez un canvas avec la taille dans la fenêtre (comme dans mon cas), et si vous voulez, vous pouvez spécifier des paramètres lors de la création d'une instance de la classe. Je l'ai fait de cette façon moi-même.

 
Nikolai Semko:

Bien sûr, je pourrais me passer de la classe CCanvas. Mais le code augmentera, mais il n'y aura pas de gain de vitesse, car tout ce que j'utilise de la classe CCanvas est le tableau de ressources graphiques m_pixels[] (et les fonctions Update() et Destroy(), mais vous pouvez les négliger, car elles ne feront pas d'économies).

Mais un tableau reste un tableau. Comment pouvez-vous le rendre plus rapide ? Tu ne peux pas. La classe CCanvas se charge simplement de certaines routines, lorsque vous créez une ressource, la mettez à jour (ou plutôt la recrée) et la supprimez.

Ou bien vous dites que C.m_pixels[] ne se compile pas comme un accès direct à un tableau? Je pense que c'est direct. Sans aucun geste intermédiaire. Ou est-ce que je me trompe ?

CCanvas est une enveloppe pour ResourceCreate. Ainsi, par exemple, vous disposez de 20 images prêtes à l'emploi sous forme de tableaux. Si vous voulez les modifier via le canevas, vous devrez faire un coûteux ArrayCopy+Update.

Et si vous le faites sans CCanvas, vous n'aurez besoin que de ResourceCreate+ChartRerdraw. J'ai posté plusieurs travaux de dessin dynamique dans kodobase. Il était évident que CCanvas n'est pas bon.

 
Nikolai Semko:

Vous devez déplacer le tableau m_pixels[] de protected : vers public dans le fichier Canvas.mqh avant de le compiler :

Vous êtes sûr que PixelSet ne vousaidera pas ?

 
Rashid Umarov:

Vous êtes sûr que PixelSet ne vousaidera pas ?

Bien sûr, cela aidera, mais ce sera terriblement lent. Tout d'abord, un appel de fonction n'est pas libre, car les paramètres sont passés et sauvegardés (dans PixelSet, cela ne se fait même pas par référence), tous les registres doivent être poussés sur la pile et ensuite retirés. Deuxièmement, la fonction elle-même vérifie si X et Y se situent dans l'intervalle spécifié, et troisièmement, elle calcule l'indice du tableau. Et je n'ai pas besoin de tout ça parce que j'ai déjà un index et que dans mon algorithme, je ne peux pas sortir de la plage.

 
Superbe diagramme arc-en-ciel ! J'aimerais aussi faire en sorte que les bougies dansent au rythme de la musique et se tordent les unes les autres !