diff --git a/CMakeLists.txt b/CMakeLists.txt index 43a2f8e..2d6d934 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -14,6 +14,7 @@ add_executable(Graph "lex.c" "parser.c" "tree.c" + "ps_graph.c" ) # Optionally, you can set compiler warnings diff --git a/main.c b/main.c index 1b46599..0338011 100644 --- a/main.c +++ b/main.c @@ -2,6 +2,7 @@ #include #include "lex.h" #include "parser.h" +#include "ps_graph.h" int main(int argc, char *argv[]) { @@ -22,14 +23,35 @@ int main(int argc, char *argv[]) { node = parse_expression(lex); lex_free(lex); + //if (node) { + // double x; + // node_debug_print(node); + // printf("polygon("); + // for (x = -10.0; x < 10.0; x += 0.1) { + // printf("(%.2f,%.2f),", x, node_eval(node, x)); + // } + // printf("(10, -1000),(-10,-1000))\n"); + //} + if (node) { - double x; - node_debug_print(node); - printf("polygon("); - for (x = -10.0; x < 10.0; x += 0.1) { - printf("(%.2f,%.2f),", x, node_eval(node, x)); - } - printf("(10, -1000),(-10,-1000))\n"); + FILE *file; + struct graph_range graph; + //graph.xmin = -10.0; + //graph.xmax = 10.0; + //graph.ymin = -10.0; + //graph.ymax = 10.0; + //graph.step = 0.1; + + graph.xmin = -3.14; + graph.xmax = 3.14; + graph.ymin = -1; + graph.ymax = 1; + graph.step = 0.01; + + + file = fopen("out.ps", "w"); + ps_export_graph(file, node, &graph); + fclose(file); } node_free(node); diff --git a/ps_graph.c b/ps_graph.c new file mode 100644 index 0000000..5249a1d --- /dev/null +++ b/ps_graph.c @@ -0,0 +1,114 @@ +#include "ps_graph.h" + +#define GRAPH_SIZE 400 +#define HALF_GRAPH_SIZE (GRAPH_SIZE / 2) +#define GRID_STEP (GRAPH_SIZE / 10) + +void ps_export_graph(FILE *file, struct expr_node *node, struct graph_range *range) { + int i; + double x; + int first = 1; + + fprintf(file, + "306 500 translate\n" + "2 setlinewidth\n" + "/gridline {\n" + " .5 setlinewidth\n" + " .5 setgray\n" + " [3 3] 0 setdash\n" + " newpath\n" + " moveto\n" + " rlineto\n" + " stroke\n" + "} def\n" + "\n" + ); + + /* mrizka */ + for (i = -HALF_GRAPH_SIZE + GRID_STEP; i < HALF_GRAPH_SIZE; i += GRID_STEP) { + fprintf(file, "%5d 0 %5d %5d gridline\n", GRAPH_SIZE, -HALF_GRAPH_SIZE, i); + fprintf(file, " 0 %5d %5d %5d gridline\n", GRAPH_SIZE, i, -HALF_GRAPH_SIZE); + } + + /* popisky */ + fprintf(file, + "/Arial findfont\n" + "12 scalefont\n" + "setfont\n" + ); + + for (i = -HALF_GRAPH_SIZE; i <= HALF_GRAPH_SIZE; i += GRID_STEP) { + double inorm = (double)i / (double)GRAPH_SIZE + 0.5; + double xval = range->xmax * inorm + range->xmin * (1.0 - inorm) ; // range->xmin + inorm * (range->xmax - range->xmin); + double yval = range->ymax * inorm + range->ymin * (1.0 - inorm) ; // range->xmin + inorm * (range->xmax - range->xmin); + + fprintf(file, + "newpath\n" + "%d %d moveto\n" + "(%.2f) dup\n" + "stringwidth pop neg\n" + "0 rmoveto\n" + "-10 -3 rmoveto\n" + "show\n" + "\n", + -HALF_GRAPH_SIZE, i, yval + ); + + fprintf(file, + "newpath\n" + "%d %d moveto\n" + "(%.2f) dup\n" + "stringwidth pop\n" + "2 div neg\n" + "-20 rmoveto\n" + "show\n" + "\n", + i, -HALF_GRAPH_SIZE, xval + ); + + } + + fprintf(file, + "[] 0 setdash\n" + "newpath\n" + "%d %d moveto\n" + "%d 0 rlineto\n" + "0 %d rlineto\n" + "%d 0 rlineto\n" + "closepath\n" + "gsave\n" + "clip\n", + -HALF_GRAPH_SIZE, -HALF_GRAPH_SIZE, GRAPH_SIZE, GRAPH_SIZE, -GRAPH_SIZE + ); + + fprintf(file, + "2 setlinewidth\n" + "0 .3 .7 setrgbcolor\n" + "newpath\n" + ); + + for (x = range->xmin; x <= range->xmax; x += range->step) { + double y = node_eval(node, x); + double xpos = (double)(-HALF_GRAPH_SIZE) + (x - range->xmin) / (range->xmax - range->xmin) * (double)GRAPH_SIZE; + double ypos = (double)(-HALF_GRAPH_SIZE) + (y - range->ymin) / (range->ymax - range->ymin) * (double)GRAPH_SIZE; + const char* cmd = "lineto"; + if (first) { + cmd = "moveto"; + first = 0; + } + fprintf(file, "%.2f %.2f %s\n", xpos, ypos, cmd); + } + + fprintf(file, + "stroke\n" + ); + + fprintf(file, + "grestore\n" + "2 setlinewidth\n" + "0 0 0 setrgbcolor\n" + "stroke\n" + ); + + +} \ No newline at end of file diff --git a/ps_graph.h b/ps_graph.h new file mode 100644 index 0000000..be4fb6d --- /dev/null +++ b/ps_graph.h @@ -0,0 +1,15 @@ +#ifndef PS_GRAPH_H +#define PS_GRAPH_H + +#include +#include "tree.h" + +struct graph_range { + double xmin, xmax; + double ymin, ymax; + double step; +}; + +extern void ps_export_graph(FILE *file, struct expr_node *node, struct graph_range *range); + +#endif \ No newline at end of file