drawing dots - ploot - simple plotting tools HTML git clone git://bitreich.org/ploot git://enlrupgkhuxnvlhsf6lc3fziv5h2hhfrinws65d7roiv6bfj7d652fid.onion/ploot DIR Log DIR Files DIR Refs DIR Tags DIR README DIR LICENSE --- DIR commit 8112f382b3e9104289ade9cae2d777ab4d68ea1b DIR parent 04a8bcf172e92e0f70bc889b5181bc3cbdb8f381 HTML Author: Josuah Demangeon <mail@josuah.net> Date: Fri, 2 Feb 2018 21:05:01 +0100 drawing dots Diffstat: M Makefile | 2 +- A config.h | 2 ++ M plot | 0 M plot.c | 74 ++++++++++++++++++++++++++----- 4 files changed, 66 insertions(+), 12 deletions(-) --- DIR diff --git a/Makefile b/Makefile @@ -1,4 +1,4 @@ CFLAGS = -Wall -Wextra -Werror -std=c89 -pedantic -all: plot.o +all: plot.o config.h ${CC} -o plot plot.o DIR diff --git a/config.h b/config.h @@ -0,0 +1,2 @@ +#define MAX_WIDTH 80 +#define MAX_HEIGHT 20 DIR diff --git a/plot b/plot Binary files differ. DIR diff --git a/plot.c b/plot.c @@ -1,18 +1,23 @@ #include <stdio.h> +#include <string.h> + +#include "config.h" #define ABS(x) ((x) < 0 ? -(x) : (x)) +#define LEN(x) (sizeof(x) / sizeof(*x)) /* - * Set `str' to a human-readable form of `num' with always a width of 8 - * (including '\0' terminator). + * Set `str' to a human-readable form of `num' with always a width of 7 (+ 1 + * the '\0' terminator). Buffer overflow is ensured not to happen due to the + * max size of a double. */ void -humanize(double num, char *str, size_t len) +humanize(char *str, double num) { int exp; char *label = " kMGTE", fmt[] = "%+.?f%c"; - for (exp = 0; ABS(num) > 1000; exp += 3) + for (exp = 0; ABS(num) > 1000; exp++) num /= 1000; fmt[3] = (ABS(num) < 10) ? '3' : (ABS(num) < 100) ? '2' : '1'; @@ -20,18 +25,65 @@ humanize(double num, char *str, size_t len) fmt[5] = '\0'; fmt[3]++; } - snprintf(str, len, fmt, num, label[exp / 3]); - if (num > 0) + snprintf(str, 8, fmt, num, label[exp]); + if (num >= 0) str[0] = ' '; } -int -main() +/* + * Print two rows of a plot into a single line using ' ', '.' and ':'. + */ +void +line(double *beg, double *end, double top, double bot) +{ + double *val; + + for (val = beg; val <= end; val++) + putchar((*val < bot) ? ' ' : (*val < top) ? '.' : ':'); +} + +/* + * Returns the maximal double of values between `beg' and `end'. + */ +double +maxdv(double *beg, double *end) { - char str[8]; + double *val, max; - humanize(-1 << 18, str, sizeof(str)); - printf("%s\n", str); + max = *beg; + for (val = beg; val < end; val++) { + if (*val > max) + max = *val; + } + return max; +} +/* + * Plot values between `beg' and `end' in a plot of height `height'. + */ +void +plot(int height, double *beg, double *end) +{ + double top, bot, max; + int h; +/* + char label[8]; +*/ + + max = maxdv(beg, end); + + for (h = height + height % 2; h > 0; h -= 2) { + top = h * max / height; + bot = (h - 1) * max / height; + line(beg, end, top, bot); + putchar('\n'); + } +} + +int +main() +{ + double val[] = { 0.0, 0.4, 3.4, 2.1, 3.5, 3.0, 1.1, 2.0 } ; + plot(10, val, val + LEN(val)); return 0; }