aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--tri.c114
1 files changed, 114 insertions, 0 deletions
diff --git a/tri.c b/tri.c
new file mode 100644
index 0000000..e8f0e24
--- /dev/null
+++ b/tri.c
@@ -0,0 +1,114 @@
+#include <stdio.h>
+#include <stdlib.h>
+
+typedef struct {
+ int x, y;
+ int dx, dy;
+ int sx, sy;
+ int e;
+} Line;
+
+void init_line(
+ Line* l,
+ const int* f,
+ const int* t
+) {
+ const int dx = abs(t[0] - f[0]);
+ const int dy = -abs(t[1] - f[1]);
+ l->e = dx + dy;
+ l->dx = dx;
+ l->dy = dy;
+ l->sx = f[0] < t[0]? 1: -1;
+ l->sy = f[1] < t[1]? 1: -1;
+ l->x = f[0];
+ l->y = f[1];
+}
+
+void step_line(Line* l) {
+ const int e2 = l->e * 2;
+ const int dx = l->dx;
+ const int dy = l->dy;
+ if (e2 > dy) {
+ l->e += dy;
+ l->x += l->sx;
+ }
+ if (e2 <= dx) {
+ l->e += dx;
+ l->y += l->sy;
+ }
+}
+
+int tri_hand(
+ const int* v0,
+ const int* v1,
+ const int* v2
+) {
+ return
+ (v1[0] - v0[0]) * (v2[1] - v0[1]) -
+ (v2[0] - v0[0]) * (v1[1] - v0[1]) > 0;
+}
+
+void fill_tri(
+ char* buf, int w,
+ const int* v0,
+ const int* v1,
+ const int* v2
+) {
+ Line ne, fe;
+ const int* t;
+ int ha, x;
+#define swap(a, b) { \
+ t = a; \
+ a = b; \
+ b = t; \
+}
+ if (v0[1] > v1[1])
+ swap(v0, v1);
+ if (v1[1] > v2[1])
+ swap(v1, v2);
+ if (v0[1] > v1[1])
+ swap(v0, v1);
+#undef swap
+ ha = tri_hand(v0, v1, v2);
+ if (ha) {
+ init_line(&ne, v0, v2);
+ init_line(&fe, v0, v1);
+ } else {
+ init_line(&ne, v0, v1);
+ init_line(&fe, v0, v2);
+ }
+#define scanline \
+ for (x = ne.x; x < fe.x; x++) \
+ buf[x + fe.y * w] = '#'; \
+ step_line(&fe); \
+ while (ne.y != fe.y) \
+ step_line(&ne);
+ while (fe.y < v1[1]) {
+ scanline
+ }
+ if (ha)
+ init_line(&fe, v1, v2);
+ else
+ init_line(&ne, v1, v2);
+ while (fe.y < v2[1]) {
+ scanline
+ }
+#undef scanline
+}
+
+int main(void) {
+ int v0[] = { 16, 2 };
+ int v1[] = { 31, 16 };
+ int v2[] = { 1, 30 };
+ char buf[32*32];
+ int i;
+ for (i = 0; i < 32*32; i++)
+ buf[i] = ' ';
+ fill_tri(buf, 32, v0, v1, v2);
+ for (i = 0; i < 32*32; i++) {
+ if (!(i & 31)) printf("\n");
+ printf("%c", buf[i]);
+ }
+ printf("\n");
+}
+