MathArccos関数の働き・役割
MathArccos関数は、指定された値の逆余弦(アークコサイン)を計算し、その結果をラジアン単位で返します。この関数は、-1以上1以下の範囲の値を入力として受け取り、その値に対応する逆余弦を0からπの範囲で返します。逆余弦の計算は三角関数の一種であり、特に三角形の角度を求める際に使用されます。
逆余弦とは?
逆余弦(アークコサイン、arccos)は、コサイン関数の逆関数です。コサイン値から元の角度を求めるために使用されます。範囲は0からπ(ラジアン)です。
ラジアンとは?
ラジアンとは、角度の測定単位の一つです。ラジアン単位は、円の半径と円周の長さに基づいています。具体的には、円の半径の長さと同じ長さの弧(円周の一部分)が作る中心角が1ラジアンです。、1ラジアンは約57.3度です。180度はπラジアンに相当します。1周(360度)は2πラジアンに相当します。
コサイン関数とは?
コサイン関数は、三角関数の一つで、直角三角形の角度とその隣接辺と斜辺の比を表します。角度θに対するコサインは、cos(θ)で表されます。
逆関数とは?
逆関数は、元の関数が与える出力から、その入力を逆に求める関数です。例えば、関数fがxをyに変換するなら、逆関数f⁻¹はyをxに変換します。
コサインとは?
そもそもコサインって何?という話なのですが、コサインは、直角三角形の角度と辺の長さの比を表す三角関数です。具体的には、コサインは角度の隣の辺(角度に接している辺)の長さを斜辺(直角に対する最も長い辺)の長さで割ったものです。この「隣の辺」とは、指定された角度の頂点から見て、角度の一方に接している辺のことを指します。
思いの外前提の説明が長くなりましたが、つまり、コサインの値がわかっているけれど角度がわからない時に、その角度を求めるために使う関数が逆余弦(arccos)という訳です。
逆余弦の公式は、通常arccosまたはcos⁻¹で表されます。具体的には、
θ = arccos(x) または θ = cos⁻¹(x)
ここで、θは角度、xはコサインの値(-1から1の範囲)です。
具体例
直角三角形ABCがあり、角度Aが直角であるとします。辺ABの長さが3、辺ACの長さが5である場合、角度Bを求めたいとします。
計算方法
基本的に電卓やプログラミング言語を使って逆余弦の計算を行います。ここでは、Pythonを使った例を示します。
import math
# コサイン値
cosine_value = 0.6
# 逆余弦を使って角度を求める(ラジアン単位)
angle_radians = math.acos(cosine_value)
# ラジアンから度に変換
angle_degrees = math.degrees(angle_radians)
print(f"角度Bは {angle_degrees:.2f} 度です。")
手計算
逆余弦は通常、手計算ではなく電卓やソフトウェアを使用して求めますが、電卓を使用する場合の手順は以下の通りです:
計算結果
上記のPythonコードを実行すると、角度Bが約53.13度であることがわかります。これは、逆余弦を使ってコサイン値から角度を求める具体例です。
MathArccos関数の引数について
double MathArccos(double val);
MathArccos関数の引数構成は以下の通りです。
引数
val
種類: double型
説明: 逆余弦が計算されるコサインの値を指定します。この値は-1以上1以下でなければなりません。範囲外の値を指定すると、結果はNaN(不定値)となります。
※コサインの値が-1から1の範囲にあるのは、コサイン関数の定義と性質によるものです。コサインは、単位円(半径1の円)上の角度に対応するx座標を表すため、x座標は常に-1から1の範囲に収まります。これにより、どの角度に対してもコサインの値は-1から1の間にあります。
MathArccos関数の戻り値について
MathArccos関数は、指定された値の逆余弦をラジアン単位で返します。戻り値は以下の通りです。
戻り値
種類: double型
説明: ラジアン単位での数値の逆余弦を返します。引数の値が-1以上1以下の場合、逆余弦が計算され、0からπの範囲で値が返されます。引数の値が-1未満または1より大きい場合、NaN(Not a Number、不定値)が返されます。
MathArccos関数を使う際の注意点
引数として指定する値は必ず-1以上1以下の範囲でなければなりません。この範囲外の値を指定すると、関数はNaN(Not a Number、不定値)を返します。例えば、MathArccos(1.5)のような呼び出しは無効です。
MathArccos関数はラジアン単位で値を返します。ラジアンは角度の単位の一つであり、1ラジアンは約57.2958度です。角度を度単位で扱いたい場合は、追加の変換が必要です。例えば、結果を度に変換するには、ラジアンの値に180/πを掛ける必要があります。
MathArccos関数は数学的に厳密な計算を行うため、計算精度の問題が生じることがあります。特に、引数が-1や1に非常に近い場合、計算結果が正確でない場合があります。計算結果の精度が重要な場合は、この点を考慮する必要があります。
MathArccos関数を使ったサンプルコード
#define GRAPH_WIDTH 750 // グラフの幅を定義
#define GRAPH_HEIGHT 350 // グラフの高さを定義
#include <Graphics\Graphic.mqh> // グラフィックモジュールをインクルード
CGraphic ExtGraph; // グラフィックオブジェクトを作成
//+------------------------------------------------------------------+
//| スクリプトプログラム開始関数 |
//+------------------------------------------------------------------+
void OnStart()
{
// 101個の値を2π/1000ステップで生成し、deltaベクトルに格納
vector delta = vector::Full(101, 2 * M_PI / 1000);
delta[0] = -1;
// deltaステップで-1から2πまでの値を取得
vector X = delta.CumSum();
// Xベクトルの各値の逆余弦値を計算し、Yベクトルに格納
vector Y = MathArccos(X);
// 計算されたベクトル値を配列に転送
double x_array[], y_array[];
X.Swap(x_array);
Y.Swap(y_array);
// 計算されたベクトル値のグラフを描画
CurvePlot(x_array, y_array, clrDodgerBlue);
// EscapeキーまたはPgDnキーを押してグラフを削除し(スクリーンショットを撮り)、終了するまで待機
while (!IsStopped())
{
if (StopKeyPressed())
break;
Sleep(16); // 16ミリ秒待機
}
// クリーンアップ処理
ExtGraph.Destroy();
}
//+------------------------------------------------------------------+
//| ESCが押されたら「true」を返す |
//| PgDnが押されたら、グラフのスクリーンショットを撮り、「true」を返す |
//| その他の場合は「false」を返す |
//+------------------------------------------------------------------+
bool StopKeyPressed()
{
// ESCキーが押されたら「true」を返す
if (TerminalInfoInteger(TERMINAL_KEYSTATE_ESCAPE) != 0)
return(true);
// PgDnキーが押されてグラフのスクリーンショットが正常に取得されたら、「true」を返す
if (TerminalInfoInteger(TERMINAL_KEYSTATE_PAGEDOWN) != 0 && MakeAndSaveScreenshot(MQLInfoString(MQL_PROGRAM_NAME) + "_Screenshot"))
return(true);
// それ以外の場合は「false」を返す
return(false);
}
//+------------------------------------------------------------------+
//| グラフオブジェクトを作成して曲線を描く |
//+------------------------------------------------------------------+
void CurvePlot(double &x_array[], double &y_array[], const color colour)
{
// グラフオブジェクトを作成
ExtGraph.Create(ChartID(), "Graphic", 0, 0, 0, GRAPH_WIDTH, GRAPH_HEIGHT);
// 曲線を追加
ExtGraph.CurveAdd(x_array, y_array, ColorToARGB(colour), CURVE_LINES);
// グラフのインデントを調整
ExtGraph.IndentUp(30);
// すべての曲線を描画
ExtGraph.CurvePlotAll();
// テキストを追加
string text1 = "Press ESC to delete the graph and stop the script, or";
string text2 = "Press PgDn to create a screen, delete the graph and stop the script";
ExtGraph.TextAdd(54, 9, text1, ColorToARGB(clrBlack));
ExtGraph.TextAdd(54, 21, text2, ColorToARGB(clrBlack));
// グラフを更新
ExtGraph.Update();
}
//+------------------------------------------------------------------+
//| スクリーンショットを撮り、画像をファイルに保存する |
//+------------------------------------------------------------------+
bool MakeAndSaveScreenshot(const string file_name)
{
string file_names[];
ResetLastError();
// ファイル保存ダイアログを表示
int selected = FileSelectDialog("Save Picture", NULL, "All files (*.*)|*.*", FSD_WRITE_FILE, file_names, file_name + ".png");
// ファイルが選択されなかった場合
if (selected < 1)
{
if (selected < 0)
PrintFormat("%s: FileSelectDialog() function returned error %d", __FUNCTION__, GetLastError());
return false;
}
bool res = false;
// グラフを非表示にしてスクリーンショットを撮る
if (ChartSetInteger(0, CHART_SHOW, false))
res = ChartScreenShot(0, file_names[0], GRAPH_WIDTH, GRAPH_HEIGHT);
// グラフを再表示
ChartSetInteger(0, CHART_SHOW, true);
return(res);
}
このコードは、MathArccos関数を使用して計算された逆余弦値のグラフを描画し、ユーザーがESCキーまたはPgDnキーを押すまで待機します。ESCキーが押された場合、グラフを削除し、スクリプトを終了します。PgDnキーが押された場合、グラフのスクリーンショットを撮り、グラフを削除してスクリプトを終了します。
サンプルコード解説1: グローバル領域での定義
以下のコードは、サンプルコードのグローバル領域で定義されている内容を示しています。このセクションでは、グラフの描画に必要な設定やライブラリのインクルード、オブジェクトの作成が行われています。
#define GRAPH_WIDTH 750 // グラフの幅を定義
#define GRAPH_HEIGHT 350 // グラフの高さを定義
#include <Graphics\Graphic.mqh> // グラフィックライブラリのインクルード
CGraphic ExtGraph; // グラフィックオブジェクトの作成
定義の詳細
グラフの幅と高さの定義
グラフの幅を750ピクセル(デジタル画像を構成する最小の単位)に、グラフの高さを350ピクセルに設定しています。defineディレクティブを使用して定数を定義することで、コード内でこれらの値を使用する際に簡単に参照できるようになります。
グラフィックライブラリのインクルード
includeディレクティブを使用して、グラフィック関連の機能を提供するライブラリファイル「Graphic.mqh」をインクルードしています。このライブラリには、グラフの描画や曲線の追加など、グラフィック操作に必要な関数やクラスが定義されています。
グラフィックオブジェクトの作成
CGraphicクラスのインスタンスであるExtGraphオブジェクトを作成しています。このオブジェクトは、グラフの描画や操作に使用されます。クラスはオブジェクト指向プログラミングの基本要素であり、特定の機能を持つオブジェクト(変数や配列など)を作成するためのテンプレートです。
サンプルコード解説2: OnStart関数の中1
OnStart関数の概要
OnStart関数はスクリプトの実行が開始されたときに自動的に呼び出される関数です。この関数内では、MathArccos関数を用いて逆余弦を計算し、その結果をグラフとして描画する一連の処理が行われます。
コードの詳細解説
// スクリプトプログラム開始関数
void OnStart()
{
// 101個の値を2π/1000ステップで生成し、deltaベクトルに格納
vector delta = vector::Full(101, 2 * M_PI / 1000);
delta[0] = -1;
// deltaステップで-1から2πまでの値を取得
vector X = delta.CumSum();
// Xベクトルの各値の逆余弦値を計算し、Yベクトルに格納
vector Y = MathArccos(X);
// 計算されたベクトル値を配列に転送
double x_array[], y_array[];
X.Swap(x_array);
Y.Swap(y_array);
vector deltaの生成
vector delta = vector::Full(101, 2 * M_PI / 1000);
この部分では、vectorの静的メソッドFullを使用して、指定されたサイズと値で新しいベクトルを生成しています。具体的には、101個の要素を持つベクトルを作成し、各要素に2 * π / 1000の値を設定します。最初の要素は手動で-1に設定されます
※M_PIは円周率πの値を持つ組み込みの数学定数です。
※vectorキーワードについての詳細は↓の記事をご参照ください。
スコープ解決演算子「::」について
※コロンが2つ続いている「::」は、スコープ解決演算子と呼ばれます。これはC++やMQL5などのプログラミング言語で使用され、特定のクラスや名前空間に属するメンバや関数を指定するために使われます。
スコープ解決演算子の意味
スコープ解決演算子「::」は、以下のような用途で使用されます。
クラスのメンバ関数や静的メンバにアクセスする場合: クラス内に定義された関数や変数にアクセスする際に使用します。
class MyClass {
public:
static void MyFunction() {
// 何らかの処理
}
};
// クラスの静的メンバ関数を呼び出す
MyClass::MyFunction();
名前空間内の関数や変数にアクセスする場合: 名前空間に属する要素にアクセスする際に使用します。
※namespaceキーワードや名前空間についての詳細は↓の記事をご参照ください。
namespace MyNamespace {
void MyFunction() {
// 何らかの処理
}
}
// 名前空間の関数を呼び出す
MyNamespace::MyFunction();
同一クラス内の別のスコープにあるメンバにアクセスする場合: 内部クラスやネストされたスコープに属するメンバにアクセスする際に使用します。
class OuterClass {
public:
class InnerClass {
public:
void InnerFunction() {
// 何らかの処理
}
};
};
// 内部クラスのメンバ関数を呼び出す
OuterClass::InnerClass::InnerFunction();
スコープ解決演算子「::」を使ってクラスのメソッドを呼び出す場合、そのメソッドが静的メソッド(staticメソッド)であれば、クラスのインスタンスを生成しなくても呼び出すことができます。
静的メソッドとは
静的メソッド(staticメソッド)は、クラスに属するメソッドですが、クラスのインスタンスに依存しないため、インスタンスを生成せずにクラス名を使って直接呼び出すことができます。静的メソッドはクラス全体に共通の動作を提供し、通常はクラスの共通機能を実装するために使用されます。
今回呼び出しているFullメソッドは以下のような定義になっている静的メソッドになります。
static matrix matrix::Full(
const ulong rows, // 行数
const ulong cols, // 列数
const double value // 書き入れる値
);
static vector vector::Full(
const ulong size, // ベクトルサイズ
const double value // 書き入れる値
);
第1引数にベクトルのサイズを指定し、第2引数に書き入れる値を記述する仕様になっています。
vector Xの生成
vector X = delta.CumSum();
この部分では、deltaベクトルの累積和を計算し、Xベクトルに格納しています。CumSumメソッドを使用して、deltaの各要素の累積和を計算します。これにより、-1から始まり2πまでの範囲の値が得られます。
vector Yの生成
vector Y = MathArccos(X);
この部分では、Xベクトルの各値に対して逆余弦を計算し、その結果をYベクトルに格納しています。MathArccos関数を使用して、各要素の逆余弦を計算します。
ベクトルの配列への転送
double x_array[], y_array[];
X.Swap(x_array);
Y.Swap(y_array);
この部分では、計算されたXとYのベクトル値を配列に転送しています。Swapメソッドを使用して、ベクトルの内容を配列にコピーします。x_arrayにはXベクトルの値が、y_arrayにはYベクトルの値がそれぞれ格納されます。
これらのステップを通じて、逆余弦の計算に必要なデータを準備し、その結果を配列に転送する処理が行われます。この後、配列に格納されたデータを使用してグラフを描画します。
サンプルコード解説3: OnStart関数の中2
コードの詳細解説
// 計算されたベクトル値のグラフを描画
CurvePlot(x_array, y_array, clrDodgerBlue);
// EscapeキーまたはPgDnキーを押してグラフを削除し(スクリーンショットを撮り)、終了するまで待機
while (!IsStopped())
{
if (StopKeyPressed())
break;
Sleep(16); // 16ミリ秒待機
}
// クリーンアップ処理
ExtGraph.Destroy();
グラフの描画
CurvePlot(x_array, y_array, clrDodgerBlue);
この部分では、計算されたベクトル値を使用してグラフを描画しています。CurvePlot関数は、X軸とY軸のデータを入力として受け取り、指定された色でグラフを描画します。ここでは、clrDodgerBlueという色が使用されています。
グラフの表示と待機ループ
while (!IsStopped())
{
if (StopKeyPressed())
break;
Sleep(16); // 16ミリ秒待機
}
この部分では、EscapeキーまたはPgDnキーが押されるまでグラフを表示し続けるための待機ループを実装しています。IsStopped関数は、スクリプトの停止が要求されたかどうかをチェックし、サンプルStopKeyPressed関数はEscapeキーまたはPgDnキーが押されたかどうかをチェックします。16ミリ秒ごとにSleep関数で待機することで、CPU負荷を軽減しつつループを繰り返します。
クリーンアップ処理
ExtGraph.Destroy();
この部分では、使用したグラフオブジェクトのクリーンアップを行います。Destroyメソッドは、ExtGraphオブジェクトを破棄し、メモリを解放します。これにより、次回以降のグラフ描画が正しく行えるようになります。
関数の説明
- CurvePlot関数:
この関数は、X軸とY軸のデータを基にグラフを描画します。色を指定することで、グラフの線の色を変更できます。 - IsStopped関数:
この関数は、スクリプトの停止が要求されたかどうかをチェックします。要求されていない場合はfalseを返し、要求された場合はtrueを返します。 - StopKeyPressed関数:
この関数は、EscapeキーまたはPgDnキーが押されたかどうかをチェックします。押された場合はtrueを返し、押されていない場合はfalseを返します。 - Sleep関数:
指定されたミリ秒数だけ待機します。この例では、16ミリ秒ごとに待機することで、ループの繰り返しを制御しています。 - Destroyメソッド:
グラフオブジェクトを破棄し、メモリを解放します。これにより、リソースの無駄遣いを防ぎます。
これらのステップにより、計算された逆余弦のデータをグラフとして視覚的に表示し、ユーザーの操作に応じて適切にクリーンアップすることができます。
サンプルコード解説4: StopKeyPressed関数
コードの詳細解説
//+------------------------------------------------------------------+
//| ESCが押されたら「true」を返す |
//| PgDnが押されたら、グラフのスクリーンショットを撮り、「true」を返す |
//| その他の場合は「false」を返す |
//+------------------------------------------------------------------+
bool StopKeyPressed()
{
// ESCキーが押されたら「true」を返す
if (TerminalInfoInteger(TERMINAL_KEYSTATE_ESCAPE) != 0)
return(true);
// PgDnキーが押されてグラフのスクリーンショットが正常に取得されたら、「true」を返す
if (TerminalInfoInteger(TERMINAL_KEYSTATE_PAGEDOWN) != 0 && MakeAndSaveScreenshot(MQLInfoString(MQL_PROGRAM_NAME) + "_Screenshot"))
return(true);
// それ以外の場合は「false」を返す
return(false);
}
関数の概要
StopKeyPressed関数は、特定のキー(ESCキーまたはPgDnキー)が押されたかどうかをチェックし、その結果に応じてtrue
またはfalse
を返します。この関数は、ユーザーの入力に応じてスクリプトを停止するために使用されます。
各部分の説明
ESCキーのチェック
// ESCキーが押されたら「true」を返す
if (TerminalInfoInteger(TERMINAL_KEYSTATE_ESCAPE) != 0)
return(true);
この部分では、TerminalInfoInteger関数を使用してESCキーが押されたかどうかを確認します。TERMINAL_KEYSTATE_ESCAPEは、ESCキーの状態を表す定数です。ESCキーが押されている場合、この関数は非ゼロの値を返します。このチェックがtrue
の場合、関数はtrue
を返し、スクリプトの停止を指示します。
PgDnキーのチェックとスクリーンショットの保存
// PgDnキーが押されてグラフのスクリーンショットが正常に取得されたら、「true」を返す
if (TerminalInfoInteger(TERMINAL_KEYSTATE_PAGEDOWN) != 0 && MakeAndSaveScreenshot(MQLInfoString(MQL_PROGRAM_NAME) + "_Screenshot"))
return(true);
この部分では、PgDnキーが押されたかどうかをチェックします。TERMINAL_KEYSTATE_PAGEDOWNは、PgDnキーの状態を表す定数です。PgDnキーが押されている場合、この関数は非ゼロの値を返します。
さらに、MakeAndSaveScreenshot関数を呼び出して、現在のグラフのスクリーンショットを保存します。スクリーンショットの保存が成功した場合、この関数はtrue
を返します。
デフォルトの戻り値
// それ以外の場合は「false」を返す
return(false);
この部分では、ESCキーもPgDnキーも押されていない場合、関数はfalse
を返します。これにより、スクリプトは継続して実行されます。
この関数を使用することで、ユーザーがESCキーまたはPgDnキーを押した際にスクリプトの動作を制御することができます。これにより、ユーザーの入力に応じてグラフを削除したり、スクリーンショットを保存したりすることができます。
サンプルコード解説5: CurvePlot関数
コードの詳細解説
//+------------------------------------------------------------------+
//| グラフオブジェクトを作成して曲線を描く |
//+------------------------------------------------------------------+
void CurvePlot(double &x_array[], double &y_array[], const color colour)
{
// グラフオブジェクトを作成
ExtGraph.Create(ChartID(), "Graphic", 0, 0, 0, GRAPH_WIDTH, GRAPH_HEIGHT);
// 曲線を追加
ExtGraph.CurveAdd(x_array, y_array, ColorToARGB(colour), CURVE_LINES);
// グラフのインデントを調整
ExtGraph.IndentUp(30);
// すべての曲線を描画
ExtGraph.CurvePlotAll();
// テキストを追加
string text1 = "Press ESC to delete the graph and stop the script, or";
string text2 = "Press PgDn to create a screen, delete the graph and stop the script";
ExtGraph.TextAdd(54, 9, text1, ColorToARGB(clrBlack));
ExtGraph.TextAdd(54, 21, text2, ColorToARGB(clrBlack));
// グラフを更新
ExtGraph.Update();
}
関数の概要
CurvePlot関数は、指定されたX軸とY軸のデータを使用してグラフを描画するための関数です。この関数は、グラフオブジェクトを作成し、曲線を追加し、テキストを表示して、最終的にグラフを更新します。
各部分の説明
グラフオブジェクトの作成
// グラフオブジェクトを作成
ExtGraph.Create(ChartID(), "Graphic", 0, 0, 0, GRAPH_WIDTH, GRAPH_HEIGHT);
この部分では、ExtGraphオブジェクトを作成します。Createメソッドは、チャート上に新しいグラフオブジェクトを作成します。ChartID関数を使用して現在のチャートIDを取得し、”Graphic”という名前でグラフオブジェクトを作成します。グラフの位置とサイズは、GRAPH_WIDTHとGRAPH_HEIGHTの定数を使用して指定します。
曲線の追加
// 曲線を追加
ExtGraph.CurveAdd(x_array, y_array, ColorToARGB(colour), CURVE_LINES);
この部分では、X軸とY軸のデータを使用してグラフに曲線を追加します。CurveAddメソッドを使用して、指定された色と曲線の種類(CURVE_LINES)で曲線を追加します。ColorToARGB関数を使用して、指定された色をARGB形式に変換します。
グラフのインデント調整
// グラフのインデントを調整
ExtGraph.IndentUp(30);
この部分では、グラフのインデントを30ピクセル(デジタル画像を構成する最小の単位)上に調整します。IndentUpメソッドを使用して、グラフ全体の位置を調整します。
曲線の描画
// すべての曲線を描画
ExtGraph.CurvePlotAll();
この部分では、追加されたすべての曲線を描画します。CurvePlotAllメソッドを使用して、グラフに追加されたすべての曲線を描画します。
テキストの追加
// テキストを追加
string text1 = "Press ESC to delete the graph and stop the script, or";
string text2 = "Press PgDn to create a screen, delete the graph and stop the script";
ExtGraph.TextAdd(54, 9, text1, ColorToARGB(clrBlack));
ExtGraph.TextAdd(54, 21, text2, ColorToARGB(clrBlack));
この部分では、ユーザーに指示を表示するためのテキストを追加します。TextAddメソッドを使用して、指定された位置にテキストを追加します。テキストは、色を指定して表示されます。ここでは、黒色(clrBlack)が使用されています。
グラフの更新
// グラフを更新
ExtGraph.Update();
この部分では、グラフを更新して、すべての変更を反映させます。Updateメソッドを使用して、グラフの内容を最新の状態に更新します。
関数の説明
- Createメソッド:
グラフオブジェクトを作成します。チャートID、名前、位置、サイズを指定して新しいグラフを作成します。 - CurveAddメソッド:
指定されたX軸とY軸のデータを使用して曲線を追加します。色と曲線の種類を指定します。 - IndentUpメソッド:
グラフのインデントを調整します。指定されたピクセル数だけグラフを上に移動します。 - CurvePlotAllメソッド:
追加されたすべての曲線を描画します。 - TextAddメソッド:
指定された位置にテキストを追加します。テキストの内容と色を指定します。 - Updateメソッド:
グラフを更新して、すべての変更を反映させます。
これにより、CurvePlot関数はX軸とY軸のデータを使用してグラフを描画し、ユーザーに指示を表示するためのテキストを追加し、最終的にグラフを更新します。
サンプルコード解説6: MakeAndSaveScreenshot関数
コードの詳細解説
//+------------------------------------------------------------------+
//| スクリーンショットを撮り、画像をファイルに保存する |
//+------------------------------------------------------------------+
bool MakeAndSaveScreenshot(const string file_name)
{
string file_names[];
ResetLastError();
// ファイル保存ダイアログを表示
int selected = FileSelectDialog("Save Picture", NULL, "All files (*.*)|*.*", FSD_WRITE_FILE, file_names, file_name + ".png");
// ファイルが選択されなかった場合
if (selected < 1)
{
if (selected < 0)
PrintFormat("%s: FileSelectDialog() function returned error %d", __FUNCTION__, GetLastError());
return false;
}
bool res = false;
// グラフを非表示にしてスクリーンショットを撮る
if (ChartSetInteger(0, CHART_SHOW, false))
res = ChartScreenShot(0, file_names[0], GRAPH_WIDTH, GRAPH_HEIGHT);
// グラフを再表示
ChartSetInteger(0, CHART_SHOW, true);
return(res);
}
関数の概要
MakeAndSaveScreenshot関数は、現在のグラフのスクリーンショットを撮り、指定されたファイル名で画像ファイルとして保存します。この関数は、スクリーンショットを撮る際に一時的にグラフを非表示にし、撮影後に再表示することで、正確なスクリーンショットを取得します。
各部分の説明
ファイル名の配列とエラーレセット
string file_names[];
ResetLastError();
この部分では、ファイル名を格納するための配列file_namesを宣言し、ResetLastError関数を使用して、前回のエラーをリセットします。
ファイル保存ダイアログの表示
// ファイル保存ダイアログを表示
int selected = FileSelectDialog("Save Picture", NULL, "All files (*.*)|*.*", FSD_WRITE_FILE, file_names, file_name + ".png");
この部分では、
FileSelectDialog関数を使用してファイル保存ダイアログを表示し、ユーザーにファイルの保存場所と名前を選択させます。選択されたファイル名はfile_names配列に格納されます。
識別子FSD_WRITE_FILEは、FileSelectDialog関数で使用される定数で、ファイルを保存するためのダイアログを開くために使用されます。このFSD_WRITE_FILEを指定することで、ユーザーがファイルを選択するときに、保存ダイアログとして機能します。
※FileSelectDialog関数の引数内に記述されている文字列の↓
(*.*)|*.*
についてですが、これはファイル選択ダイアログで使用されるフィルタ文字列で、ユーザーが特定の種類のファイルのみを表示するようにフィルタリングできる形式を指定しています。
このフィルタ文字列の形式は一般的に次のように解釈されます:
(\*.\*)
:- 最初の部分はフィルタの説明です。ここでは「すべてのファイル」を意味します。
|
:- これはフィルタの説明と実際のフィルタパターンを分けるセパレーター(区切り文字)です。
\*.\*
:- これはフィルタパターンそのものです。ここでは、すべてのファイルを意味します。
ファイルが選択されなかった場合の処理
// ファイルが選択されなかった場合
if (selected < 1)
{
if (selected < 0)
PrintFormat("%s: FileSelectDialog() function returned error %d", __FUNCTION__, GetLastError());
return false;
}
この部分では、ファイル保存ダイアログでファイルが選択されなかった場合の処理を行います。選択されなかった場合、またはエラーが発生した場合は、falseを返します。
スクリーンショットの撮影
bool res = false;
// グラフを非表示にしてスクリーンショットを撮る
if (ChartSetInteger(0, CHART_SHOW, false))
res = ChartScreenShot(0, file_names[0], GRAPH_WIDTH, GRAPH_HEIGHT);
// グラフを再表示
ChartSetInteger(0, CHART_SHOW, true);
この部分では、グラフを一時的に非表示にしてからスクリーンショットを撮影し、再度グラフを表示します。ChartSetInteger関数を使用して、チャートの表示設定を変更します。ChartScreenShot関数を使用して、スクリーンショットを撮影し、指定されたファイル名で保存します。スクリーンショットの撮影が成功した場合、res変数にtrueが設定されます。
戻り値の設定
return(res);
この部分では、スクリーンショットの撮影結果を返します。撮影が成功した場合はtrueを、失敗した場合はfalseを返します。
関数の説明
- FileSelectDialog関数:
ファイル保存ダイアログを表示し、ユーザーにファイルの保存場所と名前を選択させます。選択されたファイル名は指定された配列に格納されます。 - ResetLastError関数:
前回のエラー情報をリセットします。 - ChartSetInteger関数:
指定されたチャートプロパティを設定します。ここでは、チャートの表示/非表示を切り替えるために使用されます。 - ChartScreenShot関数:
現在のチャートのスクリーンショットを撮影し、指定されたファイル名で保存します。 - PrintFormat関数:
フォーマットされた文字列をエキスパートログに出力します。
この関数を使用することで、ユーザーは現在のグラフのスクリーンショットを撮り、任意の場所に画像ファイルとして保存することができます。これにより、グラフの状態を記録することができます。
まとめ
このサンプルコードは、MQL5でグラフを描画し、そのグラフのスクリーンショットを撮って保存するための一連の処理を実装しています。たくさんの関数が出てきて「一体このこーどはなにをやっているんだ・・・」と混乱してしまった方もいるかもしれません。
最後に、各関数がどのような役割を担い、サンプルコードが全体としてどのように連動しているかを説明します。
OnStart関数
OnStart関数は、このスクリプトの実行が開始されると、最初に呼び出される関数です。ここでは、次の一連の操作を行います。
- 逆余弦を計算するための値のセットを生成します。
- 生成した値を使って逆余弦を計算し、その結果を配列に格納します。
- 格納された値を使用してグラフを描画します。
- ユーザーがESCキーまたはPgDnキーを押すまで待機し、ESCキーが押された場合はグラフを削除し、PgDnキーが押された場合はスクリーンショットを撮って保存します。
CurvePlot関数
この関数は、OnStart関数から呼び出され、グラフを描画します。指定されたX軸とY軸のデータを使ってグラフを作成し、ユーザーに指示を表示するためのテキストも追加します。最終的に、グラフを更新して描画内容を反映させます。
StopKeyPressed関数
この関数は、ユーザーがESCキーまたはPgDnキーを押したかどうかをチェックします。ESCキーが押された場合はtrueを返してスクリプトの終了を指示し、PgDnキーが押された場合はスクリーンショットを撮って保存し、保存が成功した場合にtrueを返します。
MakeAndSaveScreenshot関数
この関数は、PgDnキーが押されたときに呼び出され、グラフのスクリーンショットを撮って保存します。まず、ユーザーにファイルの保存場所と名前を選択させ、次にグラフを一時的に非表示にしてからスクリーンショットを撮影し、指定されたファイルに保存します。最後に、グラフを再表示します。
全体の流れ
- スクリプトが開始されると、OnStart関数が呼び出され、値の生成、逆余弦の計算、グラフの描画が行われます。
- ユーザーの入力(ESCキーまたはPgDnキー)があるまで待機し、入力があった場合に適切な処理を行います。
- ESCキーが押された場合はグラフを削除し、PgDnキーが押された場合はスクリーンショットを撮って保存します。
- スクリプトの終了時に、使用したリソース(グラフオブジェクトなど)をクリーンアップします。