coding UTF-8; import Math; import Text; import GUI; import File; import tool.Graph2D; /** The default value of the expression y(x,t) to plot graph */ const string DEFAULT_Y_EXPRESSION = "sin(3*x-t)"; /** The default value of the maximum value of the x-range of the graph. */ const string DEFAULT_X_MAX = "1.0"; /** The default value of the minimum value of the x-range of the graph. */ const string DEFAULT_X_MIN = "-1.0"; /** The default value of the number of the point of the graph. */ const string DEFAULT_X_N = "100"; /** The default value of the maximum value of the y-range of the graph. */ const string DEFAULT_Y_MAX = "1.0"; /** The default value of the minimum value of the y-range of the graph. */ const string DEFAULT_Y_MIN = "-1.0"; /** The default value of the maximum value of the time-parameter t. */ const string DEFAULT_T_MAX = "100.0"; /** The default value of the minimum value of the time-parameter t. */ const string DEFAULT_T_MIN = "0.0"; /** The default directory to which image files will be output. */ const string DEFAULT_OUTPUT_DIRECTORY_PATH = "./output"; /** The default names of saved image files. */ const string DEFAULT_OUTPUT_FILE_NAME_HEAD = "sample2d_"; /** Stores the expression y(x,t) during the animation. */ string yExpression; /** Stores the value of the maximum value of the x-range during the animation. */ float xMax; /** Stores the value of the minimum value of the x-range during the animation. */ float xMin; /** Stores the number of the point of the graph during the animation. */ int xN; /** Stores the maximum value of the time-parameter t during the animation. */ float tMax; /** Stores the maximum value of the time-parameter t during the animation. */ float tMin; // Followings are variables for animations, for plottings, and to control the flow. /** Stores x coordinate values of vertices to plot the graph. */ float xVertexArray[0]; /** Stores y coordinate values of vertices to plot the graph. */ float yVertexArray[0]; /** A flag to control the continuation of the main loop (set this false to break main loop). */ bool mainLoopState = true; /** A flag to control the state of the animation (true: playing, false: stopping). */ bool animationState = false; /** The frame counter (which counts-up the number of rendered frames from the start of the animation). */ int frameCounter; /** The value of the frame counter at the end of the animation. The time-interval of each frames is given by dividing the time range by this value. */ int frameCounterMax = 1000; /** The value of the waiting time (millisec) between each frames. */ int animationWait = 30; /** If this flag is true, the graph will be re-plotted in the main loop, and then this flag will be turned into false. */ bool plotRequest = false; /** If this flag is true, graph settings will be re-loaded in the main loop, and then this flag will be turned into false. */ bool reloadRequest = false; /** The flag to perform exporting of all animation images in the main-loop. */ bool animationExportRequest = false; // Followings are variables to store IDs of the graph and GUI components. /** Stores the ID of the graph. */ int graph = NULL; /** Stores the ID of the input-window. */ int inputWindow = NULL; /** Stores the ID of the text-field of the expression y(x,t). */ int expressionField = NULL; /** Stores the ID of the text-field of the maximum value of x-range. */ int xMaxField = NULL; /** Stores the ID of the text-field of the minimum value of x-range. */ int xMinField = NULL; /** Stores the ID of the text-field of the number of points of the graph. */ int xNField = NULL; /** Stores the ID of the text-field of the maximum value of y-range. */ int yMaxField = NULL; /** Stores the ID of the text-field of the minimum value of y-range. */ int yMinField = NULL; /** Stores the ID of the checkbox to control whether adjust the y-range automatically or not. */ int yAutoRangeBox = NULL; /** Stores the ID of the text-field of the maximum (end) value of the time-parameter t. */ int tMaxField = NULL; /** Stores the ID of the text-field of the minimum (begin) value of the time-parameter t. */ int tMinField = NULL; /** Stores the ID of the SET button. */ int setButton = NULL; /** Stores the ID of the SAVE-IMAGES button. **/ int outputButton = NULL; /** Stores the ID of the EXIT button. */ int exitButton = NULL; /** Stores the ID of the text-field to input the path of the folder to which image files will be output. */ int outputPathField = NULL; /** Stores the ID of the text-field to select the folder to which image files will be output. */ int outputPathSelectButton = NULL; /** Stores the ID of the animation-window. */ int animationWindow = NULL; /** Stores the ID of the PLAY button. */ int animationButton = NULL; /** Stores the ID of the time-controlling slider. */ int animationSlider = NULL; /** Stores the ID of the time-displaying label. */ int animationLabel = NULL; /** * Invoked automatically when this program have started. */ void main(){ // Set the console window invisible because it is not necessary for GUI program. hide(); // Create (or get from the system) a 2D graph window. graph = getGraph2D(); clearGraph2D(graph); // Set the size and the location of the graph-window. setGraph2DLocation(graph, 330, 120); setGraph2DSize(graph, 720, 600); // Create and launch the input-window. createInputWindow(); // The main loop (which continues looping until the program will exit). while( mainLoopState ){ if ( animationExportRequest ) { string outputDirectoryPath = getComponentText(outputPathField); if (!exists(outputDirectoryPath)) { alert("The specified folder \"" + outputDirectoryPath + "\" does not exist."); } else if (!isdir(outputDirectoryPath)) { alert("The specified path \"" + outputDirectoryPath + "\" is not the folder."); } else { outputDirectoryPath = getFilePath(outputDirectoryPath); outputImages(outputDirectoryPath); } frameCounter = 0; plotRequest = true; animationExportRequest = false; } 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(); } /** * Plots the expression to the 2D graph. * * @param frameIndex the index of the animation frame (the first frame is 0, the next is 1, ...) to be plotted. */ void plotGraph(int frameIndex){ // Get the value of the time parameter t from the current value of the frame counter. float dt = (tMax-tMin)/frameCounterMax; float t = tMin + frameIndex * dt; // Allocate arrays for storing vertices and transferring them to graph. alloc[xN] xVertexArray; alloc[xN] yVertexArray; // coordinate variables of a point. float x; float y; float dx = (xMax-xMin)/(xN-1); for( int i=0; i yMax ){ yMax = y; } } rate = frameCounter*10 / (frameCounterMax-1); if( rate != rateStock ){ setComponentText( setButton, "Scan: " + rate + "0 %" ); } rateStock = rate; } setComponentText( setButton, "SET" ); clear(); float range[] = { yMin, yMax }; return range; } /** * Sets the state of the animation (playing or stopping). * * @param state true means playing and false means stopping. */ void setAnimationState( bool state ){ animationState = state; if( state ){ // Reset the value of the frame counter if it is the end value of the animation. if( getComponentValueInt( animationSlider ) == frameCounterMax ){ resetTimer(); } setComponentText( animationButton, "STOP" ); }else{ setComponentText( animationButton, "PLAY" ); } } /** * Sets the value of the frame counter (the graph will be re-plotted automatically when this function will be called). * * @param value The value of framecounter you want to set. */ void setTimer( int value ){ frameCounter = value; plotRequest = true; } /** * Resets the value of the frame counter and the value of the time-displaying label. */ void resetTimer(){ frameCounter = 0; setComponentText( animationLabel, "t = " + tMin ); setComponentInt( animationSlider, 0 ); return; } /** * Saves graphs as image files. * * @param outputDirectoryPath the path of the folder to which image files will be saved. */ void outputImages(string outputDirectoryPath) { hideGraph2D(graph); if (animationWindow == NULL) { popup("Please push \"SET\" button to reflect setting parameters."); showGraph2D(graph); return; } string outputFileNameHead = input("Input the file name (excluding number parts) to be saved:", DEFAULT_OUTPUT_FILE_NAME_HEAD); if (outputFileNameHead == NULL) { showGraph2D(graph); return; } setComponentText(outputButton, "Saving..."); hideComponent(animationWindow); hideComponent(inputWindow); show(); setAnimationState(false); plotRequest = false; popup( "This save processing might take few minutes." + EOL + "Please wait without any operations after clicking \"OK\" button." ); // Repeats plotting and saving for all data files. sleep(1000); for (int frameIndex=0; frameIndex<=frameCounterMax; frameIndex++) { plotGraph(frameIndex); string outputFileName = outputFileNameHead + frameIndex + ".png"; string outputFilePath = getFilePath(outputFileName, outputDirectoryPath); println("Save image (" + frameIndex + "/" + frameCounterMax + "): " + outputFilePath); exportGraph2D(graph, outputFilePath, "PNG"); sleep(20); } showGraph2D(graph); showComponent(animationWindow); showComponent(inputWindow); hide(); setComponentText(outputButton, "SAVE IMAGE"); popup("Saved. Folder: " + EOL + outputDirectoryPath); frameCounter = 0; setComponentValueInt( animationSlider, 0 ); } /** * Creates GUI components of the input-window and launch it. */ void createInputWindow(){ int leftWidth = 110; int rightX = leftWidth + 10; int rightWidth = 160; int buttonWidth = 270; int fontSize = 20; inputWindow = newWindow( 0, 0, 320, 630, "Input Window" ); int expressionLabel = newTextLabel( 10, 10, leftWidth, 25, "y( x, t ) =" ); setComponentFontSize(expressionLabel, fontSize); mountComponent( expressionLabel, inputWindow ); expressionField = newTextField( rightX, 10, rightWidth, 25, DEFAULT_Y_EXPRESSION ); setComponentFontSize(expressionField, fontSize); mountComponent( expressionField, inputWindow ); int xMaxLabel = newTextLabel( 10, 60, leftWidth, 25, "x-max =" ); setComponentFontSize(xMaxLabel, fontSize); mountComponent( xMaxLabel, inputWindow ); xMaxField = newTextField( rightX, 60, rightWidth, 25, DEFAULT_X_MAX ); setComponentFontSize(xMaxField, fontSize); mountComponent( xMaxField, inputWindow ); int xMinLabel = newTextLabel( 10, 90, leftWidth, 25, "x-min =" ); setComponentFontSize(xMinLabel, fontSize); mountComponent( xMinLabel, inputWindow ); xMinField = newTextField( rightX, 90, rightWidth, 25, DEFAULT_X_MIN ); setComponentFontSize(xMinField, fontSize); mountComponent( xMinField, inputWindow ); int xNLabel = newTextLabel( 10, 120, leftWidth, 25, "x-N =" ); setComponentFontSize(xNLabel, fontSize); mountComponent( xNLabel, inputWindow ); xNField = newTextField( rightX, 120, rightWidth, 25, DEFAULT_X_N ); setComponentFontSize(xNField, fontSize); mountComponent( xNField, inputWindow ); int tMaxLabel = newTextLabel( 10, 160, leftWidth, 25, "t-max = " ); setComponentFontSize(tMaxLabel, fontSize); mountComponent( tMaxLabel, inputWindow ); tMaxField = newTextField( rightX, 160, rightWidth, 25, DEFAULT_T_MAX ); setComponentFontSize(tMaxField, fontSize); mountComponent( tMaxField, inputWindow ); int tMinLabel = newTextLabel( 10, 190, leftWidth, 25, "t-min = " ); setComponentFontSize(tMinLabel, fontSize); mountComponent( tMinLabel, inputWindow ); tMinField = newTextField( rightX, 190, rightWidth, 25, DEFAULT_T_MIN ); setComponentFontSize(tMinField, fontSize); mountComponent( tMinField, inputWindow ); yAutoRangeBox = newCheckBox( 10, 250, 500, 20, "Auto Y-Range", true ); mountComponent( yAutoRangeBox, inputWindow ); int yMaxLabel = newTextLabel( 10, 280, leftWidth, 25, "y-max = " ); setComponentFontSize(yMaxLabel, fontSize); mountComponent( yMaxLabel, inputWindow ); yMaxField = newTextField( rightX, 280, rightWidth, 25, DEFAULT_Y_MAX ); setComponentFontSize(yMaxField, fontSize); mountComponent( yMaxField, inputWindow ); int yMinLabel = newTextLabel( 10, 310, leftWidth, 25, "y-min = " ); setComponentFontSize(yMinLabel, fontSize); mountComponent( yMinLabel, inputWindow ); yMinField = newTextField( rightX, 310, rightWidth, 25, DEFAULT_Y_MIN ); setComponentFontSize(yMinField, fontSize); mountComponent( yMinField, inputWindow ); setButton = newButton( 10, 360, buttonWidth, 50, "SET" ); setComponentFontSize(setButton, fontSize); mountComponent( setButton, inputWindow ); outputButton = newButton( 10, 420, buttonWidth, 50, "SAVE IMAGE" ); setComponentFontSize(outputButton, fontSize); mountComponent( outputButton, inputWindow ); int outputPathLabel = newTextLabel( 10, 475, 80, 24, "Folder ="); mountComponent( outputPathLabel, inputWindow ); outputPathField = newTextField( 90, 475, 100, 24, DEFAULT_OUTPUT_DIRECTORY_PATH); mountComponent( outputPathField, inputWindow ); outputPathSelectButton = newButton( 190, 475, 90, 24, "SELECT" ); mountComponent( outputPathSelectButton, inputWindow ); exitButton = newButton( 10, 520, buttonWidth, 50, "EXIT" ); setComponentFontSize(exitButton, fontSize); mountComponent( exitButton, inputWindow ); } /** * Creates GUI components of the animation-window and launch it. */ void createAnimationWindow(){ animationWindow = newWindow( 330, 0, 500, 120, "Animation Window" ); 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 ); } /** * Invoked when buttons are clicked (event handler). * * @param id The ID of the clicked button. */ void onButtonClick( int id ){ // Case of SET button is clicked. if( id == setButton ){ yExpression = getComponentText( expressionField ); if( !evaluable( getComponentText( xMaxField ), 0.0 ) ){ alert("The form of the expression of \"x-max\" is wrong."); return; } if( !evaluable( getComponentText( xMinField ), 0.0 ) ){ alert("The form of the expression of \"x-min\" is wrong."); return; } if( !evaluable( getComponentText( xNField ), 0.0 ) ){ alert("The form of the expression of \"x-N\" is wrong."); return; } if( !evaluable( getComponentText( tMaxField ), 0.0 ) ){ alert("The form of the expression of \"t-max\" is wrong."); return; } if( !evaluable( getComponentText( tMinField ), 0.0 ) ){ alert("The form of the expression of \"t-min\" is wrong."); return; } xMax = feval( getComponentText( xMaxField ), 0.0); xMin = feval( getComponentText( xMinField ), 0.0); xN = feval( getComponentText( xNField ), 0.0); tMax = feval( getComponentText( tMaxField ), 0.0); tMin = feval( getComponentText( tMinField ), 0.0); float x, t; if( !evaluable(yExpression, 0.0) ){ alert("The form of the expression of \"y(x,t)\" is wrong."); return; } if( animationWindow == NULL ){ createAnimationWindow(); setComponentVisible(animationWindow, false); } setAnimationState( false ); resetTimer(); reloadRequest = true; return; } // Case of SAVE IMAGES button is clicked. if( id == outputButton ){ animationExportRequest = true; return; } // Case of SELECT button under the SAVE IMAGES button is clicked. if ( id == outputPathSelectButton ) { string path = choose(); if (!isdir(path)) { alert("The specified path \"" + path + "\" is not the folder."); path = choose(); } setComponentText(outputPathField, path); } // Case of EXIT button is clicked. if( id == exitButton ){ mainLoopState = false; return; } // Case of PLAY/STOP button is clicked. if( id == animationButton ){ if( animationState ){ setAnimationState( false ); }else{ setAnimationState( true ); } return; } } /** * Invoked when sliders are moved (event handler). * * @param id The ID of the moved slider. */ void onSliderMove( int id, int value ){ if( id == animationSlider ){ setTimer( value ); } } /** * Invoked when windows are closed (event handler). * * @param id The ID of the closed window. */ void onWindowClose( int id ){ // Case of the input-window was closed. if( id == inputWindow ){ setGraph2DAutoRange( graph, true, true ); mainLoopState = false; // Case of the animation-window was closed. }else if( id == animationWindow ){ animationState = false; } } /** * Invoked when graphs are closed (event handler). * * @param id The ID of the closed graph. */ void onGraph2DClose( int id ){ if( id == graph ){ animationState = false; } }