coding Shift_JIS; import Math; import Text; import GUI; import File; import tool.Graph3D; /** グラフに描画する数式 z(x,y,t) のデフォルト入力値です。 */ const string DEFAULT_Z_EXPRESSION = "sin(3*x) + cos(3*y-t)"; /** グラフのX範囲の最大値のデフォルト入力値です。 */ const string DEFAULT_X_MAX = "1.0"; /** グラフのX範囲の最小値のデフォルト入力値です。 */ const string DEFAULT_X_MIN = "-1.0"; /** グラフのメッシュにおけるX方向の点数のデフォルト入力値です。 */ const string DEFAULT_X_N = "60"; /** グラフのY範囲の最大値のデフォルト入力値です。 */ const string DEFAULT_Y_MAX = "1.0"; /** グラフのY範囲の最小値のデフォルト入力値です。 */ const string DEFAULT_Y_MIN = "-1.0"; /** グラフのメッシュにおけるY方向の点数のデフォルト入力値です。 */ const string DEFAULT_Y_N = "60"; /** 時刻 t の最大値(終了値)のデフォルト入力値です。 */ const string DEFAULT_MAX = "100.0"; /** 時刻 t の最小値(開始値)のデフォルト入力値です。 */ const string DEFAULT_MIN = "0.0"; /** デフォルトのファイル保存先フォルダです。 */ const string DEFAULT_OUTPUT_DIRECTORY_PATH = "./output"; /** デフォルトの出力ファイル名(番号部を除く)です。 */ const string DEFAULT_OUTPUT_FILE_NAME_HEAD = "sample3d_"; /** アニメーションの間、数式 z(x,y,t) の内容を控えておく変数です。 */ string zExpression; /** アニメーションの間、グラフのX範囲の最大値を控えておく変数です。 */ float xMax; /** アニメーションの間、グラフのX範囲の最小値を控えておく変数です。 */ float xMin; /** グラフのメッシュにおけるX方向の点数を控えておく変数です。 */ int xN; /** アニメーションの間、グラフのY範囲の最大値を控えておく変数です。 */ float yMax; /** アニメーションの間、グラフのY範囲の最小値を控えておく変数です。 */ float yMin; /** グラフのメッシュにおけるY方向の点数を控えておく変数です。 */ int yN; /** アニメーションの間、時刻 t の最大値(終了値)を控えておく変数です。 */ float tMax; /** アニメーションの間、時刻 t の最小値(開始値)を控えておく変数です。 */ float tMin; // 以下、アニメーション処理や制御用の変数 /** グラフにプロットする座標点列のX値を格納する配列です。 */ double xVertexArray[0][0]; /** グラフにプロットする座標点列のY値を格納する配列です。 */ double yVertexArray[0][0]; /** グラフにプロットする座標点列のZ値を格納する配列です。 */ double zVertexArray[0][0]; /** メインループの継続状態を保持します(falseにすると脱出)。 */ bool mainLoopState = true; /** アニメーションの状態を保持します(true=アニメーション中、false=待機状態)。 */ bool animationState = false; /** フレームカウンタ(アニメーションの描画回数の中で、何回目かを保持するカウンタ)です。 */ int frameCounter; /** アニメーションを終了する最終フレームカウンタ値です。フレーム間の時刻変数 t の増分は、時間範囲をこの値で割ったものになります。 */ int frameCounterMax = 1000; /** 時刻が1つ進む際の待ち時間(アニメーションウェイト)です。 */ int animationWait = 30; /** グラフをプロットするリクエストフラグ(trueにするとメインループでプロットされ、falseに戻される)です。 */ bool plotRequest = false; /** グラフ設定を再読み込みするリクエストフラグ(trueにするとメインループで読み込み処理が行われ、falseに戻される)です。 */ bool reloadRequest = false; /** メインループで連番画像出力処理を行うためのフラグです。 */ bool animationExportRequest = false; // 以下、グラフやGUIコンポーネントIDを格納する変数 /** グラフのIDを格納します。 **/ int graph = NULL; /** 入力画面のウィンドウのIDを格納します。 */ int inputWindow = NULL; /** z(x,y,t) の数式を入力するテキストフィールドのIDを格納します。 */ int expressionField = NULL; /** X軸の最大値を入力するテキストフィールドのIDを格納します。 */ int xMaxField = NULL; /** X軸の最小値を入力するテキストフィールドのIDを格納します。 */ int xMinField = NULL; /** グラフのメッシュにおけるX方向の点数を入力するテキストフィールドのIDを格納します。 */ int xNField = NULL; /** Y軸の最大値を入力するテキストフィールドのIDを格納します。 */ int yMaxField = NULL; /** Y軸の最小値を入力するテキストフィールドのIDを格納します。 */ int yMinField = NULL; /** グラフのメッシュにおけるY方向の点数を入力するテキストフィールドのIDを格納します。 */ int yNField = NULL; /** 時刻 t の最小値(開始値)を入力するテキストフィールドのIDを格納します。 */ int tMaxField = NULL; /** 時刻 t の最大値(終了値)を入力するテキストフィールドのIDを格納します。 */ int tMinField = NULL; /** Z軸の最大値を入力するテキストフィールドのIDを格納します。 */ int zMaxField = NULL; /** Z軸の最小値を入力するテキストフィールドのIDを格納します。 */ int zMinField = NULL; /** Z軸の範囲を自動調整するかどうかを選択するチェックボックスのIDを格納します。 */ int zAutoRangeBox = NULL; /** SETボタンのIDを格納します。 */ int setButton = NULL; /** 画像出力ボタンのIDを格納します。 */ int outputButton = NULL; /** EXITボタンのIDを格納します。 */ int exitButton = NULL; /** 画像出力フォルダ指定フィールドのIDを指定します。 */ int outputPathField = NULL; /** 画像出力フォルダ選択ボタンのIDを指定します。 */ int outputPathSelectButton = NULL; /** アニメーション操作ウィンドウのIDを格納します。 */ int animationWindow = NULL; /** アニメーションの「PLAY」/「STOP」ボタンのIDを格納します。 */ int animationButton = NULL; /** アニメーションの時間操作スライダーのIDを格納します。 */ int animationSlider = NULL; /** アニメーションの時間表示ラベルのIDを格納します。 */ int animationLabel = NULL; /** * プログラムの開始時に自動で実行されます。 */ void main(){ // GUIを備えたツールではコンソール画面は邪魔なので非表示化 hide(); // システム側で標準接続されている3DグラフソフトがあればIDを取得(無ければnewGraph3D関数同様、新規に立ち上がる) graph = getGraph3D(); // ※ 普通に newGraph3D 関数で新規生成しないのは、このプログラムがリニアングラフ3Dにも同梱されるツールであり、 // リニアングラフ3D上でメニューからこのプログラムを実行した際に、そのグラフ自身を制御対象とするためです。 // このプログラムでは、既存のグラフ内容に重ね描きする用途は考えにくいので、最初に内容をクリアしておく clearGraph3D(graph); // グラフ画面の位置とサイズを設定 setGraph3DLocation(graph, 340, 120); setGraph3DSize(graph, 720, 600); // プロットオプションを設定 setGraph3DOption( graph, "WITH_POINTS", false ); setGraph3DOption( graph, "WITH_LINES", false ); setGraph3DOption( graph, "WITH_MEMBRANES", true ); setGraph3DOption( graph, "WITH_MESHES", false ); // 設定画面を起動 createInputWindow(); // メインループ ― プログラム終了までずっと繰り返し、必要なら処理を行い、何も無ければ待機する while( mainLoopState ){ if (animationExportRequest) { string outputDirectoryPath = getComponentText(outputPathField); if (!exists(outputDirectoryPath)) { alert("指定された保存先フォルダ「" + outputDirectoryPath + "」が存在しません。"); } else if (!isdir(outputDirectoryPath)) { alert("指定された保存先フォルダ「" + outputDirectoryPath + "」はフォルダではありません。"); } else { outputDirectoryPath = getFilePath(outputDirectoryPath); outputImages(outputDirectoryPath); } frameCounter = 0; plotRequest = true; animationExportRequest = false; } if ( animationExportRequest ) { sleep( animationWait ); continue; } if( animationState ){ frameCounter++; if( frameCounter <= frameCounterMax ){ setComponentValueInt( animationSlider, frameCounter ); }else{ setAnimationState( false ); } } if (reloadRequest) { reloadRange(); plotGraph( frameCounter ); if( animationWindow < 0 ){ createAnimationWindow(); }else{ setComponentVisible( animationWindow, true ); } setTimer(0); reloadRequest = false; } if( plotRequest ){ plotGraph( frameCounter ); plotRequest = false; } sleep( animationWait ); } // メインループを脱出すれば終了 exit(); } /** * 現在のzExpressionの内容をグラフにプロットします。 * * @param frameIndex アニメーション始点を 0 とする、プロット対象フレームのインデックス */ void plotGraph(int frameIndex){ // フレームインデックスから、時刻の値へ変換 float dt = (tMax-tMin)/frameCounterMax; float t = tMin + frameIndex * dt; // グラフに転送するデータ配列を xN * yN 要素で確保 alloc[yN][xN] xVertexArray; alloc[yN][xN] yVertexArray; alloc[yN][xN] zVertexArray; // 座標を計算し、データ配列に数値を代入 double x; double y; double z; for( int i=0; i zMax ){ zMax = z; } } } rate = frameCounter*10 / (frameCounterMax-1); if( rate != rateStock ){ setComponentText( setButton, "計算中: " + rate + "0 %" ); } rateStock = rate; } setComponentText( setButton, "セット" ); clear(); double range[] = { zMax, zMin }; return range; } /** * アニメーションのON/OFF状態を切り替えます。 * * @param state アニメーションのON/OFF状態(ONならtrue) */ void setAnimationState( bool state ){ animationState = state; if( state ){ // タイマーが最終時刻なら、時刻を初期化 if( getComponentValueInt( animationSlider ) == frameCounterMax ){ resetTimer(); } setComponentText( animationButton, "STOP" ); }else{ setComponentText( animationButton, "PLAY" ); } } /** * アニメーション中の時刻を設定します。 * * @param t 設定する時刻 */ void setTimer( int t ){ frameCounter = t; plotRequest = true; } /** * 時刻を初期化します(アニメーション終了時) */ void resetTimer(){ frameCounter = 0; double tMin = getComponentText( tMinField ); setComponentText( animationLabel, "t = " + tMin ); setComponentValueInt( animationSlider, 0 ); return; } /** * グラフを連番画像として保存します。 * @param outputDirectoryPath 保存フォルダのパス */ void outputImages(string outputDirectoryPath) { // カーソルを描画させないためにグラフ画面を非表示にする hideGraph3D(graph); if (animationWindow == NULL) { popup("先に「 セット 」を行い、設定内容をアニメーションに反映させてください。"); showGraph3D(graph); return; } string outputFileNameHead = input("保存ファイル名(番号部を除く)を入力", DEFAULT_OUTPUT_FILE_NAME_HEAD); if (outputFileNameHead == NULL) { showGraph3D(graph); return; } setComponentText(outputButton, "保存中..."); // 操作できないように設定画面を非表示にし、代わりに進捗を表示するためコンソールを表示する hideComponent(animationWindow); hideComponent(inputWindow); show(); setAnimationState(false); plotRequest = false; popup( "アニメーションの全フレーム(コマ)のグラフを、連番の画像ファイルとして保存します。" + EOL + "これには少し時間がかかる事があります。" + EOL + "「 OK 」を押した後は、操作せずに完了までしばらくお待ちください。" ); // ファイルをプロットして画像に保存、を全ての入力ファイルに対してくり返す sleep(1000); for (int frameIndex=0; frameIndex<=frameCounterMax; frameIndex++) { plotGraph(frameIndex); string outputFileName = outputFileNameHead + frameIndex + ".png"; string outputFilePath = getFilePath(outputFileName, outputDirectoryPath); println("画像保存(" + frameIndex + "/" + frameCounterMax + "): " + outputFilePath); exportGraph3D(graph, outputFilePath, "PNG"); sleep(20); } // 処理が終わったのでグラフ画面や設定画面を表示し、コンソールは邪魔なので非表示にする showGraph3D(graph); showComponent(animationWindow); showComponent(inputWindow); hide(); setComponentText(outputButton, "画像保存"); popup("保存しました。保存先フォルダ: " + EOL + outputDirectoryPath); frameCounter = 0; setComponentValueInt( animationSlider, 0 ); } /** * 設定画面を起動します。 */ void createInputWindow(){ int leftWidth = 100; int rightX = leftWidth + 10; int rightWidth = 190; int buttonWidth = 290; int fontSize = 20; inputWindow = newWindow( 0, 0, 340, 640, "入力画面" ); int expressionLabel = newTextLabel( 10, 10, leftWidth, 25, "z(x,y,t) = " ); setComponentFontSize(expressionLabel, fontSize); mountComponent( expressionLabel, inputWindow ); expressionField = newTextField( rightX, 10, rightWidth, 25, DEFAULT_Z_EXPRESSION ); setComponentFontSize(expressionField, fontSize); mountComponent( expressionField, inputWindow ); int lowX = 10; int columnWidth = 70; int xMaxLabel = newTextLabel( lowX, 60, columnWidth, 25, "x-max" ); setComponentFontSize(xMaxLabel, fontSize); mountComponent( xMaxLabel, inputWindow ); xMaxField = newTextField( lowX+columnWidth, 60, columnWidth, 25, DEFAULT_X_MAX ); setComponentFontSize(xMaxField, fontSize); mountComponent( xMaxField, inputWindow ); int xMinLabel = newTextLabel( lowX, 90, columnWidth, 25, "x-min" ); setComponentFontSize(xMinLabel, fontSize); mountComponent( xMinLabel, inputWindow ); xMinField = newTextField( lowX+columnWidth, 90, columnWidth, 25, DEFAULT_X_MIN ); setComponentFontSize(xMinField, fontSize); mountComponent( xMinField, inputWindow ); int xNLabel = newTextLabel( lowX, 120, columnWidth, 25, "x-N" ); setComponentFontSize(xNLabel, fontSize); mountComponent( xNLabel, inputWindow ); xNField = newTextField( lowX+columnWidth, 120, columnWidth, 25, DEFAULT_X_N ); setComponentFontSize(xNField, fontSize); mountComponent( xNField, inputWindow ); lowX = 160; columnWidth = 70; int yMaxLabel = newTextLabel( lowX, 60, columnWidth, 25, "y-max" ); setComponentFontSize(yMaxLabel, fontSize); mountComponent( yMaxLabel, inputWindow ); yMaxField = newTextField( lowX+columnWidth, 60, columnWidth, 25, DEFAULT_Y_MAX ); setComponentFontSize(yMaxField, fontSize); mountComponent( yMaxField, inputWindow ); int yMinLabel = newTextLabel( lowX, 90, columnWidth, 25, "y-min" ); setComponentFontSize(yMinLabel, fontSize); mountComponent( yMinLabel, inputWindow ); yMinField = newTextField( lowX+columnWidth, 90, columnWidth, 25, DEFAULT_Y_MIN ); setComponentFontSize(yMinField, fontSize); mountComponent( yMinField, inputWindow ); int yNLabel = newTextLabel( lowX, 120, columnWidth, 25, "y-N" ); setComponentFontSize(yNLabel, fontSize); mountComponent( yNLabel, inputWindow ); yNField = newTextField( lowX+columnWidth, 120, columnWidth, 25, DEFAULT_Y_N ); setComponentFontSize(yNField, fontSize); mountComponent( yNField, inputWindow ); int tMaxLabel = newTextLabel( 10, 170, leftWidth, 25, "t-max =" ); setComponentFontSize(tMaxLabel, fontSize); mountComponent( tMaxLabel, inputWindow ); tMaxField = newTextField( rightX, 170, rightWidth, 25, DEFAULT_MAX ); setComponentFontSize(tMaxField, fontSize); mountComponent( tMaxField, inputWindow ); int tMinLabel = newTextLabel( 10, 200, leftWidth, 25, "t-min =" ); setComponentFontSize(tMinLabel, fontSize); mountComponent( tMinLabel, inputWindow ); tMinField = newTextField( rightX, 200, rightWidth, 25, DEFAULT_MIN ); setComponentFontSize(tMinField, fontSize); mountComponent( tMinField, inputWindow ); zAutoRangeBox = newCheckBox( 10, 250, 500, 20, "Z範囲を自動設定", true ); mountComponent( zAutoRangeBox, inputWindow ); int zMaxLabel = newTextLabel( 10, 280, leftWidth, 25, "z-max = " ); setComponentFontSize(zMaxLabel, fontSize); mountComponent( zMaxLabel, inputWindow ); zMaxField = newTextField( rightX, 280, rightWidth, 25, "1.0" ); setComponentFontSize(zMaxField, fontSize); mountComponent( zMaxField, inputWindow ); int zMinLabel = newTextLabel( 10, 310, leftWidth, 25, "z-min = " ); setComponentFontSize(zMinLabel, fontSize); mountComponent( zMinLabel, inputWindow ); zMinField = newTextField( rightX, 310, rightWidth, 25, "-1.0" ); setComponentFontSize(zMinField, fontSize); mountComponent( zMinField, inputWindow ); setButton = newButton( 10, 360, buttonWidth, 50, "セット" ); setComponentFontSize(setButton, fontSize); mountComponent( setButton, inputWindow ); outputButton = newButton( 10, 420, buttonWidth, 50, "画像保存" ); setComponentFontSize(outputButton, fontSize); mountComponent( outputButton, inputWindow ); int outputPathLabel = newTextLabel( 10, 475, 80, 24, "保存場所 ="); mountComponent( outputPathLabel, inputWindow ); outputPathField = newTextField( 90, 475, 120, 24, DEFAULT_OUTPUT_DIRECTORY_PATH); mountComponent( outputPathField, inputWindow ); outputPathSelectButton = newButton( 210, 475, 70, 24, "選択" ); mountComponent( outputPathSelectButton, inputWindow ); exitButton = newButton( 10, 520, buttonWidth, 50, "終了" ); setComponentFontSize(exitButton, fontSize); mountComponent( exitButton, inputWindow ); } /** * アニメーション画面を起動します。 */ void createAnimationWindow(){ animationWindow = newWindow( 340, 0, 500, 120, "アニメーション操作画面" ); animationButton = newButton( 10, 10, 100, 50, "PLAY" ); mountComponent( animationButton, animationWindow ); animationSlider = newHorizontalSlider( 120, 10, 300, 30, 0, frameCounterMax, 0 ); mountComponent( animationSlider, animationWindow ); animationLabel = newTextLabel( 125, 40, 300, 20, "" ); mountComponent( animationLabel, animationWindow ); } /** * 入力画面上の入力項目において、式として評価するのに適さない文字を、適切な文字で置き換えます。 */ void correctCharactersOnInputWindow() { setComponentText( expressionField, correctCharactersInExpression( getComponentText(expressionField) ) ); setComponentText( xMaxField, correctCharactersInExpression( getComponentText(xMaxField) ) ); setComponentText( xMinField, correctCharactersInExpression( getComponentText(xMinField) ) ); setComponentText( xNField, correctCharactersInExpression( getComponentText(xNField) ) ); setComponentText( yMaxField, correctCharactersInExpression( getComponentText(yMaxField) ) ); setComponentText( yMinField, correctCharactersInExpression( getComponentText(yMinField) ) ); setComponentText( yNField, correctCharactersInExpression( getComponentText(yNField) ) ); setComponentText( tMaxField, correctCharactersInExpression( getComponentText(tMaxField) ) ); setComponentText( tMinField, correctCharactersInExpression( getComponentText(tMinField) ) ); } /** * 文字列内で、式として評価するのに適さない文字を、適切な文字で置き換えます。 * * @param 式の内容を格納する文字列 * @return 適切に文字を置き換えた文字列 */ string correctCharactersInExpression(string expression) { string result = expression; result = replaceText(result, "×", "*", Text.ALL); result = replaceText(result, "÷", "/", Text.ALL); result = replaceText(result, "^", "**", Text.ALL); result = replaceText(result, "^", "**", Text.ALL); result = replaceText(result, "+", "+", Text.ALL); result = replaceText(result, "*", "*", Text.ALL); result = replaceText(result, "/", "/", Text.ALL); result = replaceText(result, "ー", "-", Text.ALL); result = replaceText(result, "−", "-", Text.ALL); result = replaceText(result, "―", "-", Text.ALL); result = replaceText(result, "‐", "-", Text.ALL); result = replaceText(result, "ー", "-", Text.ALL); result = replaceText(result, "%", "%", Text.ALL); result = replaceText(result, "(", "(", Text.ALL); result = replaceText(result, ")", ")", Text.ALL); result = replaceText(result, "A", "A", Text.ALL); result = replaceText(result, "B", "B", Text.ALL); result = replaceText(result, "C", "C", Text.ALL); result = replaceText(result, "D", "D", Text.ALL); result = replaceText(result, "E", "E", Text.ALL); result = replaceText(result, "F", "F", Text.ALL); result = replaceText(result, "G", "G", Text.ALL); result = replaceText(result, "H", "H", Text.ALL); result = replaceText(result, "I", "I", Text.ALL); result = replaceText(result, "J", "J", Text.ALL); result = replaceText(result, "K", "K", Text.ALL); result = replaceText(result, "L", "L", Text.ALL); result = replaceText(result, "M", "M", Text.ALL); result = replaceText(result, "N", "N", Text.ALL); result = replaceText(result, "O", "O", Text.ALL); result = replaceText(result, "P", "P", Text.ALL); result = replaceText(result, "Q", "Q", Text.ALL); result = replaceText(result, "R", "R", Text.ALL); result = replaceText(result, "S", "S", Text.ALL); result = replaceText(result, "T", "T", Text.ALL); result = replaceText(result, "U", "U", Text.ALL); result = replaceText(result, "V", "V", Text.ALL); result = replaceText(result, "W", "W", Text.ALL); result = replaceText(result, "X", "X", Text.ALL); result = replaceText(result, "Y", "Y", Text.ALL); result = replaceText(result, "Z", "Z", Text.ALL); result = replaceText(result, "a", "a", Text.ALL); result = replaceText(result, "b", "b", Text.ALL); result = replaceText(result, "c", "c", Text.ALL); result = replaceText(result, "d", "d", Text.ALL); result = replaceText(result, "e", "e", Text.ALL); result = replaceText(result, "f", "f", Text.ALL); result = replaceText(result, "g", "g", Text.ALL); result = replaceText(result, "h", "h", Text.ALL); result = replaceText(result, "i", "i", Text.ALL); result = replaceText(result, "j", "j", Text.ALL); result = replaceText(result, "k", "k", Text.ALL); result = replaceText(result, "l", "l", Text.ALL); result = replaceText(result, "m", "m", Text.ALL); result = replaceText(result, "n", "n", Text.ALL); result = replaceText(result, "o", "o", Text.ALL); result = replaceText(result, "p", "p", Text.ALL); result = replaceText(result, "q", "q", Text.ALL); result = replaceText(result, "r", "r", Text.ALL); result = replaceText(result, "s", "s", Text.ALL); result = replaceText(result, "t", "t", Text.ALL); result = replaceText(result, "u", "u", Text.ALL); result = replaceText(result, "v", "v", Text.ALL); result = replaceText(result, "w", "w", Text.ALL); result = replaceText(result, "x", "x", Text.ALL); result = replaceText(result, "y", "y", Text.ALL); result = replaceText(result, "z", "z", Text.ALL); result = replaceText(result, "1", "1", Text.ALL); result = replaceText(result, "2", "2", Text.ALL); result = replaceText(result, "3", "3", Text.ALL); result = replaceText(result, "4", "4", Text.ALL); result = replaceText(result, "5", "5", Text.ALL); result = replaceText(result, "6", "6", Text.ALL); result = replaceText(result, "7", "7", Text.ALL); result = replaceText(result, "8", "8", Text.ALL); result = replaceText(result, "9", "9", Text.ALL); result = replaceText(result, "0", "0", Text.ALL); result = replaceText(result, ".", ".", Text.ALL); return result; } /** * ボタンが押された際にコールされます(イベントハンドラ) * * @param id 押されたボタンのID */ void onButtonClick( int id ){ // 「SET」ボタンが押された場合 if( id == setButton ){ // 画面上に入力されている文字列内で、式として評価するのに適さない文字を、適切な文字で置き換え correctCharactersOnInputWindow(); // 以下、画面から入力内容を取得 zExpression = getComponentText( expressionField ); if( !evaluable( getComponentText( xMaxField ), 0.0 ) ){ alert("x-maxの式に誤りがあります。"); return; } if( !evaluable( getComponentText( xMinField ), 0.0 ) ){ alert("x-minの式に誤りがあります。"); return; } if( !evaluable( getComponentText( xNField ), 0.0 ) ){ alert("x-Nの式に誤りがあります。"); return; } if( !evaluable( getComponentText( yMaxField ), 0.0 ) ){ alert("y-maxの式に誤りがあります。"); return; } if( !evaluable( getComponentText( yMinField ), 0.0 ) ){ alert("y-minの式に誤りがあります。"); return; } if( !evaluable( getComponentText( yNField ), 0.0 ) ){ alert("y-Nの式に誤りがあります。"); return; } if( !evaluable( getComponentText( tMaxField ), 0.0 ) ){ alert("t-maxの式に誤りがあります。"); return; } if( !evaluable( getComponentText( tMinField ), 0.0 ) ){ alert("t-minの式に誤りがあります。"); return; } xMax = feval( getComponentText( xMaxField ), 0.0); xMin = feval( getComponentText( xMinField ), 0.0); xN = feval( getComponentText( xNField ), 0.0); yMax = feval( getComponentText( yMaxField ), 0.0); yMin = feval( getComponentText( yMinField ), 0.0); yN = feval( getComponentText( yNField ), 0.0); tMax = feval( getComponentText( tMaxField ), 0.0); tMin = feval( getComponentText( tMinField ), 0.0); float x, y, t; if( !evaluable(zExpression, 0.0) ){ alert("f(x,y,t)の式に誤りがあります。"); return; } if( animationWindow == NULL ){ createAnimationWindow(); setComponentVisible(animationWindow, false); } setAnimationState( false ); resetTimer(); reloadRequest = true; return; } // 「画像保存」ボタンが押された場合 if( id == outputButton ){ // このフラグを有効化すると、メインループが連番画像出力処理を行う animationExportRequest = true; return; } // 画像保存先フォルダの選択ボタンを押した際 if ( id == outputPathSelectButton ) { string path = choose(); while (!isdir(path)) { alert("選択されたものがフォルダではありません。" + EOL + "画像を保存するフォルダを選択してください。"); path = choose(); } setComponentText(outputPathField, path); } // 「EXIT」ボタンが押された場合 if( id == exitButton ){ mainLoopState = false; return; } // 「PLAY/STOP」ボタンが押された場合 if( id == animationButton ){ if( animationState ){ setAnimationState( false ); }else{ setAnimationState( true ); } return; } } /** * スライダーが動かされた際にコールされます(イベントハンドラ) * * @param id 動かされたスライダーのID */ void onSliderMove( int id, int value ){ if( id == animationSlider ){ setTimer( value ); } } /** * ウィンドウが閉じられた際にコールされます(イベントハンドラ) * * @param id 閉じられたウィンドウのID */ void onWindowClose( int id ){ if( id == inputWindow ){ // このプログラムでは範囲の自動調整を無効化しているので、終了時に戻しておく setGraph3DAutoRange( graph, true, true, true ); // メインループを脱出、プログラムを終了させる mainLoopState = false; }else if( id == animationWindow ){ animationState = false; } } /** * グラフが閉じられた際にコールされます(イベントハンドラ) * * @param id 閉じられたグラフのID */ void onGraph3DClose( int id ){ if( id == graph ){ animationState = false; } }