drawing dots - ploot - simple plotting tools
(HTM) 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
(HTM) 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;
}