This commit is contained in:
tovjemam 2024-10-14 22:10:32 +02:00
parent ea9b427363
commit 30e1165d78
4 changed files with 159 additions and 7 deletions

View File

@ -14,6 +14,7 @@ add_executable(Graph
"lex.c"
"parser.c"
"tree.c"
"ps_graph.c"
)
# Optionally, you can set compiler warnings

36
main.c
View File

@ -2,6 +2,7 @@
#include <stdlib.h>
#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);

114
ps_graph.c Normal file
View File

@ -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"
);
}

15
ps_graph.h Normal file
View File

@ -0,0 +1,15 @@
#ifndef PS_GRAPH_H
#define PS_GRAPH_H
#include <stdio.h>
#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