### Setting up the plot file

Gnuplot allows input using a script file containing commands. You can write your program in any language and automate the creation of the script files. You might want to create a string for each section of the file and at the end send each string to an open file handler to write the file. For our labs we are only drawing lines and arrows so far. There are a few important things to add to every script file.

   set title "My Title"
set xrange [-400.0: 400.0]
set yrange [-400.0: 400.0]
unset key
set size square

set title is self explanatory. set xrange and set yrange are used to set the range of the displayed plot. unset key removes the key or legend to the plot as it is not necessary for our labs. “set size square” ensures the plot is square as normally an 800×800 plot displayed on most monitors will appear as a rectangle. Other parameters to this command include “set size ratio 2” where the the plot is set to be twice as high as wide. You will probably want to include this information in every plot file you produce.

### Drawing a static line

There are at least two ways to draw lines. The first way to draw lines is using the following command:

   plot '-' with lines
-400.000000 -400.000000 0.000000 0.000000
...
e

You can plot as many lines as you want following the 'plot' command. You must end the plot command with 'e'. This works great for plotting static lines but can be problematic when animating. Once 'e' is reached if the 'plot' command is read in again, the previous set of lines disappears and the next set of points is read in. If you only want the last set of lines to be displayed in your animation, this is a good way to do it.

The second way to draw lines is like the way we created obstacles in the first lab:

   set arrow from 400.000000, 400.000000 to -400.000000, 400.000000 nohead lt 3

This command draws an arrow from the first pair of x,y coordinates to the second. The 'nohead' parameter removes the arrowhead while the 'lt #' parameter sets the line color to 3. Another option 'lw #' sets the line width as specified. Here is a list of available colors:

   -1 black
1 red
2 green
3 blue
4 magenta
5 aqua
6 brown
7 yellow? (looks light orange)
8 orange

Here is some sample code contributed by another student used to draw obstacles. Note that all of the obstacle data is put in a string that can later be written to a file. There may be a better way to do this, but you can at least consider this approach. You may want to write directly to the file:

   string PrintObstacleData() {
char buff[100];
string s;
for (int i = 0; i < (int)obstacles->size(); i++) {
double x1;
double x2;
double y1;
double y2;
obstacle_t o= obstacles->at(i);
for (int j = 0; j < 4; j++) {
x1 = o.o_corner[j][0];
y1 = o.o_corner[j][1];
x2 = o.o_corner[(j+1)%4][0];
y2 = o.o_corner[(j+1)%4][1];
sprintf(buff, "set arrow from %f, %f to %f, %f nohead lt 3\n", x1,y1,x2,y2);
s+=buff;
}
}
return s;
}

This function draws all the obstacles in blue lines cycling through vertices.

When you come to draw the next “frame” for your gnuplot animation, you will need to use the command “unset arrow”. If you don't, gnuplot will superimpose all previous arrows on top of each other with the rendering of each frame. This causes gnuplot to slow down significantly when you have a long search (such as breadth first search.)

### Gnuplot BTW

Just in case you didn't know… To have anything show up in GNUPlot, you can't use only “set arrow” commands. You must also have at least one “plot”.

### Animation

For animation you can use the 'pause' command within the script to tell gnuplot to wait before plotting the next line or lines. You may want the lines to remain on the screen, in this case use the 'set arrow' command mentioned previously. The 'set arrow' must be followed by a 'plot' command in order to appear in the plot. However the 'plot' command must contain a set of points to be valid. Here is a solution:

   set arrow from 370.000000, 70.000000 to 390.000000, 90.000000 nohead lt 6
plot '-' with lines
0 0 0 0
e
pause 0.010000

Some can not seem to get the second line (plot '-' with lines) to work. Or the e's. Alternatively, plotted a line on the border of the graph to get the plot going, set the arrows, then called replot to plot the arrows. For example:

   set yr [-20:20]
set xr [-20:20]
plot -20
pause 1
set arrow from 370.000000, 70.000000 to 390.000000, 90.000000 nohead lt 6
replot
...

First set the line, then call 'plot' with a set of points following it. Obviously, since the points are all 0, nothing is plotted. This is followed by an 'e' to note the end of the command. The number following the 'pause' is the time in seconds that gnuplot is to pause. You may want to try producing a line every time you get a node's eight neighbors. Here is example code that prints the path:
   ...
string output;
...
output+= PrintLine(currentNode, neighborNode, color);
output+= PrintAniData(delay);
...

   //plots a line between the start node and end node
string PrintLine(Node * start, Node * end, int color) {
char buff[100];
string s;
double sx = start->getX();
double sy = start->getY();
double ex = end->getX();
double ey = end->getY();
sprintf(buff, "set arrow from %f, %f to %f, %f nohead lt %d\n", sx,sy,ex,ey, color);
s+=buff;
return s;
}
   //Prints the rest of the command, including the delay for the animation
string PrintAniData(double delay){
string s;
char buff[100];
sprintf(buff, "\nplot '-' with lines\n0 0 0 0\ne\npause %f\n",delay);
s+=buff;
return s;
}

Now that you have collected all of the strings together you can output a final file. You may want a few other helper functions to plot other data such as the start and goal nodes or enemy tanks. In the following example PrintFooterData() plots anything else that needs to be ploted that did not get ploted elsewhere. Make sure in any case that your file ends with 'e' or gnuplot may produce errors.

   ...
//within the search code, at the end you can push the path data to a file.
PrintState(output, "AStar.gpi");
...

   void PrintState(string s, char * filename) {
printf("Writing Plot Data to File: %s\n", filename);
ofstream myfile;
myfile.open(filename);
myfile << PrintObstacleData();
myfile << s;
myfile << PrintTankData();
myfile << PrintNode(getGoalNode(), 1);
myfile << PrintNode(getStartNode(), 2);
myfile << PrintFooterData();
myfile.close();
printf("Finished writing plot data.\n");
}

Once the file is written simply run gnuplot to see the animation. The command is the same as the was given for the first lab:

   gnuplot -persist filename.gpi

The plot may take a while if there is a lot of data. If your animation is too slow, turn down the delay on your 'pause' commands or insert less 'pause' commands or 'set' commands into your script file. (Instead of pausing every iteration, consider pausing after you pop five or ten nodes)

### faqs

<!–Is it safe to assume that the discretization parameter must be able to divide into the world size without a remainder? For example, can I assume that if the world size is 800 I won't be given a discretization parameter 30 since 800/30 = 26 2/3 which would create a discretized world of size '26 2/3 x 26 2/3'? Are all bzflag worlds square?

A: Consider that the other team can pick any parameter(a considerable one). So you should be able to handle this input in a good way. Yes you can assume all the worlds are square.

What is the definition of “close to an obstacle”? Are we talking about space that is next to a space that is considered an obstacle? or are we talking about a space that has a piece of an obstacle in it that doesn't reach the center of the space? Does “close to an enemy tank” mean the space that contains an enemy tank or the spaces that neighbor the space with the enemy tank? Or do we penalize proportional to how close we are to an obstacle/enemy tank?

A: You could do either one, but it has to be intuitive. You might want to consider that such penalization should not influence in a negative way finding the optimal path. Meaning if the only optimal path is to pass by an obstacle, then this optimal path should still be found by your algorithm.–>