commit 4145d64035248317f7fe7cb1af6b79b1dec429fa
parent 06df6154ed6dafa80a57bc0121a7a3afe27268b1
Author: Christos Margiolis <christos@margiolis.net>
Date: Mon, 18 May 2020 17:23:54 +0300
changed to C
Diffstat:
M | Makefile | | | 8 | ++++---- |
M | bin/graphcurses | | | 0 | |
M | obj/main.o | | | 0 | |
M | obj/plane.o | | | 0 | |
A | src/main.c | | | 107 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
D | src/main.cpp | | | 100 | ------------------------------------------------------------------------------- |
A | src/plane.c | | | 109 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
D | src/plane.cpp | | | 100 | ------------------------------------------------------------------------------- |
M | src/plane.h | | | 53 | ++++++++++++++++++++++++++--------------------------- |
9 files changed, 246 insertions(+), 231 deletions(-)
diff --git a/Makefile b/Makefile
@@ -5,13 +5,13 @@ SRC_DIR = src
OBJ_DIR = obj
BIN_DIR = bin
-SRC = $(wildcard $(SRC_DIR)/*.cpp)
-OBJ = $(SRC:$(SRC_DIR)/%.cpp=$(OBJ_DIR)/%.o)
+SRC = $(wildcard $(SRC_DIR)/*.c)
+OBJ = $(SRC:$(SRC_DIR)/%.c=$(OBJ_DIR)/%.o)
MOVE = mv
MKDIR_P = mkdir -p
-CC = g++
+CC = gcc
CPPFLAGS += -Iinclude
CFLAGS += -Wall
LDFLAGS += -Llib
@@ -26,7 +26,7 @@ $(TARGET): $(OBJ)
$(CC) $(LDFLAGS) $^ $(LDLIBS) -o $@
$(MOVE) $(TARGET) $(BIN_DIR)
-$(OBJ_DIR)/%.o: $(SRC_DIR)/%.cpp
+$(OBJ_DIR)/%.o: $(SRC_DIR)/%.c
$(MKDIR_P) $(OBJ_DIR)
$(CC) $(CPPFLAGS) $(CFLAGS) -c $< -o $@
diff --git a/bin/graphcurses b/bin/graphcurses
Binary files differ.
diff --git a/obj/main.o b/obj/main.o
Binary files differ.
diff --git a/obj/plane.o b/obj/plane.o
Binary files differ.
diff --git a/src/main.c b/src/main.c
@@ -0,0 +1,107 @@
+#include "plane.h"
+
+static void *f = NULL;
+
+static void init_curses();
+static void getfunc(Plane *p, char *buf);
+static void validate_expression(Plane *p);
+static float eval(float x);
+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;
+
+ 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); */
+
+ return 0;
+}
+
+static void
+init_curses()
+{
+ 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();
+}
+
+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);
+}
+
+static float
+eval(float 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;
+ }
+}
diff --git a/src/main.cpp b/src/main.cpp
@@ -1,100 +0,0 @@
-#include "plane.h"
-
-static void *f = nullptr;
-
-static void init_curses();
-static void getfunc(char *buffer, Plane& plane);
-static void validate_expression(Plane& plane);
-static void handle_key(int key, Plane& plane);
-
-int
-main(int argc, char **argv)
-{
- init_curses();
- Plane plane;
- plane.restore_zoom();
- validate_expression(plane);
- std::function<float(float)> yfunc =
- [](float x){return evaluator_evaluate_x(f, x);};
- int key = 0;
-
- while (key != 'q')
- {
- attron(COLOR_PAIR(1));
- handle_key(key, plane);
- erase();
- attron(A_REVERSE);
- attron(A_BOLD);
- mvprintw(0, 0, "f(x) = %s", evaluator_get_string(f));
- attroff(A_REVERSE);
- attroff(A_BOLD);
- plane.draw_axes();
- attroff(COLOR_PAIR(1));
-
- plane.draw_graph(yfunc);
- refresh();
- key = getch();
- }
-
- endwin();
- evaluator_destroy(f);
-
- return 0;
-}
-
-static void
-init_curses()
-{
- initscr();
- cbreak();
- noecho();
- curs_set(0);
- keypad(stdscr, true);
- start_color();
- init_pair(1, COLOR_WHITE, COLOR_BLACK);
- init_pair(2, COLOR_YELLOW, COLOR_BLACK);
-}
-
-static void
-getfunc(char *buffer, Plane& plane)
-{
- move(0, 0);
- clrtoeol();
- printw("f(x) = ");
- echo();
- refresh();
- getnstr(buffer, 256);
- plane.restore_zoom();
- refresh();
- noecho();
-}
-
-static void
-validate_expression(Plane& plane)
-{
- char *buffer = new char[256];
- getfunc(buffer, plane);
- while (!(f = evaluator_create(buffer)))
- {
- printw("Error in expression! Try again");
- getfunc(buffer, plane);
- refresh();
- }
- delete[] buffer;
-}
-
-static void
-handle_key(int key, Plane& plane)
-{
- switch (key)
- {
- case 'k': case KEY_UP: plane.shift(0.0f, 1.0f); break;
- case 'j': case KEY_DOWN: plane.shift(0.0f, -1.0f); break;
- case 'h': case KEY_LEFT: plane.shift(-1.0f, 0.0f); break;
- case 'l': case KEY_RIGHT: plane.shift(1.0f, 0.0f); break;
- case '+': plane.handle_zoom(1.0f/1.05f); break;
- case '-': plane.handle_zoom(1.05f); break;
- case 'r': plane.restore_zoom(); break;
- case 'f': validate_expression(plane); break;
- }
-}
diff --git a/src/plane.c b/src/plane.c
@@ -0,0 +1,109 @@
+#include "plane.h"
+
+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);
+}
+
+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;
+}
+
+void
+draw_axes(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);
+}
+
+void
+draw_graph(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
+scale(float val, float omin, float omax, float nmin, float nmax)
+{
+ float s = (val - omin) / (omax - omin);
+ return s * (nmax - nmin) + nmin;
+}
+
+void
+getstep(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);
+}
+
+void
+plot(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, '.');
+}
+
+
+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);
+}
+
+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;
+}
diff --git a/src/plane.cpp b/src/plane.cpp
@@ -1,100 +0,0 @@
-#include "plane.h"
-
-Plane::Plane()
- :ymin(YMIN_PLANE), ymax(YMAX_PLANE), xmin(XMIN_PLANE), xmax(XMAX_PLANE),
- xscale(XSCALE_PLANE), yscale(YSCALE_PLANE), ymaxs(getmaxy(stdscr)),
- xmaxs(getmaxx(stdscr)) {}
-
-void
-Plane::restore_zoom()
-{
- xmin = XMIN_PLANE;
- xmax = XMAX_PLANE;
- ymin = YMIN_PLANE;
- ymax = YMAX_PLANE;
- xscale = XSCALE_PLANE;
- yscale = YSCALE_PLANE;
-}
-
-void
-Plane::draw_axes()
-{
- float x0 = scale(0.0f, xmin, xmax, 0.0f, xmaxs);
- float y0 = scale(0.0f, ymin, ymax, ymaxs, 0.0f);
- float xstep, ystep;
- getstep(xstep, ystep);
-
- for (int i = 0; i < xmaxs; i++)
- {
- float plotx = xmin + xstep * i;
- int tick = fabs(fmod(plotx, xscale)) < xstep;
- mvaddch(y0, i, tick ? ACS_PLUS : ACS_HLINE);
- }
-
- for (int i = 0; i < ymaxs; i++)
- {
- float ploty = ymin + ystep * i;
- int tick = fabs(fmod(ploty, yscale)) < ystep;
- mvaddch(i, x0, tick ? ACS_PLUS : ACS_VLINE);
- }
-}
-
-void
-Plane::draw_graph(const std::function<float(float)>& yfunc)
-{
- float xstep;
- float ystep;
- getstep(xstep, ystep);
- attron(COLOR_PAIR(2));
- for (float x = xmin; x <= xmax; x += xstep)
- {
- float y = yfunc(x);
- plot(x, y);
- }
- attroff(COLOR_PAIR(2));
-}
-
-float
-Plane::scale(float val, float omin, float omax, float nmin, float nmax)
-{
- float s = (val - omin) / (omax - omin);
- return s * (nmax - nmin) + nmin;
-}
-
-void
-Plane::getstep(float &xstep, float &ystep)
-{
- if (xstep) xstep = (xmax - xmin) / (xmaxs + 1.0f);
- if (ystep) ystep = (ymax - ymin) / (ymaxs + 1.0f);
-}
-
-void
-Plane::plot(float x, float y)
-{
- float xp = scale(x, xmin, xmax, 0.0f, xmaxs);
- float yp = scale(y, ymin, ymax, ymaxs, 0.0f);
- mvaddch(yp, xp, '.');
-}
-
-
-void
-Plane::handle_zoom(float factor)
-{
- float centerX = (xmin + ymax) / 2.0f;
- float centerY = (ymin + ymax) / 2.0f;
- xmin = scale(factor, 1.0f, 0.0f, xmin, centerX);
- xmax = scale(factor, 1.0f, 0.0f, xmax, centerX);
- ymin = scale(factor, 1.0f, 0.0f, ymin, centerY);
- ymax = scale(factor, 1.0f, 0.0f, ymax, centerY);
-}
-
-void
-Plane::shift(float xshift, float yshift)
-{
- xshift *= (xmax - xmin) / 16.0f;
- yshift *= (ymax - ymin) / 16.0f;
- xmin += xshift;
- xmax += xshift;
- ymin += yshift;
- ymax += yshift;
-}
diff --git a/src/plane.h b/src/plane.h
@@ -1,38 +1,37 @@
#ifndef PLANE_H
#define PLANE_H
-#include <cmath>
-#include <functional>
-#include <iostream>
+#include <math.h>
#include <matheval.h>
#include <ncurses.h>
+#include <stdio.h>
+#include <stdlib.h>
-class Plane
-{
- private:
- const float XMIN_PLANE = -2.0f*M_PI;
- const float XMAX_PLANE = 2.0f*M_PI;
- const float YMIN_PLANE = -M_PI;
- const float YMAX_PLANE = M_PI;
- const float XSCALE_PLANE = 1.0f;
- const float 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;
- float ymin, ymax;
- float xmin, xmax;
- float xscale, yscale;
- int ymaxs, xmaxs;
+typedef struct {
+ float (*yfunc)(float x);
+ float ymin, ymax;
+ float xmin, xmax;
+ float xscale, yscale;
+ int ymaxs, xmaxs;
+} Plane;
- public:
- Plane();
+extern Plane p;
- void restore_zoom();
- void draw_axes();
- void draw_graph(const std::function<float(float)>& yfunc);
- float scale(float val, float omin, float omax, float nmin, float nmax);
- void getstep(float &xstep, float &ystep);
- void plot(float x, float y);
- void handle_zoom(float factor);
- void shift(float xshift = 0.0f, float yshift = 0.0f);
-};
+void plane_init(Plane *p);
+void restore_zoom(Plane *p);
+void draw_axes(Plane *p);
+void draw_graph(Plane *p);
+float scale(float val, float omin, float omax, float nmin, float nmax);
+void getstep(Plane *p, float *xstep, float *ystep);
+void plot(Plane *p, float x, float y);
+void handle_zoom(Plane *p, float factor);
+void shift(Plane *p, float xshift, float yshift);
#endif /* PLANE_H */