Erreurs, bugs, questions - page 2801

 

Je veux afficher un personnage sur la toile et le déplacer, source :

#property indicator_chart_window
#property indicator_plots 0

#include <Canvas\Canvas.mqh>


CCanvas canvas;

//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit()
{
   canvas.CreateBitmapLabel(ChartID(), 0, "canvas", 0, 0, 900, 400);
   canvas.FontSet("Courier New", 32);
   canvas.Erase(0);
   canvas.Update();
   EventSetMillisecondTimer(250);
//---
   return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| Custom indicator iteration function                              |
//+------------------------------------------------------------------+
int OnCalculate(const int rates_total,
                const int prev_calculated,
                const datetime &time[],
                const double &open[],
                const double &high[],
                const double &low[],
                const double &close[],
                const long &tick_volume[],
                const long &volume[],
                const int &spread[])
{
//---

//--- return value of prev_calculated for next call
   return(rates_total);
}
//+------------------------------------------------------------------+
//| Timer function                                                   |
//+------------------------------------------------------------------+
void OnTimer()
{
   static int x = 0;
   static const uint col_black = ColorToARGB(clrBlack);
   static const uint col_red = ColorToARGB(clrRed);
   canvas.TextOut(x, 100, "S", col_black);
   x+=10;
   canvas.TextOut(x, 100, "S", col_red);
   canvas.Update();
}
//+------------------------------------------------------------------+


Pourquoi est-ce que j'écrase l'image rendue précédente avec du noir et que les artefacts restent ?


 
Igor Makanu:

Je veux afficher un personnage sur la toile et le déplacer, source :


Pourquoi est-ce que j'écrase l'image précédente avec du noir et j'ai toujours des artefacts ?


Il est préférable de remplir tout le kanvas en une seule fois. Il est préférable de redessiner l'ensemble du kanvas en une seule fois.

 
Andrey Barinov:

Il est préférable de remplir tout le canva en une seule fois. Tout est redessiné par la suite de toute façon.

J'y ai déjà pensé, mais la question est purement technique.

il s'avère que l'antialiasing des polices de caractères fonctionne ? et le but est de déplacer les sprites, en général, je veux comprendre pourquoi cela fonctionne ainsi

 

Je ne sais pas où creuser, quelqu'un peut-il me suggérer une direction de recherche. J'écris un indicateur, mais après le premier clic sur "compiler", la partie calcul donne un non-sens, je compile à nouveau, il semble être vrai.

2020.07.13 14:12:05.987 ZigZag_MP (USDJPY,M15)  Average wave size = -2147483648 points; less then average: 1/100 min=99999999.0 max=107.1 steps=-2147483648
2020.07.13 14:12:27.179 ZigZag_MP (USDJPY,M15)  Average wave size = 273 points; less then average: 65/100 min=106.422 max=107.848 steps=57

2020.07.13 14:18:38.001 ZigZag_MP (USDJPY,M15)  Average wave size = -2147483648 points; less then average: 1/100 min=99999999.0 max=107.1 steps=-2147483648
2020.07.13 14:18:46.751 ZigZag_MP (USDJPY,M15)  Average wave size = 273 points; less then average: 65/100 min=106.422 max=107.848 steps=57

Je ne fais rien d'extraordinaire - je calcule simplement les 100 derniers genoux Zig-Zag. J'ai inversé le code plus d'une fois, mais le fait est que c'est le même, mais le résultat est différent.

En anticipant une des versions possibles : les tampons indicateurs sont initialisés de manière forcée, il n'y a pas de déchets dedans.

 
Igor Zakharov:

anticipant une des versions possibles : les tampons indicateurs sont initialisés de force, il n'y a pas de déchets dedans.

la question est de savoir où initialiser

si prev_calculated == 0, alors tout est OK, si c'est dans OnInt(), alors il y aura un problème lors du changement de TF et lors de la compilation.

 
Igor Makanu:

la question est de savoir où initialiser

si par prev_calculated == 0 , alors tout est ok, si dans OnInt() , alors il y aura un problème lors du changement de TF et lors de la compilation

j'ai essayé toutes les variantes (à la fois onInt et oncalculated) ; la variante actuelle : dans la boucle, chaque valeur est assignée individuellement. j'ai vérifié à travers la fenêtre de données - pas de valeurs bizarres/mauvaises.

 
Igor Makanu:

Je veux afficher un personnage sur la toile et le déplacer, source :


Pourquoi est-ce que je passe l'image rendue précédente en noir et que les artefacts restent ?


C'est à cause de l'anti-aliasing. Le moyen le plus sûr est de dessiner un rectangle dans la couleur de fond, au-dessus du symbole. Et ensuite sortir le symbole avec les nouvelles coordonnées. C'est ce qui est généralement fait dans des cas comme celui-ci.

 
Igor Makanu:
Mihail Matkovskij:

Cela est dû à l'anticrénelage. Le moyen le plus sûr est de dessiner un rectangle dans la couleur de fond, au-dessus du symbole. Et ensuite sortir le symbole avec les nouvelles coordonnées. C'est ce qui est généralement fait dans des cas comme celui-ci.

N'oubliez pas le simple déplacement des kanvas sans aucun redécoupage ni peinture.
C'est le moyen le plus rapide de se déplacer.

#include <Canvas\iCanvas.mqh> //https://www.mql5.com/ru/code/22164

void OnStart() {
// Формируем какой-то фон
   for (int i = 0; i<1000; i++) Canvas.Circle(rand()%2048, rand()%2048,50+rand()%50,ARGB(255,rand()%256,rand()%256,rand()%256));
   Canvas.Update();
// -----------------------
   int x=100, y=100;
   iCanvas c(0,x,y,"symbol",50,50); // создаем дополнительный канвас размером 50х50
   c.TextPosition(0,0);
   c.CurentFont("Tahoma",50);
   c.Comm("S");
   c.Update();
   while(!IsStopped()&& x<W.Height) {
      c.MoveCanvas(++x,++y);        // перемещаем данный канвас
      c.Update();
      Sleep(50);
   }
}
 
Nikolai Semko:

N'oubliez pas la possibilité de déplacer simplement le kanvas sans avoir à le redessiner et à le repeindre.
C'est le moyen le plus rapide de se déplacer.

Personne ne le nie. C'est juste qu'il y a un concept où il y a un seul écran comme toile. À son tour, le même canevas personnalisé (tableau de pixels) est dessiné sur un canevas de fenêtre (graphique). Plus précisément, il est d'abord transmis au graphique (copié) à l'aide de ResourceCreate (dans OBJ_BITMAP ou OBJ_BITMAP_LABEL). Dans la fenêtre du graphique, tout est dessiné à l'aide de Win API (si je ne me trompe pas). Bien qu'il soit également possible d'utiliser d'autres API. Mais la classe CCanvas possède ses propres méthodes pour dessiner sur les éléments du tableau m_pixels.

Il s'avère que si l'on dessine un petit rectangle, il faut quand même passer beaucoup de pixels en utilisantResourceCreate (ce qui ne fait gagner du temps que sur le dessin). De cette manière, vous pouvez simplement déplacerOBJ_BITMAP_LABEL dans le graphique, sans avoir à traiter le tableau m_pixels puis à le copier dans OBJ_BITMAP_LABEL.
 
Mihail Matkovskij:

Personne ne le nie. C'est juste qu'il y a un concept où il y a un écran comme toile. À son tour, le même canevas personnalisé (un tableau de pixels) est dessiné sur le canevas de la fenêtre (le graphique). Plus précisément, il est d'abord transmis au graphique (copié) à l'aide de ResourceCreate (dans OBJ_BITMAP ou OBJ_BITMAP_LABEL). Dans la fenêtre du graphique, tout est dessiné à l'aide de Win API (si je ne me trompe pas). Bien qu'il soit également possible d'utiliser d'autres API. Mais la classe CCanvas possède ses propres méthodes pour dessiner sur les éléments du tableau m_pixels.

Il s'avère que si l'on dessine un petit rectangle, il faut encore passer beaucoup de pixels à l'aide deResourceCreate (on gagne du temps juste sur le dessin). De cette façon, vous pouvez déplacerOBJ_BITMAP_LABEL dans le graphique, sans avoir à traiter le tableau m_pixels et à le copier dans OBJ_BITMAP_LABEL.

Le problème est que la classe CCanvas n'a pas de méthode pour déplacer le canevas, ce qui est très étrange.
La classe iCanvas l'a implémenté.

ZZZ Je suis désolé, je viens de voir que la version actuelle d'iCanvas dans KB n'implémente pas cette méthode, seulement sa déclaration. Je vais le corriger maintenant.

bool iCanvas::MoveCanvas(const int x,const int y) {
   if(ObjectSetInteger(m_chart_id,m_objname,OBJPROP_XDISTANCE,x) && ObjectSetInteger(m_chart_id,m_objname,OBJPROP_YDISTANCE,y))  return(true);
   else return(false);
}

Corrigé


Dossiers :
iCanvas.mqh  45 kb
Movement.mq5  2 kb