CGraphicのテスト - 質問と提案 - ページ 6 12345678910111213 新しいコメント --- 2017.01.31 14:19 #51 Roman Konopelko: CGraphicのクラスでは、ご質問の通り、全ての箇所でカラータイプをuintに置き換えています。 また、CCanvas クラスに新しいメソッドを追加し、プリミティブを指定した厚さで描画できるようにしました。 CCanvasの革新性に合わせて、CCurveのプロパティを拡張しました。 曲線を線で描くとき、線の太さと両端のスタイルを指定できるようになりました。 それはもう、すごいですよ。 Roman Konopelko 2017.02.08 15:56 #52 スプライン(Bézier曲線による補間)の取り扱いを見直しました。その実装は、CGraphics クラスから直接 CCanvas に移され、Graphics ライブラリの外でスプラインを構築できるようになりました。 また、閉じたスプラインを描画するアルゴリズムが追加されました。その結果、CCanvas クラスは、新たに 2 つのパブリック メソッドを持つようになりました。void PolylineSmooth(const int &x[],const int &y[],const uint clr,const int size, ENUM_LINE_STYLE style=STYLE_SOLID,ENUM_LINE_END end_style=LINE_END_ROUND, double tension=0.5,double step=10); void PolygoneSmooth(int &x[],int &y[],const uint clr,const int size, ENUM_LINE_STYLE style=STYLE_SOLID,ENUM_LINE_END end_style=LINE_END_ROUND, double tension=0.5,double step=10);これらのメソッドにより、スプラインを任意のスタイルと厚さで描画することができます。 ベジェ曲線は円や楕円をかなり正確に表現するので、これらのプリミティブを所定の厚さで描画するための新しいメソッドを CCanvas クラスに追加する明白な必要性はない。 PolygoneSmooth法によるBézier曲線による楕円の近似例。#include <Canvas\Canvas.mqh> //+------------------------------------------------------------------+ //| Get arrays with ellipse coordinates | //+------------------------------------------------------------------+ void Ellipse(int &x[],int &y[]) { int xc = 750; int yc = 300; int rx = 300; int ry = 150; ArrayResize(x,16); ArrayResize(y,16); int i=0; for(double fi=0; fi<2*M_PI; fi+=M_PI_4/2,i++) { x[i]=(int)MathRound(xc+cos(fi)*rx); y[i]=(int)MathRound(yc+sin(fi)*ry); } } //+------------------------------------------------------------------+ //| Script program start function | //+------------------------------------------------------------------+ void OnStart() { CCanvas canvas; canvas.CreateBitmapLabel(0,0,"Canvas",0,0,1500,600); canvas.Erase(ColorToARGB(clrWhite)); int x[]; int y[]; Ellipse(x,y); canvas.PolygoneSmooth(x,y,ColorToARGB(clrBlack),20,STYLE_SOLID,LINE_END_BUTT,0.5,1); canvas.Arc(750,300,300,150,0,M_PI*2,ColorToARGB(clrRed)); canvas.Update(); }結果 Roman Konopelko 2017.02.08 15:59 #53 グラフィックス・ライブラリの多機能化に向けたもう一つの可能性として、カスタム曲線描画モードCURVE_CUSTOMがある。このモードでは、ライブラリの標準ツールで可能なものとは異なる曲線を描くために、CGraphicクラスを継承し、...Plotメソッドをオーバーロードする必要がなくなります。このモードを実装するために、CCurve クラスに新しいプロパティ CURVE_CUSTOM が追加される予定です。 //--- gets or sets the custom properties PlotFucntion CustomPlotFunction(void) const { return(m_custom_plot_func); } void *CustomPlotCBData(void) const { return(m_custom_plot_cbdata); } void CustomPlotFunction(PlotFucntion func) { m_custom_plot_func=func; } void CustomPlotCBData(void *cbdata) { m_custom_plot_cbdata=cbdata; }PlotFucntion 関数への新しいポインタに基づきます。typedef void(*PlotFucntion)(double &x[],double &y[], int size, CGraphic *graphic,CCanvas *canvas,void *cbdata);この手法により、プロット描画の新しい可能性が開かれます。例として、ローソク足の描画をCGraphicsライブラリで実装してみましょう。1.1本のキャンドルの全データを格納するコンテナクラスを作成しましょう。//+------------------------------------------------------------------+ //| Class CCandle | //| Usage: class to represent the candle | //+------------------------------------------------------------------+ class CCandle: public CObject { private: double m_open; double m_close; double m_high; double m_low; uint m_clr_inc; uint m_clr_dec; int m_width; public: CCandle(const double open,const double close,const double high,const double low, const int width,const uint clr_inc=0x000000,const uint clr_dec=0xF5F5F5); ~CCandle(void); double OpenValue(void) const { return(m_open); } double CloseValue(void) const { return(m_close); } double HigthValue(void) const { return(m_high); } double LowValue(void) const { return(m_low); } uint CandleColorIncrement(void) const { return(m_clr_inc); } uint CandleColorDecrement(void) const { return(m_clr_dec); } int CandleWidth(void) const { return(m_width); } }; //+------------------------------------------------------------------+ //| Constructor | //+------------------------------------------------------------------+ CCandle::CCandle(const double open,const double close,const double high,const double low, const int width,const uint clr_inc=0x000000,const uint clr_dec=0xF5F5F5): m_open(open),m_close(close),m_high(high),m_low(low), m_clr_inc(clr_inc),m_clr_dec(clr_dec),m_width(width) { } //+------------------------------------------------------------------+ //| Destructor | //+------------------------------------------------------------------+ CCandle::~CCandle(void) { }CCandle クラスは CObject クラスの子孫なので、描画したいローソク足はすべて、CArrayObj クラスの オブジェクトに順次書き込んでいけばいいのです。この配列は、cbdata パラメータとしてカスタム描画メソッドに取り込まれる。その結果、ローソク足の描画方法は以下のようになります。//+------------------------------------------------------------------+ //| Custom method for plot candles | //+------------------------------------------------------------------+ void PlotCandles(double &x[],double &y[],int size,CGraphic *graphic,CCanvas *canvas,void *cbdata) { //--- check obj CArrayObj *candles=dynamic_cast<CArrayObj*>(cbdata); if(candles==NULL || candles.Total()!=size) return; //--- plot candles for(int i=0; i<size; i++) { CCandle *candle=dynamic_cast<CCandle*>(candles.At(i)); if(candle==NULL) return; //--- primary calculate int xc=graphic.ScaleX(x[i]); int width_2=candle.CandleWidth()/2; int open=graphic.ScaleY(candle.OpenValue()); int close=graphic.ScaleY(candle.CloseValue()); int high=graphic.ScaleY(candle.HigthValue()); int low=graphic.ScaleY(candle.LowValue()); uint clr=(open<=close) ? candle.CandleColorIncrement() : candle.CandleColorDecrement(); //--- plot candle canvas.LineVertical(xc,high,low,0x000000); //--- plot candle real body canvas.FillRectangle(xc+width_2,open,xc-width_2,close,clr); canvas.Rectangle(xc+width_2,open,xc-width_2,close,0x000000); } }3.簡単のために、すべてのローソク足はランダムに生成されます。そして、10本のローソク足を順次生成し、CArrayObjクラスのオブジェクトに充填していきます。次に、CGraphicsオブジェクトを作成し、PlotCandles関数で描画することを指定しながら、そこに1本の曲線を追加します。また、Y軸の最大値と最小値を変更し、キャンドルが完全に見えるようにする必要があります。//+------------------------------------------------------------------+ //| Script program start function | //+------------------------------------------------------------------+ void OnStart() { int count=10; int width=10; double x[]; double y[]; ArrayResize(x,count); ArrayResize(y,count); CArrayObj candles(); double max=0; double min=0; //--- create values for(int i=0; i<count; i++) { x[i] = i; y[i] = i; //--- calculate values double open=MathRound(50.0+(MathRand()/32767.0)*50.0); double close=MathRound(50.0+(MathRand()/32767.0)*50.0); double high=MathRound(MathMax(open,close)+(MathRand()/32767.0)*10.0); double low=MathRound(MathMin(open,close) -(MathRand()/32767.0)*10.0); //--- find max and min if(i==0 || max<high) max=high; if(i==0 || min>low) min=low; //--- create candle CCandle *candle=new CCandle(open,close,high,low,width); candles.Add(candle); } //--- create graphic CGraphic graphic; if(!graphic.Create(0,"CandleGraphic",0,30,30,780,380)) { graphic.Attach(0,"CandleGraphic"); } //--- create curve CCurve *curve=graphic.CurveAdd(x,y,CURVE_CUSTOM,"Candles"); //--- sets the curve properties curve.CustomPlotFunction(PlotCandles); curve.CustomPlotCBData(GetPointer(candles)); //--- sets the graphic properties graphic.YAxis().Max((int)max); graphic.YAxis().Min((int)min); //--- plot graphic.CurvePlotAll(); graphic.Update(); }その結果、次のようなグラフが得られました。 ファイル: Canvas.mqh 304 kb Axis.mqh 12 kb ColorGenerator.mqh 4 kb Curve.mqh 23 kb Graphic.mqh 73 kb Candle.mq5 6 kb --- 2017.03.12 17:51 #54 ロマン・コノペルコCGraphic::SetDefaultParameters関数に小さな誤りがあります。色は不透明度を考慮して初期化する必要があります。void CGraphic::SetDefaultParameters(void) { ... ... //--- sets the default values for grid m_grid.clr_line=ColorToARGB(clrWhiteSmoke,255); m_grid.clr_axis_line=ColorToARGB(clrSilver,255); Roman Konopelko 2017.03.13 15:29 #55 o_o:ロマン・コノペルコCGraphic::SetDefaultParameters関数に小さな誤りがあります。色は不透明度を考慮して初期化する必要があります。 この点についてはすでに修正済みですが、残念ながらこの編集はまだビルドに反映されていません。 Vladimir Karputov 2017.06.13 11:40 #56 この例では、パソコンがフリーズしてしまいました。やったこと:エディタでチャートにインジケータを 置いた後、87行目と88行目のコメントアウト/アンコメントの組み合わせを変えて遊んでみた(1つずつの場合、一緒にした場合)。//+------------------------------------------------------------------+ //| tst.mq5 | //| Copyright © 2017, Vladimir Karputov | //| http://wmua.ru/slesar/ | //+------------------------------------------------------------------+ #property copyright "Copyright © 2017, Vladimir Karputov" #property link "http://wmua.ru/slesar/" #property version "1.000" #property description "Panel indicator: \"Evening Star\" pattern " #property description "search results for different periods" #property indicator_chart_window #property indicator_buffers 0 #property indicator_plots 0 #include <Graphics\Graphic.mqh> //--- object for creating graphs CGraphic my_graphic; //+------------------------------------------------------------------+ //| Global Variables | //+------------------------------------------------------------------+ bool m_first_start=false; //+------------------------------------------------------------------+ //| Custom indicator initialization function | //+------------------------------------------------------------------+ int OnInit() { if(!EventSetTimer(3)) if(!EventSetTimer(3)) if(!EventSetTimer(3)) { Print("Error create timer! THREE attempts!"); return(INIT_FAILED); } //--- canvas creation my_graphic.Create(0,"Evening Star Statistics",0,10,10,800,550); my_graphic.CurvePlotAll(); my_graphic.Update(); //--- m_first_start=false; //--- return(INIT_SUCCEEDED); } //+------------------------------------------------------------------+ //| Custom indicator deinitialization function | //+------------------------------------------------------------------+ void OnDeinit(const int reason) { my_graphic.Destroy(); } //+------------------------------------------------------------------+ //| 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[]) { if(!m_first_start) { //--- revert access to arrays - do it like in timeseries ArraySetAsSeries(time,true); ArraySetAsSeries(open,true); ArraySetAsSeries(high,true); ArraySetAsSeries(low,true); ArraySetAsSeries(close,true); int size=ArraySize(time); double arrY[],arrX[]; ArrayResize(arrX,size); ArrayResize(arrY,size); for(int i=0; i<size;++i) { arrX[i]=(double)time[i]; arrY[i]=close[i]; } CCurve *curve_b=my_graphic.CurveAdd(arrX,arrY,CURVE_LINES,"Close"); CAxis *xAxis=my_graphic.XAxis(); // получаем ось X //---попеременно комбинирую (комментировать, раскомментировать) строки 87 //--- и 88 можно словить момент поглощения памяти и зависания компьютера //xAxis.AutoScale(false); //xAxis.Type(AXIS_TYPE_DATETIME); my_graphic.CurvePlotAll(); my_graphic.Update(); m_first_start=true; } //--- return value of prev_calculated for next call return(rates_total); } //+------------------------------------------------------------------+ //| Timer function | //+------------------------------------------------------------------+ void OnTimer() { } //+------------------------------------------------------------------+ 2回達成を繰り返した。一連の動作は記録していない。3回目は些細なことですが......確認するのが怖いです。追加:ビルド1607 x64 ファイル: tst.mq5 8 kb Vladimir Karputov 2017.06.14 07:06 #57 Vladimir Karputov:この例では、パソコンがフリーズしてしまいました。やったこと:エディタでチャートにインジケータを 置いた後、87行目と88行目のコメントアウト/アンコメントの組み合わせを変えて遊んでみた(1つずつの場合、一緒にした場合)。2回達成を繰り返した。一連の動作は記録していない。3回目は些細なことですが......確認するのが怖いです。追加:ビルド1607 x64 今日も記録を繰り返しました。死んだコンピュータがハングアップし、RAMの消費量が2GBから5.5GBに上昇するのを確認することが出来ました。スケジュールを閉じることができたようだが、コンピュータが5分間もハングアップしている。今回は配列のサイズに制限を設け、300要素以内としました。見ての通り役に立たなかった🤔。 --- 2017.06.14 08:11 #58 デバッグは何を言っているのですか? Vladimir Karputov 2017.06.14 08:14 #59 o_o:デバッグは何を言っているのですか? Jbugではダメだったので、インジケータにカーソルを合わせて1~2行をアンコメント/コメントし、コンパイルする、という方法をとりました。結局、タブレットから書くことになった。ノートパソコンが故障してしまったので...。 Vladimir Karputov 2017.06.14 08:28 #60 Vladimir Karputov: gbugではダメで、こうしました。インジケータにカーソルを合わせて、1~2行コメントアウト/コメントアウトしてコンパイルしました。結局、タブレットから書くことになった。ノートパソコンが故障してしまったので...。 ラップトップはハード・リブートしたら復活したが、これ以上破壊的な実験はしたくない。ラップトップにはいくつかのExpert Advisorが走っているので、丸一時間フリーズを捕まえる気もないのだ。 12345678910111213 新しいコメント 理由: キャンセル 取引の機会を逃しています。 無料取引アプリ 8千を超えるシグナルをコピー 金融ニュースで金融マーケットを探索 新規登録 ログイン スペースを含まないラテン文字 このメールにパスワードが送信されます エラーが発生しました Googleでログイン WebサイトポリシーおよびMQL5.COM利用規約に同意します。 新規登録 MQL5.com WebサイトへのログインにCookieの使用を許可します。 ログインするには、ブラウザで必要な設定を有効にしてください。 ログイン/パスワードをお忘れですか? Googleでログイン
CGraphicのクラスでは、ご質問の通り、全ての箇所でカラータイプをuintに置き換えています。
また、CCanvas クラスに新しいメソッドを追加し、プリミティブを指定した厚さで描画できるようにしました。
CCanvasの革新性に合わせて、CCurveのプロパティを拡張しました。
曲線を線で描くとき、線の太さと両端のスタイルを指定できるようになりました。
それはもう、すごいですよ。
スプライン(Bézier曲線による補間)の取り扱いを見直しました。その実装は、CGraphics クラスから直接 CCanvas に移され、Graphics ライブラリの外でスプラインを構築できるようになりました。
また、閉じたスプラインを描画するアルゴリズムが追加されました。
その結果、CCanvas クラスは、新たに 2 つのパブリック メソッドを持つようになりました。
これらのメソッドにより、スプラインを任意のスタイルと厚さで描画することができます。
ベジェ曲線は円や楕円をかなり正確に表現するので、これらのプリミティブを所定の厚さで描画するための新しいメソッドを CCanvas クラスに追加する明白な必要性はない。
PolygoneSmooth法によるBézier曲線による楕円の近似例。
結果
グラフィックス・ライブラリの多機能化に向けたもう一つの可能性として、カスタム曲線描画モードCURVE_CUSTOMがある。
このモードでは、ライブラリの標準ツールで可能なものとは異なる曲線を描くために、CGraphicクラスを継承し、...Plotメソッドをオーバーロードする必要がなくなります。
このモードを実装するために、CCurve クラスに新しいプロパティ CURVE_CUSTOM が追加される予定です。
PlotFucntion 関数への新しいポインタに基づきます。
この手法により、プロット描画の新しい可能性が開かれます。
例として、ローソク足の描画をCGraphicsライブラリで実装してみましょう。
1.1本のキャンドルの全データを格納するコンテナクラスを作成しましょう。
CCandle クラスは CObject クラスの子孫なので、描画したいローソク足はすべて、CArrayObj クラスの オブジェクトに順次書き込んでいけばいいのです。この配列は、cbdata パラメータとしてカスタム描画メソッドに取り込まれる。その結果、ローソク足の描画方法は以下のようになります。
3.簡単のために、すべてのローソク足はランダムに生成されます。そして、10本のローソク足を順次生成し、CArrayObjクラスのオブジェクトに充填していきます。次に、CGraphicsオブジェクトを作成し、PlotCandles関数で描画することを指定しながら、そこに1本の曲線を追加します。また、Y軸の最大値と最小値を変更し、キャンドルが完全に見えるようにする必要があります。
その結果、次のようなグラフが得られました。
ロマン・コノペルコ
CGraphic::SetDefaultParameters関数に小さな誤りがあります。
色は不透明度を考慮して初期化する必要があります。
ロマン・コノペルコ
CGraphic::SetDefaultParameters関数に小さな誤りがあります。
色は不透明度を考慮して初期化する必要があります。
この例では、パソコンがフリーズしてしまいました。やったこと:エディタでチャートにインジケータを 置いた後、87行目と88行目のコメントアウト/アンコメントの組み合わせを変えて遊んでみた(1つずつの場合、一緒にした場合)。
2回達成を繰り返した。一連の動作は記録していない。3回目は些細なことですが......確認するのが怖いです。
追加:ビルド1607 x64
この例では、パソコンがフリーズしてしまいました。やったこと:エディタでチャートにインジケータを 置いた後、87行目と88行目のコメントアウト/アンコメントの組み合わせを変えて遊んでみた(1つずつの場合、一緒にした場合)。
2回達成を繰り返した。一連の動作は記録していない。3回目は些細なことですが......確認するのが怖いです。
追加:ビルド1607 x64
今日も記録を繰り返しました。死んだコンピュータがハングアップし、RAMの消費量が2GBから5.5GBに上昇するのを確認することが出来ました。スケジュールを閉じることができたようだが、コンピュータが5分間もハングアップしている。
今回は配列のサイズに制限を設け、300要素以内としました。見ての通り役に立たなかった🤔。
デバッグは何を言っているのですか?
デバッグは何を言っているのですか?
Jbugではダメだったので、インジケータにカーソルを合わせて1~2行をアンコメント/コメントし、コンパイルする、という方法をとりました。結局、タブレットから書くことになった。ノートパソコンが故障してしまったので...。
gbugではダメで、こうしました。インジケータにカーソルを合わせて、1~2行コメントアウト/コメントアウトしてコンパイルしました。結局、タブレットから書くことになった。ノートパソコンが故障してしまったので...。
ラップトップはハード・リブートしたら復活したが、これ以上破壊的な実験はしたくない。ラップトップにはいくつかのExpert Advisorが走っているので、丸一時間フリーズを捕まえる気もないのだ。