drawing dots - ploot - simple plotting tools | |
git clone git://bitreich.org/ploot git://enlrupgkhuxnvlhsf6lc3fziv5h2hhfrinws65… | |
Log | |
Files | |
Refs | |
Tags | |
README | |
LICENSE | |
--- | |
commit 8112f382b3e9104289ade9cae2d777ab4d68ea1b | |
parent 04a8bcf172e92e0f70bc889b5181bc3cbdb8f381 | |
Author: Josuah Demangeon <[email protected]> | |
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(-) | |
--- | |
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 | |
diff --git a/config.h b/config.h | |
@@ -0,0 +1,2 @@ | |
+#define MAX_WIDTH 80 | |
+#define MAX_HEIGHT 20 | |
diff --git a/plot b/plot | |
Binary files differ. | |
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; | |
} |