graphcurses

Curses 2D graph generator
git clone git://git.christosmarg.xyz/graphcurses.git
Log | Files | Refs | README | LICENSE

commit a642dc564b7ebeab205cb7e502d6a57271bf81d9
parent 2d1eeea3c655d5a2252e3ed1efbf1251c70f611c
Author: Christos Margiolis <christos@margiolis.net>
Date:   Mon, 25 May 2020 14:12:19 +0300

tabs -> spaces

Diffstat:
MREADME.md | 16++++++++++++++++
Msrc/main.c | 130++++++++++++++++++++++++++++++++++++++++----------------------------------------
Msrc/plane.c | 124++++++++++++++++++++++++++++++++++++++++----------------------------------------
Msrc/plane.h | 22+++++++++++-----------
4 files changed, 154 insertions(+), 138 deletions(-)

diff --git a/README.md b/README.md @@ -9,6 +9,22 @@ A simple ncurses graph generator. * `ncurses` * `matheval` +## Usage + +```shell +$ cd path/to/graphcurses +$ make +$ make run +``` +In order to install do +```shell +$ cd path/to/graphcurses +$ make +$ sudo make install +$ make clean # optional +``` +The binary will be installed at `/usr/local/bin/` + ## To Do * Improve key handling diff --git a/src/main.c b/src/main.c @@ -11,97 +11,97 @@ static void handle_key(Plane *p, int key); int main(int argc, char **argv) { - init_curses(); - Plane p; - plane_init(&p); - restore_zoom(&p); - validate_expression(&p); - p.yfunc = eval; - int key = 0; + init_curses(); + Plane p; + plane_init(&p); + restore_zoom(&p); + validate_expression(&p); + p.yfunc = eval; + int key = 0; - while (key != 'q') - { - attron(COLOR_PAIR(1)); - handle_key(&p, key); - erase(); - attron(A_REVERSE); - attron(A_BOLD); - mvprintw(0, 0, "f(x) = %s", evaluator_get_string(f)); - attroff(A_REVERSE); - attroff(A_BOLD); - draw_axes(&p); - attroff(COLOR_PAIR(1)); + while (key != 'q') + { + attron(COLOR_PAIR(1)); + handle_key(&p, key); + erase(); + attron(A_REVERSE); + attron(A_BOLD); + mvprintw(0, 0, "f(x) = %s", evaluator_get_string(f)); + attroff(A_REVERSE); + attroff(A_BOLD); + draw_axes(&p); + attroff(COLOR_PAIR(1)); - draw_graph(&p); - refresh(); - key = getch(); - } - - endwin(); - evaluator_destroy(f); + draw_graph(&p); + refresh(); + key = getch(); + } + + endwin(); + evaluator_destroy(f); - return 0; + return 0; } static void init_curses(void) { - initscr(); - cbreak(); - noecho(); - curs_set(0); - keypad(stdscr, 1); - start_color(); - init_pair(1, COLOR_WHITE, COLOR_BLACK); - init_pair(2, COLOR_YELLOW, COLOR_BLACK); + initscr(); + cbreak(); + noecho(); + curs_set(0); + keypad(stdscr, 1); + start_color(); + init_pair(1, COLOR_WHITE, COLOR_BLACK); + init_pair(2, COLOR_YELLOW, COLOR_BLACK); } static void getfunc(Plane *p, char *buf) { - move(0, 0); - clrtoeol(); - printw("f(x) = "); - echo(); - refresh(); - getnstr(buf, 256); - restore_zoom(p); - refresh(); - noecho(); + move(0, 0); + clrtoeol(); + printw("f(x) = "); + echo(); + refresh(); + getnstr(buf, 256); + restore_zoom(p); + refresh(); + noecho(); } static void validate_expression(Plane *p) { - char *buf = (char *)malloc(256 + sizeof(char)); - getfunc(p, buf); - while (!(f = evaluator_create(buf))) - { - printw("Error in expression! Try again"); - getfunc(p, buf); - refresh(); - } - free(buf); + char *buf = (char *)malloc(256 + sizeof(char)); + getfunc(p, buf); + while (!(f = evaluator_create(buf))) + { + printw("Error in expression! Try again"); + getfunc(p, buf); + refresh(); + } + free(buf); } static float eval(float x) { - return evaluator_evaluate_x(f, x); + return evaluator_evaluate_x(f, x); } static void handle_key(Plane *p, int key) { - switch (key) - { - case 'k': case KEY_UP: shift(p, 0.0f, 1.0f); break; - case 'j': case KEY_DOWN: shift(p, 0.0f, -1.0f); break; - case 'h': case KEY_LEFT: shift(p, -1.0f, 0.0f); break; - case 'l': case KEY_RIGHT: shift(p, 1.0f, 0.0f); break; - case '+': handle_zoom(p, 1.0f/1.05f); break; - case '-': handle_zoom(p, 1.05f); break; - case 'r': restore_zoom(p); break; - case 'f': validate_expression(p); break; - } + switch (key) + { + case 'k': case KEY_UP: shift(p, 0.0f, 1.0f); break; + case 'j': case KEY_DOWN: shift(p, 0.0f, -1.0f); break; + case 'h': case KEY_LEFT: shift(p, -1.0f, 0.0f); break; + case 'l': case KEY_RIGHT: shift(p, 1.0f, 0.0f); break; + case '+': handle_zoom(p, 1.0f/1.05f); break; + case '-': handle_zoom(p, 1.05f); break; + case 'r': restore_zoom(p); break; + case 'f': validate_expression(p); break; + } } diff --git a/src/plane.c b/src/plane.c @@ -3,107 +3,107 @@ void plane_init(Plane *p) { - p->xmin = XMIN_PLANE; - p->xmax = XMAX_PLANE; - p->ymin = YMIN_PLANE; - p->ymax = YMAX_PLANE; - p->xscale = XSCALE_PLANE; - p->yscale = YSCALE_PLANE; - p->xmaxs = getmaxx(stdscr); - p->ymaxs = getmaxy(stdscr); + p->xmin = XMIN_PLANE; + p->xmax = XMAX_PLANE; + p->ymin = YMIN_PLANE; + p->ymax = YMAX_PLANE; + p->xscale = XSCALE_PLANE; + p->yscale = YSCALE_PLANE; + p->xmaxs = getmaxx(stdscr); + p->ymaxs = getmaxy(stdscr); } void restore_zoom(Plane *p) { - p->xmin = XMIN_PLANE; - p->xmax = XMAX_PLANE; - p->ymin = YMIN_PLANE; - p->ymax = YMAX_PLANE; - p->xscale = XSCALE_PLANE; - p->yscale = YSCALE_PLANE; + p->xmin = XMIN_PLANE; + p->xmax = XMAX_PLANE; + p->ymin = YMIN_PLANE; + p->ymax = YMAX_PLANE; + p->xscale = XSCALE_PLANE; + p->yscale = YSCALE_PLANE; } void draw_axes(const Plane *p) { - int i; - float x0 = scale(0.0f, p->xmin, p->xmax, 0.0f, p->xmaxs); - float y0 = scale(0.0f, p->ymin, p->ymax, p->ymaxs, 0.0f); - float xstep, ystep; - getstep(p, &xstep, &ystep); - for (i = 0; i < p->xmaxs; i++) - { - float plotx = p->xmin + xstep * i; - int tick = fabs(fmod(plotx, p->xscale)) < xstep; - mvaddch(y0, i, tick ? ACS_PLUS : ACS_HLINE); - } - for (i = 0; i < p->ymaxs; i++) - { - float ploty = p->ymin + ystep * i; - int tick = fabs(fmod(ploty, p->yscale)) < ystep; - mvaddch(i, x0, tick ? ACS_PLUS : ACS_VLINE); - } - mvaddch(y0, x0, ACS_PLUS); + int i; + float x0 = scale(0.0f, p->xmin, p->xmax, 0.0f, p->xmaxs); + float y0 = scale(0.0f, p->ymin, p->ymax, p->ymaxs, 0.0f); + float xstep, ystep; + getstep(p, &xstep, &ystep); + for (i = 0; i < p->xmaxs; i++) + { + float plotx = p->xmin + xstep * i; + int tick = fabs(fmod(plotx, p->xscale)) < xstep; + mvaddch(y0, i, tick ? ACS_PLUS : ACS_HLINE); + } + for (i = 0; i < p->ymaxs; i++) + { + float ploty = p->ymin + ystep * i; + int tick = fabs(fmod(ploty, p->yscale)) < ystep; + mvaddch(i, x0, tick ? ACS_PLUS : ACS_VLINE); + } + mvaddch(y0, x0, ACS_PLUS); } void draw_graph(const Plane *p) { - float x; - float xstep; - float ystep; - getstep(p, &xstep, &ystep); - attron(COLOR_PAIR(2)); - for (x = p->xmin; x <= p->xmax; x += xstep) - { - float y = p->yfunc(x); - plot(p, x, y); - } - attroff(COLOR_PAIR(2)); + float x; + float xstep; + float ystep; + getstep(p, &xstep, &ystep); + attron(COLOR_PAIR(2)); + for (x = p->xmin; x <= p->xmax; x += xstep) + { + float y = p->yfunc(x); + plot(p, x, y); + } + attroff(COLOR_PAIR(2)); } float scale(float val, float omin, float omax, float nmin, float nmax) { - float s = (val - omin) / (omax - omin); - return s * (nmax - nmin) + nmin; + float s = (val - omin) / (omax - omin); + return s * (nmax - nmin) + nmin; } void getstep(const Plane *p, float *xstep, float *ystep) { - if (*xstep) *xstep = (p->xmax - p->xmin) / (p->xmaxs + 1.0f); - if (*ystep) *ystep = (p->ymax - p->ymin) / (p->ymaxs + 1.0f); + if (*xstep) *xstep = (p->xmax - p->xmin) / (p->xmaxs + 1.0f); + if (*ystep) *ystep = (p->ymax - p->ymin) / (p->ymaxs + 1.0f); } void plot(const Plane *p, float x, float y) { - float xp = scale(x, p->xmin, p->xmax, 0.0f, p->xmaxs); - float yp = scale(y, p->ymin, p->ymax, p->ymaxs, 0.0f); - mvaddch(yp, xp, '.'); + float xp = scale(x, p->xmin, p->xmax, 0.0f, p->xmaxs); + float yp = scale(y, p->ymin, p->ymax, p->ymaxs, 0.0f); + mvaddch(yp, xp, '.'); } void handle_zoom(Plane *p, float factor) { - float centerX = (p->xmin + p->ymax) / 2.0f; - float centerY = (p->ymin + p->ymax) / 2.0f; - p->xmin = scale(factor, 1.0f, 0.0f, p->xmin, centerX); - p->xmax = scale(factor, 1.0f, 0.0f, p->xmax, centerX); - p->ymin = scale(factor, 1.0f, 0.0f, p->ymin, centerY); - p->ymax = scale(factor, 1.0f, 0.0f, p->ymax, centerY); + float centerX = (p->xmin + p->ymax) / 2.0f; + float centerY = (p->ymin + p->ymax) / 2.0f; + p->xmin = scale(factor, 1.0f, 0.0f, p->xmin, centerX); + p->xmax = scale(factor, 1.0f, 0.0f, p->xmax, centerX); + p->ymin = scale(factor, 1.0f, 0.0f, p->ymin, centerY); + p->ymax = scale(factor, 1.0f, 0.0f, p->ymax, centerY); } void shift(Plane *p, float xshift, float yshift) { - xshift *= (p->xmax - p->xmin) / 16.0f; - yshift *= (p->ymax - p->ymin) / 16.0f; - p->xmin += xshift; - p->xmax += xshift; - p->ymin += yshift; - p->ymax += yshift; + xshift *= (p->xmax - p->xmin) / 16.0f; + yshift *= (p->ymax - p->ymin) / 16.0f; + p->xmin += xshift; + p->xmax += xshift; + p->ymin += yshift; + p->ymax += yshift; } diff --git a/src/plane.h b/src/plane.h @@ -7,19 +7,19 @@ #include <stdio.h> #include <stdlib.h> -#define XMIN_PLANE -2.0f*M_PI; -#define XMAX_PLANE 2.0f*M_PI; -#define YMIN_PLANE -M_PI; -#define YMAX_PLANE M_PI; -#define XSCALE_PLANE 1.0f; -#define YSCALE_PLANE 1.0f; +#define XMIN_PLANE -2.0f*M_PI; +#define XMAX_PLANE 2.0f*M_PI; +#define YMIN_PLANE -M_PI; +#define YMAX_PLANE M_PI; +#define XSCALE_PLANE 1.0f; +#define YSCALE_PLANE 1.0f; typedef struct { - float (*yfunc)(float x); - float ymin, ymax; - float xmin, xmax; - float xscale, yscale; - int ymaxs, xmaxs; + float (*yfunc)(float x); + float ymin, ymax; + float xmin, xmax; + float xscale, yscale; + int ymaxs, xmaxs; } Plane; extern Plane p;