coding UTF-8; import Math; import Text; import GUI; import File; import tool.Graph3D; /** グラフに描画する数式 x(t) のデフォルト入力値です。 */ const string DEFAULT_X_EXPRESSION = "cos(t*4*PI)"; /** グラフに描画する数式 y(t) のデフォルト入力値です。 */ const string DEFAULT_Y_EXPRESSION = "sin(t*2*PI)"; /** グラフに描画する数式 z(t) のデフォルト入力値です。 */ const string DEFAULT_Z_EXPRESSION = "sin(t*PI)"; /** 媒介変数 t(時刻)の最大値(終了値)のデフォルト入力値です。 */ const string DEFAULT_T_MAX = "1.0"; /** 媒介変数 t(時刻)の最小値(開始値)のデフォルト入力値です。 */ const string DEFAULT_T_MIN = "-1.0"; /** 媒介変数 t の範囲を分割する点数(プロット点数)のデフォルト入力値です。 */ const string DEFAULT_T_N = "300"; // 以下、グラフやGUIコンポーネントIDを格納する変数 /** グラフのIDを格納します。 **/ int graph; /** 入力画面のウィンドウのIDを格納します。 */ int window; /** x(t) の数式を入力するテキストフィールドのIDを格納します。 */ int xExpressionField; /** y(t) の数式を入力するテキストフィールドのIDを格納します。 */ int yExpressionField; /** z(t) の数式を入力するテキストフィールドのIDを格納します。 */ int zExpressionField; /** 時刻 t の最大値を入力するテキストフィールドのIDを格納します。 */ int tMaxField; /** 時刻 t の最小値を入力するテキストフィールドのIDを格納します。 */ int tMinField; /** 時刻の刻み数(=グラフのプロット点数)を入力するテキストフィールドのIDを格納します。 */ int tNField; /** PLOTボタンのIDを格納します。 */ int plotButton; /** CLEARボタンのIDを格納します。 */ int clearButton; /** ANIMATIONボタンのIDを格納します。 */ int animationButton; /** EXPORTボタンのIDを格納します。 */ int exportButton; /** EXITボタンのIDを格納します。 */ int exitButton; /** * プログラムの開始時に自動で実行されます。 */ void main(){ // GUIを備えたツールではコンソール画面は邪魔なので非表示化 hide(); // システム側で標準接続されている3DグラフソフトがあればIDを取得(無ければnewGraph3D関数同様、新規に立ち上がる) graph = getGraph3D(); // ※ 普通に newGraph3D 関数で新規生成しないのは、このプログラムがリニアングラフ3Dにも同梱されるツールであり、 // リニアングラフ3D上でメニューからこのプログラムを実行した際に、そのグラフ自身を制御対象とするためです。 // グラフ画面の位置とサイズを設定 setGraph3DLocation(graph, 350, 0); setGraph3DSize(graph, 720, 600); // グラフのプロットオプションを設定(点プロットと線プロットをONに) setGraph3DOption( graph, "WITH_POINTS", true ); setGraph3DOption( graph, "WITH_LINES", true ); setGraph3DOption( graph, "WITH_MEMBRANES", false ); setGraph3DOption( graph, "WITH_MESHES", false ); // 設定画面を起動 createSettingWindow(); } /** * 引数に指定された数式をグラフにプロットします。 * * @param xExpression プロットするxの数式(時刻変数tの関数) * @param yExpression プロットするyの数式(時刻変数tの関数) * @param zExpression プロットするzの数式(時刻変数tの関数) * @param yMin 時刻変数tの最小値(開始値) * @param yMax 時刻変数tの最大値(終了値) * @param n プロット点数 */ void plotGraph( string xExpression, string yExpression, string zExpression, double tMax, double tMin, int n ){ // グラフに転送するデータ配列 double xArray[n]; double yArray[n]; double zArray[n]; // グラフを構成する点の x, y, z 座標および時刻 t を格納する変数 //(入力された x, y の数式の中でも変数 t は参照するので、スコープの都合上ここで宣言) double x; double y; double z; double t; // x, y, z の数式が文法的に正しいか検査 if( !evaluable(xExpression, 0.0) ){ alert("x(t)の式に誤りがあります。"); return; } if( !evaluable(yExpression, 0.0) ){ alert("y(t)の式に誤りがあります。"); return; } if( !evaluable(zExpression, 0.0) ){ alert("z(t)の式に誤りがあります。"); return; } // 時間範囲をn分割した時刻 t において、数式から x, y の値を求め、配列に格納 float dt = (tMax-tMin)/(n-1); for( int i=0; i<n; i++ ){ t = tMin + i * dt; // 文字列の式を解釈してfloatの値を得る(第2引数は式内の整数を浮動小数点数と見なすオプション) x = feval( xExpression, 0.0 ); y = feval( yExpression, 0.0 ); z = feval( zExpression, 0.0 ); xArray[ i ] = x; yArray[ i ] = y; zArray[ i ] = z; } // データ配列をグラフソフトウェアに転送し、追加プロット addGraph3DData( graph, xArray, yArray, zArray ); } /** * 設定画面を起動します。 */ void createSettingWindow(){ int fontSize = 20; int leftWidth = 120; int rightX = leftWidth + 10; int rightWidth = 160; int buttonWidth = 270; window = newWindow( 0, 0, 320, 580, "入力画面" ); int xExpressionLabel = newTextLabel( 10, 10, leftWidth, 25, "x( t ) =" ); setComponentFontSize( xExpressionLabel, fontSize ); mountComponent( xExpressionLabel, window ); xExpressionField = newTextField( rightX, 10, rightWidth, 25, DEFAULT_X_EXPRESSION ); setComponentFontSize( xExpressionField, fontSize ); mountComponent( xExpressionField, window ); int yExpressionLabel = newTextLabel( 10, 50, leftWidth, 25, "y( t ) =" ); setComponentFontSize( yExpressionLabel, fontSize ); mountComponent( yExpressionLabel, window ); yExpressionField = newTextField( rightX, 50, rightWidth, 25, DEFAULT_Y_EXPRESSION ); setComponentFontSize( yExpressionField, fontSize ); mountComponent( yExpressionField, window ); int zExpressionLabel = newTextLabel( 10, 90, leftWidth, 25, "z( t ) =" ); setComponentFontSize( zExpressionLabel, fontSize ); mountComponent( zExpressionLabel, window ); zExpressionField = newTextField( rightX, 90, rightWidth, 25, DEFAULT_Z_EXPRESSION ); setComponentFontSize( zExpressionField, fontSize ); mountComponent( zExpressionField, window ); int tMaxLabel = newTextLabel( 10, 140, leftWidth, 25, "t-max =" ); setComponentFontSize( tMaxLabel, fontSize ); mountComponent( tMaxLabel, window ); tMaxField = newTextField( rightX, 140, rightWidth, 25, DEFAULT_T_MAX ); setComponentFontSize( tMaxField, fontSize ); mountComponent( tMaxField, window ); int tMinLabel = newTextLabel( 10, 170, leftWidth, 25, "t-min =" ); setComponentFontSize( tMinLabel, fontSize ); mountComponent( tMinLabel, window ); tMinField = newTextField( rightX, 170, rightWidth, 25, DEFAULT_T_MIN ); setComponentFontSize( tMinField, fontSize ); mountComponent( tMinField, window ); int tNLabel = newTextLabel( 10, 200, leftWidth, 25, "t-N =" ); setComponentFontSize( tNLabel, fontSize ); mountComponent( tNLabel, window ); tNField = newTextField( rightX, 200, rightWidth, 25, DEFAULT_T_N ); setComponentFontSize( tNField, fontSize ); mountComponent( tNField, window ); int buttonGridPanel = newGridPanel( 10, 240, buttonWidth, 280, "", 5, 1 ); mountComponent( buttonGridPanel, window ); plotButton = newButton( 0, 0, 0, 0, "プロット" ); setComponentFontSize( plotButton, fontSize ); mountComponent( plotButton, buttonGridPanel ); animationButton = newButton( 0, 0, 0, 0, "アニメーション" ); setComponentFontSize( animationButton, fontSize ); mountComponent( animationButton, buttonGridPanel ); clearButton = newButton( 0, 0, 0, 0, "クリア" ); setComponentFontSize( clearButton, fontSize ); mountComponent( clearButton, buttonGridPanel ); exportButton = newButton( 0, 0, 0, 0, "データ出力" ); setComponentFontSize( exportButton, fontSize ); mountComponent( exportButton, buttonGridPanel ); exitButton = newButton( 0, 0, 0, 0, "終了" ); setComponentFontSize( exitButton, fontSize ); mountComponent( exitButton, buttonGridPanel ); } /** * 現在のデータをファイルに出力します。 */ void exportFile(){ // ファイルパスの選択 string exportFilePath[] = choose(); if (length(exportFilePath) == 0) { return; // 何も選択されなかった場合 } // 拡張子が無ければ付ける string name = getFileName( exportFilePath[0] ); if( indexOf(name,".") < 0 ){ exportFilePath += ".dat3d"; } // ファイル出力 exportGraph3DData(graph, exportFilePath[0], "COLUMN_TSV"); // 保存完了メッセージを表示 pop( "SAVED: " + exportFilePath[0] ); } /** * 入力画面上の入力項目において、式として評価するのに適さない文字を、適切な文字で置き換えます。 */ void correctCharactersOnInputWindow() { setComponentText( xExpressionField, correctCharactersInExpression( getComponentText(xExpressionField) ) ); setComponentText( yExpressionField, correctCharactersInExpression( getComponentText(yExpressionField) ) ); setComponentText( zExpressionField, correctCharactersInExpression( getComponentText(zExpressionField) ) ); setComponentText( tMaxField, correctCharactersInExpression( getComponentText(tMaxField) ) ); setComponentText( tMinField, correctCharactersInExpression( getComponentText(tMinField) ) ); setComponentText( tNField, correctCharactersInExpression( getComponentText(tNField) ) ); } /** * 文字列内で、式として評価するのに適さない文字を、適切な文字で置き換えます。 * * @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 ){ // 「PLOT」ボタンが押された場合 if( id == plotButton ){ // 画面上に入力されている文字列内で、式として評価するのに適さない文字を、適切な文字で置き換え correctCharactersOnInputWindow(); // 以下、画面から入力内容を取得 // 入力された x, y, z の数式を取得 string xExpression = getComponentText( xExpressionField ); string yExpression = getComponentText( yExpressionField ); string zExpression = getComponentText( zExpressionField ); // t の範囲の最大・最小値やプロット点数の入力内容が、文法的に正しいか検査 if( !evaluable( getComponentText( tMaxField ), 0.0 ) ){ alert("t-maxの式に誤りがあります。"); return; } if( !evaluable( getComponentText( tMinField ), 0.0 ) ){ alert("t-minの式に誤りがあります。"); return; } if( !evaluable( getComponentText( tNField ), 0.0 ) ){ alert("t-Nの式に誤りがあります。"); return; } // t の範囲の最大・最小値やプロット点数の入力内容を解釈し、値を求める double tMax = feval( getComponentText( tMaxField ), 0.0 ); double tMin = feval( getComponentText( tMinField ), 0.0 ); int tN = feval( getComponentText( tNField ), 0.0 ); // x, y, z の数式をグラフにプロットする(plotGraph関数はこのファイル内の上の方で定義) plotGraph( xExpression, yExpression, zExpression, tMax, tMin, tN ); return; } // 「CLEAR」ボタンが押された場合 if( id == clearButton ){ clearGraph3D(graph); return; } // 「ANIMATION」ボタンが押された場合 if( id == animationButton ){ setGraph3DAnimation( graph, "TRACE", true ); return; } // 「SAVE」ボタンが押された場合 if( id == exportButton ){ exportFile(); return; } // 「EXIT」ボタンが押された場合 if( id == exitButton ){ exit(); return; } } /** * ウィンドウが閉じられた際にコールされます(イベントハンドラ) */ void onWindowClose( int id ){ if( id == window ){ exit(); return; } } /** * グラフが閉じられた際にコールされます(イベントハンドラ) */ void onGraph3DClose( int id ){ if( id == graph ){ exit(); return; } }