127 lines
3.1 KiB
C
127 lines
3.1 KiB
C
#include "ps_graph.h"
|
|
#include <math.h>
|
|
|
|
#define GRAPH_SIZE 400
|
|
#define HALF_GRAPH_SIZE (GRAPH_SIZE / 2)
|
|
#define GRID_STEP (GRAPH_SIZE / 10)
|
|
#define FUNCTION_SEGMENTS 1000
|
|
|
|
void ps_export_graph(FILE *file, const struct expr_node *node, const 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);
|
|
double yval = range->ymax * inorm + range->ymin * (1.0 - inorm);
|
|
|
|
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 (i = 0; i < FUNCTION_SEGMENTS; ++i) {
|
|
const char *cmd = "lineto";
|
|
double xpos, ypos;
|
|
double y;
|
|
|
|
x = range->xmin + (range->xmax - range->xmin) * (double)i / (double)FUNCTION_SEGMENTS;
|
|
|
|
if (node_eval(node, x, &y) != EVAL_OK) {
|
|
first = 1;
|
|
continue;
|
|
}
|
|
|
|
xpos = (double)(-HALF_GRAPH_SIZE) + (x - range->xmin) / (range->xmax - range->xmin) * (double)GRAPH_SIZE;
|
|
ypos = (double)(-HALF_GRAPH_SIZE) + (y - range->ymin) / (range->ymax - range->ymin) * (double)GRAPH_SIZE;
|
|
|
|
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"
|
|
);
|
|
|
|
|
|
} |